Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions pycross/private/resolved_lock_renderer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,64 @@ def _is_in_same_cycle(dep_key, pkg, packages):
return False
return dep_pkg.get("cycle_group") == cycle_group

def _render_package_override_label_validation_test_rule(lines):
lines.extend([
"def _package_override_label_validation_test_impl(ctx):",
_ind("_ = ctx.attr.targets"),
_ind('executable = ctx.actions.declare_file(ctx.label.name + ".sh")'),
_ind("ctx.actions.write("),
_ind("output = executable,", 2),
_ind('content = "#!/bin/sh\\nexit 0\\n",', 2),
_ind("is_executable = True,", 2),
_ind(")"),
_ind("return [DefaultInfo(executable = executable)]"),
"",
"_package_override_label_validation_test = rule(",
_ind("implementation = _package_override_label_validation_test_impl,"),
_ind("attrs = {"),
_ind('"targets": attr.label_list(', 2),
_ind("allow_files = True,", 3),
_ind('doc = "Targets referenced by pycross package overrides.",', 3),
_ind("),", 2),
_ind("},"),
_ind("test = True,"),
")",
"",
])

def _collect_package_override_labels(packages):
labels = {}
for _pkg_key, pkg in packages.items():
build_target = pkg.get("build_target")
if build_target:
labels[build_target] = True

sdist_file = pkg.get("sdist_file")
if sdist_file and sdist_file.get("label"):
labels[sdist_file["label"]] = True

for candidate in pkg.get("wheel_candidates", []):
file_ref = candidate.get("file_reference", {})
if file_ref.get("label"):
labels[file_ref["label"]] = True

return sorted(labels.keys())

def _render_package_override_label_validation_test(lines, package_override_labels):
lines.extend([
_ind("_package_override_label_validation_test("),
_ind('name = "validate_package_override_labels",', 2),
_ind("targets = [", 2),
])
for label in package_override_labels:
lines.append(_ind('"{}",'.format(label), 3))
lines.extend([
_ind("],", 2),
_ind('visibility = ["//visibility:public"],', 2),
_ind(")"),
"",
])

def _wheel_target(file_ref, sdist_file, pkg_key, pkg, repo_map, sdist_map, rctx_name):
if file_ref.get("label"):
return file_ref["label"]
Expand Down Expand Up @@ -603,12 +661,17 @@ def render_lock_bzl(lock, repo_map, sdist_map = None, rctx_name = ""):

lines.extend([
"",
])
_render_package_override_label_validation_test_rule(lines)
lines.extend([
"# buildifier: disable=unnamed-macro",
"def targets():",
_ind('"""Generated package targets."""'),
"",
])

package_override_labels = _collect_package_override_labels(packages)

# 1. Marker evaluators for dependency markers (deduped)
unique_markers = _collect_unique_markers(packages)
_render_marker_evaluators(lines, unique_markers)
Expand All @@ -627,4 +690,7 @@ def render_lock_bzl(lock, repo_map, sdist_map = None, rctx_name = ""):
# 4. Extras aggregates ([_all_] targets)
_render_extras_aggregates(lines, packages)

# 5. Package override label validation
_render_package_override_label_validation_test(lines, package_override_labels)

return "\n".join(lines) + "\n"
50 changes: 50 additions & 0 deletions tests/unit/test_resolved_lock_renderer.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,55 @@ def _test_wheel_library_tags_rendering(name):
util.helper_target(native.filegroup, name = name + "_subject", srcs = [])
analysis_test(name = name, target = name + "_subject", impl = _test_wheel_library_tags_rendering_impl)

# buildifier: disable=unused-variable
def _test_package_override_label_validation_impl(env, target):
"""Verify package override labels are rendered into a validation test."""
lock = {
"packages": {
"[email protected]": {
"wheel_candidates": [
{
"filename": "bar-2.0-py3-none-any.whl",
"file_reference": {"label": "@//local:bar_wheel"},
},
{
"filename": "bar-2.0-cp310-cp310-manylinux_2_17_x86_64.whl",
"file_reference": {"label": "@//local:bar_wheel"},
},
],
},
"[email protected]": {
"build_target": "@//third_party:foo_wheel",
"sdist_file": {"label": "@//third_party:foo_sdist"},
},
"[email protected]": {
"wheel_candidates": [
{
"filename": "remote-3.0-py3-none-any.whl",
"file_reference": {"key": "remote_wheel"},
},
],
},
},
}
repo_map = {"remote_wheel": "@repo//remote:wheel"}
res = render_lock_bzl(lock, repo_map, rctx_name = "my_rctx")

pre_targets_section = res.split("def targets():")[0]
env.expect.that_bool("def _package_override_label_validation_test_impl(ctx):" in pre_targets_section).equals(True)
env.expect.that_bool("_package_override_label_validation_test = rule(" in pre_targets_section).equals(True)

validation_section = res.split('name = "validate_package_override_labels"')[1].split(")", 1)[0]
env.expect.that_bool('"@//local:bar_wheel",' in validation_section).equals(True)
env.expect.that_bool('"@//third_party:foo_sdist",' in validation_section).equals(True)
env.expect.that_bool('"@//third_party:foo_wheel",' in validation_section).equals(True)
env.expect.that_bool("@repo//remote:wheel" not in validation_section).equals(True)
env.expect.that_collection(validation_section.split('"@//local:bar_wheel",')).has_size(2)

def _test_package_override_label_validation(name):
util.helper_target(native.filegroup, name = name + "_subject", srcs = [])
analysis_test(name = name, target = name + "_subject", impl = _test_package_override_label_validation_impl)

def resolved_lock_renderer_test_suite(name):
test_suite(
name = name,
Expand All @@ -716,5 +765,6 @@ def resolved_lock_renderer_test_suite(name):
_test_resolution_marker_evaluator_rendering,
_test_resolution_marker_compound_rendering,
_test_wheel_library_tags_rendering,
_test_package_override_label_validation,
],
)
Loading