diff --git a/bazel/MODULE.bazel b/bazel/MODULE.bazel index 02a3895203..98e6e7f922 100644 --- a/bazel/MODULE.bazel +++ b/bazel/MODULE.bazel @@ -64,6 +64,9 @@ pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") use_repo(pip, "pip3", "website_pip3") +reachability_test_ext = use_extension("//dependency/test:reachability_test_extension.bzl", "reachability_test_extension", dev_dependency = True) +use_repo(reachability_test_ext, "apparent_excluded_repo", "apparent_excluded_transitive_repo") + # Load llvm_source for compile targets http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") diff --git a/bazel/MODULE.bazel.lock b/bazel/MODULE.bazel.lock index b033ca89a8..83226684f1 100644 --- a/bazel/MODULE.bazel.lock +++ b/bazel/MODULE.bazel.lock @@ -402,8 +402,8 @@ }, "//compile:extensions.bzl%llvm_minimal_extension": { "general": { - "bzlTransitiveDigest": "C48jAKE8lhdSLvr5IuCU7Kcne6TGLexGDZRR7MgRQaM=", - "usagesDigest": "AHSt7sa5kBf8c5QI3eJR6nOEA7gNEf0bLJghifbBSpM=", + "bzlTransitiveDigest": "iGhoyv/rCamuOdT7NVhoofJc2Gsxlkdl9ymm3SgqLFo=", + "usagesDigest": "ZqLfAjRhUAMAeJiS/eI2hiP3v3uIOtSBvc703K/qOb0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -411,7 +411,7 @@ "llvm_minimal_linux_x64": { "repoRuleId": "@@//compile:llvm_minimal.bzl%llvm_minimal_repo", "attributes": { - "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.10/llvm-minimal-22.1.8-Linux-X64.tar.zst", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.11/llvm-minimal-22.1.8-Linux-X64.tar.zst", "sha256": "6cb4cca6df33be00c80fa1639062c973d1cafe4e7ad98a9b4bdf21bf9dec5806", "strip_prefix": "llvm-minimal-22.1.8-Linux-X64" } @@ -419,7 +419,7 @@ "llvm_minimal_linux_arm64": { "repoRuleId": "@@//compile:llvm_minimal.bzl%llvm_minimal_repo", "attributes": { - "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.10/llvm-minimal-22.1.8-Linux-ARM64.tar.zst", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.11/llvm-minimal-22.1.8-Linux-ARM64.tar.zst", "sha256": "9a6cc0a84d524342e578db739b04e8a3875adb40b38887e4e074661e925f8a9c", "strip_prefix": "llvm-minimal-22.1.8-Linux-ARM64" } @@ -427,7 +427,7 @@ "llvm_minimal_macos_arm64": { "repoRuleId": "@@//compile:llvm_minimal.bzl%llvm_minimal_repo", "attributes": { - "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.10/llvm-minimal-22.1.8-macOS-ARM64.tar.zst", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.11/llvm-minimal-22.1.8-macOS-ARM64.tar.zst", "sha256": "928e51aa7c97fbb8c5c50075118f4b36e36363b1a2c3af2dfef9aea1ef526ade", "strip_prefix": "llvm-minimal-22.1.8-macOS-ARM64" } @@ -480,6 +480,30 @@ "recordedRepoMappingEntries": [] } }, + "//dependency/test:reachability_test_extension.bzl%reachability_test_extension": { + "general": { + "bzlTransitiveDigest": "NqxwhacnUCjbNmVUwIbYGp2Qbml8/4TK6imuNETJWnY=", + "usagesDigest": "JpYNilrJt8/GsPfYlEGn1o5zRlvR7SKmfkifD8YCuzs=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "apparent_excluded_transitive_repo": { + "repoRuleId": "@@//dependency/test:reachability_test_extension.bzl%_test_repo", + "attributes": { + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"leaf\",\n srcs = [],\n)\n" + } + }, + "apparent_excluded_repo": { + "repoRuleId": "@@//dependency/test:reachability_test_extension.bzl%_test_repo", + "attributes": { + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"direct\",\n srcs = [\"@apparent_excluded_transitive_repo//:leaf\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [] + } + }, "//sysroot:extensions.bzl%macos_sysroot_build_extension": { "general": { "bzlTransitiveDigest": "FOSmmvc22vA+YeVHySGYbJvOJk9fO2s5NCh3/JxObds=", @@ -514,8 +538,8 @@ }, "//sysroot:extensions.bzl%sysroot_extension": { "general": { - "bzlTransitiveDigest": "AkUtBUSmvVtVFVco6cQ9N99suyuFtlvl7GPK4IIi+Bg=", - "usagesDigest": "jh0WqeF6MJ8vzoO7dJIE2HGQPtw8HH5O6P4PlLekAc0=", + "bzlTransitiveDigest": "PRext/1KRDZnD3QPsbnKQMaXacghUYN2mdYPFjOMm/Q=", + "usagesDigest": "S9rr2cGiXVc4Inmt9v2uEbWMw9zQJ7m6K554kfMS8i0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -523,8 +547,8 @@ "sysroot_linux_amd64": { "repoRuleId": "@@//sysroot:sysroot.bzl%sysroot", "attributes": { - "version": "0.2.10", - "sha256": "c5faf74999edad82a750e2b4773afb6cb48c9d314fa1645fdc99ee4657ed82ee", + "version": "0.2.11", + "sha256": "63b3b31f7e1a0182816bde18513d72f734e02cc5d2ec50336f04c72c720e4484", "arch": "amd64", "glibc_version": "2.31", "stdcc_version": "13" @@ -533,8 +557,8 @@ "sysroot_linux_arm64": { "repoRuleId": "@@//sysroot:sysroot.bzl%sysroot", "attributes": { - "version": "0.2.10", - "sha256": "4fcf6fdcfacc17af966b16555db2b4ae2bb51f444782c9e33cca89fd9caacba7", + "version": "0.2.11", + "sha256": "cea58c40b0ced7ff83e1de70879ab904142167d4e0f3caf9e93aecd67845d1c5", "arch": "arm64", "glibc_version": "2.31", "stdcc_version": "13" diff --git a/bazel/WORKSPACE b/bazel/WORKSPACE index 410f847a1a..07f3517a02 100644 --- a/bazel/WORKSPACE +++ b/bazel/WORKSPACE @@ -37,3 +37,6 @@ load_website_packages() load("@website_pip3//:requirements.bzl", website_install_deps = "install_deps") website_install_deps() + +load("//dependency/test:reachability_test_extension.bzl", "reachability_test_repos") +reachability_test_repos() diff --git a/bazel/dependency/reachability.bzl b/bazel/dependency/reachability.bzl index afcc853c6c..cccc6ea254 100644 --- a/bazel/dependency/reachability.bzl +++ b/bazel/dependency/reachability.bzl @@ -281,6 +281,9 @@ def _repo_is_excluded(repo_name, patterns): return True return False +def _repo_or_apparent_is_excluded(repo_name, patterns): + return _repo_is_excluded(repo_name, patterns) or _repo_is_excluded(apparent_name(repo_name), patterns) + def _matches_package_pattern(package, pattern): if pattern == "//...": return True @@ -395,7 +398,7 @@ def _reachability_aspect_impl(target, ctx): continue for dep in _attr_targets(ctx.rule.attr, attr_name): dep_repo = dep.label.repo_name - if dep_repo and _repo_is_excluded(dep_repo, excluded_patterns): + if dep_repo and _repo_or_apparent_is_excluded(dep_repo, excluded_patterns): continue if dep_repo and dep_repo != consumer_repo: edges.append(struct( @@ -717,10 +720,12 @@ def _dependency_reachability_rule(flags = []): "excluded_patterns": attr.string_list( default = [], doc = ( - "Canonical repository-name patterns excluded from " + - "traversal. Supported forms are exact matches (`repo_name`) " + - "and a single trailing `*` wildcard (`prefix*`) for prefix " + - "matching." + "Repository-name patterns excluded from traversal. Patterns " + + "are matched against both the canonical repository name and " + + "the apparent/module name emitted in dependency metadata, " + + "so metadata-facing patterns work under both WORKSPACE and " + + "bzlmod. Supported forms are exact matches (`repo_name`) and " + + "a single trailing `*` wildcard (`prefix*`) for prefix matching." ), ), "attribution_patterns": attr.string_list( diff --git a/bazel/dependency/test/BUILD b/bazel/dependency/test/BUILD index c3c5b22434..5b80ac291c 100644 --- a/bazel/dependency/test/BUILD +++ b/bazel/dependency/test/BUILD @@ -278,6 +278,24 @@ dependency_reachability( excluded_patterns = ["bazel_*"], ) +filegroup( + name = "apparent_exclusion_root", + srcs = ["@apparent_excluded_repo//:direct"], +) + +dependency_reachability( + name = "reachability_apparent_exclusion_baseline", + testonly = True, + roots = [":apparent_exclusion_root"], +) + +dependency_reachability( + name = "reachability_apparent_exclusion", + testonly = True, + roots = [":apparent_exclusion_root"], + excluded_patterns = ["apparent_excluded_repo"], +) + filegroup( name = "rules_pkg_root", srcs = ["@rules_pkg//pkg:filter_directory"], @@ -317,6 +335,8 @@ sh_test( data = [ ":reachability_excluded_edge", ":reachability_edge_and_pattern", + ":reachability_apparent_exclusion_baseline", + ":reachability_apparent_exclusion", ":reachability_excluded_pattern", ":reachability_rules_pkg_transitive", ":reachability_excluded_rules_pkg_transitive", @@ -338,6 +358,7 @@ bzl_library( "reachability_apparent_name_test.bzl", "reachability_config_validation_test.bzl", "reachability_package_pattern_test.bzl", + "reachability_test_extension.bzl", "reachability_test_rules.bzl", ], deps = [ diff --git a/bazel/dependency/test/exclusions_reachability_test.sh b/bazel/dependency/test/exclusions_reachability_test.sh index fb29f46ae9..f516075768 100755 --- a/bazel/dependency/test/exclusions_reachability_test.sh +++ b/bazel/dependency/test/exclusions_reachability_test.sh @@ -17,6 +17,8 @@ JQ="${JQ_BIN:-jq}" REACHABILITY_EXCLUDED_EDGE_JSON="${RUNFILES_DIR}/dependency/test/reachability_excluded_edge.json" REACHABILITY_EDGE_AND_PATTERN_JSON="${RUNFILES_DIR}/dependency/test/reachability_edge_and_pattern.json" REACHABILITY_EXCLUDED_PATTERN_JSON="${RUNFILES_DIR}/dependency/test/reachability_excluded_pattern.json" +REACHABILITY_APPARENT_EXCLUSION_BASELINE_JSON="${RUNFILES_DIR}/dependency/test/reachability_apparent_exclusion_baseline.json" +REACHABILITY_APPARENT_EXCLUSION_JSON="${RUNFILES_DIR}/dependency/test/reachability_apparent_exclusion.json" REACHABILITY_RULES_PKG_TRANSITIVE_JSON="${RUNFILES_DIR}/dependency/test/reachability_rules_pkg_transitive.json" REACHABILITY_EXCLUDED_RULES_PKG_TRANSITIVE_JSON="${RUNFILES_DIR}/dependency/test/reachability_excluded_rules_pkg_transitive.json" REACHABILITY_EMPTY_EXCLUSIONS_JSON="${RUNFILES_DIR}/dependency/test/reachability_empty_exclusions.json" @@ -85,6 +87,26 @@ check "combined excluded_edges and excluded_patterns apply together" \ "0" \ "${REACHABILITY_EDGE_AND_PATTERN_JSON}" +check "baseline records extension repo by apparent name" \ + '[.dependencies | to_entries[] | select(.value.name == "apparent_excluded_repo")] | length' \ + "1" \ + "${REACHABILITY_APPARENT_EXCLUSION_BASELINE_JSON}" + +check "baseline reaches through bzlmod extension repo before apparent-name exclusion" \ + '[.dependencies[] | .name] | any(. == "apparent_excluded_transitive_repo")' \ + "true" \ + "${REACHABILITY_APPARENT_EXCLUSION_BASELINE_JSON}" + +check "apparent-name excluded bzlmod extension repo is not recorded" \ + '[.dependencies[] | .name] | any(. == "apparent_excluded_repo")' \ + "false" \ + "${REACHABILITY_APPARENT_EXCLUSION_JSON}" + +check "apparent-name excluded bzlmod extension repo is pruned transitively" \ + '[.dependencies[] | .name] | any(. == "apparent_excluded_transitive_repo")' \ + "false" \ + "${REACHABILITY_APPARENT_EXCLUSION_JSON}" + check "baseline attribution records the unexcluded repository" \ '.dependencies | to_entries[] | select(.value.name == "rules_pkg") | .value.attributed_packages[0].package' \ "//dependency/test/transitive/ext/excluded" \ diff --git a/bazel/dependency/test/reachability_test_extension.bzl b/bazel/dependency/test/reachability_test_extension.bzl new file mode 100644 index 0000000000..8e02e2d7ad --- /dev/null +++ b/bazel/dependency/test/reachability_test_extension.bzl @@ -0,0 +1,43 @@ +"""Test-only module extension for reachability tests.""" + +def _test_repo_impl(ctx): + ctx.file("BUILD.bazel", ctx.attr.build_file_content) + +_test_repo = repository_rule( + implementation = _test_repo_impl, + attrs = { + "build_file_content": attr.string(mandatory = True), + }, +) + +def reachability_test_repos(): + """Declares the fixture repos shared by bzlmod and WORKSPACE reachability tests.""" + _test_repo( + name = "apparent_excluded_transitive_repo", + build_file_content = """\ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "leaf", + srcs = [], +) +""", + ) + _test_repo( + name = "apparent_excluded_repo", + build_file_content = """\ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "direct", + srcs = ["@apparent_excluded_transitive_repo//:leaf"], +) +""", + ) + +def _reachability_test_extension_impl(_module_ctx): + reachability_test_repos() + +reachability_test_extension = module_extension( + implementation = _reachability_test_extension_impl, +)