From f0bba0c4d015888bafc2288ed73ff25edea7d395 Mon Sep 17 00:00:00 2001 From: Greg Roodt Date: Fri, 24 Jul 2026 12:41:57 +1000 Subject: [PATCH] Validate pycross package override labels --- pycross/private/resolved_lock_renderer.bzl | 66 ++++++++++++++++++++++ tests/unit/test_resolved_lock_renderer.bzl | 50 ++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/pycross/private/resolved_lock_renderer.bzl b/pycross/private/resolved_lock_renderer.bzl index 101f9c1f..78665fb5 100644 --- a/pycross/private/resolved_lock_renderer.bzl +++ b/pycross/private/resolved_lock_renderer.bzl @@ -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"] @@ -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) @@ -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" diff --git a/tests/unit/test_resolved_lock_renderer.bzl b/tests/unit/test_resolved_lock_renderer.bzl index 0e7ce043..2da03f9a 100644 --- a/tests/unit/test_resolved_lock_renderer.bzl +++ b/tests/unit/test_resolved_lock_renderer.bzl @@ -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": { + "bar@2.0": { + "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"}, + }, + ], + }, + "foo@1.0": { + "build_target": "@//third_party:foo_wheel", + "sdist_file": {"label": "@//third_party:foo_sdist"}, + }, + "remote@3.0": { + "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, @@ -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, ], )