Skip to content

Commit e28d0ca

Browse files
committed
pkl.project: check symlink targets
The pkl module extension uses symlinks to refer to the PklProject and PklProject.deps.json files. The rctx.symlink function does not guarantee that the symlink points at a real file on the filesystem and it doesn't watch the file for changes. With this change, we ensure the file exists before symlinking to it and watch it for changes (in case it's deleted by the user).
1 parent 3b05153 commit e28d0ca

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

pkl/private/pkl_project.bzl

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,35 @@ def convert_dict_to_options(option_name, items_dict):
8989
list.append("{key}={value}".format(key = key, value = value))
9090
return list
9191

92+
def _watch_symlink_target(rctx, label):
93+
"""Validates that a label points to an existing file and watches it for changes.
94+
95+
Args:
96+
rctx: The repository context.
97+
label: The label to validate.
98+
Returns:
99+
The resolved path.
100+
"""
101+
path = rctx.path(label)
102+
if not path.exists:
103+
fail("Cannot symlink '{}': file does not exist.".format(label))
104+
rctx.watch(path)
105+
return path
106+
92107
def _pkl_project_impl(rctx):
93-
packages = parse_pkl_project_deps_json(rctx.read(rctx.attr.pkl_project_deps))
108+
pkl_project_path = _watch_symlink_target(rctx, rctx.attr.pkl_project)
109+
pkl_project_deps_path = _watch_symlink_target(rctx, rctx.attr.pkl_project_deps)
110+
111+
packages = parse_pkl_project_deps_json(rctx.read(pkl_project_deps_path))
94112
targets_for_all = []
95113
for package in packages:
96114
targets_for_all.append("@%s//:item" % package.workspace_name)
97115

98-
rctx.symlink(rctx.attr.pkl_project, "PklProject")
99-
rctx.symlink(rctx.path(rctx.attr.pkl_project_deps), "PklProject.deps.json")
116+
rctx.symlink(pkl_project_path, "PklProject")
117+
rctx.symlink(pkl_project_deps_path, "PklProject.deps.json")
100118

101119
env_vars = convert_dict_to_options("--env-var", rctx.attr.environment)
102-
pkl_project_metadata = _eval_pkl_project(rctx, "PklProject", extra_args = env_vars + rctx.attr.extra_flags)
120+
pkl_project_metadata = _eval_pkl_project(rctx, pkl_project_path, extra_args = env_vars + rctx.attr.extra_flags)
103121
has_package = "package" in pkl_project_metadata
104122

105123
build_bazel_content = ""
@@ -138,7 +156,8 @@ pkl_cache(
138156
rctx.file("BUILD.bazel", content = build_bazel_content, executable = False)
139157

140158
def _pkl_project_http_rewrites_impl(rctx):
141-
rules = _eval_pkl_project(rctx, rctx.path(rctx.attr.pkl_project), extra_args = [
159+
pkl_project_path = _watch_symlink_target(rctx, rctx.attr.pkl_project)
160+
rules = _eval_pkl_project(rctx, pkl_project_path, extra_args = [
142161
"--expression",
143162
# Render the rewrite rules as list, to make sure the order is preserved.
144163
"""

0 commit comments

Comments
 (0)