Dmitry Ivankov | 11717a1 | 2025-05-08 09:11:39 -0700 | [diff] [blame] | 1 | #!/usr/bin/env bash |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 2 | # |
| 3 | # Copyright 2023 The Bazel Authors. All rights reserved. |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | # |
| 17 | # An end-to-end test for Bazel's *experimental* subrule API. |
| 18 | |
| 19 | # --- begin runfiles.bash initialization --- |
| 20 | set -euo pipefail |
| 21 | if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then |
| 22 | if [[ -f "$0.runfiles_manifest" ]]; then |
| 23 | export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" |
| 24 | elif [[ -f "$0.runfiles/MANIFEST" ]]; then |
| 25 | export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST" |
| 26 | elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then |
| 27 | export RUNFILES_DIR="$0.runfiles" |
| 28 | fi |
| 29 | fi |
| 30 | if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then |
| 31 | source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash" |
| 32 | elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then |
| 33 | source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \ |
| 34 | "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)" |
| 35 | else |
| 36 | echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash" |
| 37 | exit 1 |
| 38 | fi |
| 39 | # --- end runfiles.bash initialization --- |
| 40 | |
| 41 | source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ |
| 42 | || { echo "integration_test_setup.sh not found!" >&2; exit 1; } |
| 43 | |
| 44 | case "$(uname -s | tr [:upper:] [:lower:])" in |
| 45 | msys*|mingw*|cygwin*) |
| 46 | declare -r is_windows=true |
| 47 | ;; |
| 48 | *) |
| 49 | declare -r is_windows=false |
| 50 | ;; |
| 51 | esac |
| 52 | |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 53 | function set_up() { |
| 54 | mkdir -p subrule_testing |
| 55 | cat > subrule_testing/rule.bzl <<EOF |
| 56 | def _subrule_impl(ctx, _foo, _bar): |
| 57 | pass |
| 58 | |
| 59 | my_subrule = subrule( |
| 60 | implementation = _subrule_impl, |
| 61 | attrs = { |
| 62 | "_foo": attr.label(default = "//some:label"), |
Googler | eb098e5 | 2023-09-08 09:14:24 -0700 | [diff] [blame] | 63 | "_bar": attr.label(default = "//some:label_1"), |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 64 | }, |
| 65 | ) |
| 66 | |
| 67 | def _rule_impl(ctx): |
| 68 | my_subrule() |
| 69 | return [] |
| 70 | |
| 71 | my_rule = rule( |
| 72 | implementation = _rule_impl, |
| 73 | attrs = { |
| 74 | "_foo": attr.label(), |
| 75 | }, |
| 76 | subrules = [my_subrule], |
| 77 | ) |
Googler | 575dc85 | 2023-10-11 06:04:22 -0700 | [diff] [blame] | 78 | |
| 79 | def _aspect_impl(target, ctx): |
| 80 | return [] |
| 81 | |
| 82 | _my_aspect = aspect(implementation = _aspect_impl, subrules = [my_subrule]) |
| 83 | |
| 84 | def _rule_with_aspect_impl(ctx): |
| 85 | return [] |
| 86 | |
| 87 | my_rule_with_aspect = rule( |
| 88 | implementation = _rule_with_aspect_impl, |
| 89 | attrs = {"dep": attr.label(aspects = [_my_aspect])}, |
| 90 | ) |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 91 | EOF |
| 92 | cat > subrule_testing/BUILD <<EOF |
Googler | 575dc85 | 2023-10-11 06:04:22 -0700 | [diff] [blame] | 93 | load(":rule.bzl", "my_rule", "my_rule_with_aspect") |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 94 | my_rule(name = 'foo') |
Googler | 575dc85 | 2023-10-11 06:04:22 -0700 | [diff] [blame] | 95 | my_rule_with_aspect(name = 'foo_with_aspect', dep = '//some:label_2') |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 96 | EOF |
| 97 | |
| 98 | mkdir -p some |
| 99 | cat > some/BUILD <<EOF |
| 100 | package(default_visibility = ["//visibility:public"]) |
| 101 | genrule(name = 'label', cmd = '', outs = ['0.out']) |
| 102 | genrule(name = 'label_1', cmd = '', outs = ['1.out']) |
| 103 | genrule(name = 'label_2', cmd = '', outs = ['2.out']) |
| 104 | EOF |
| 105 | } |
| 106 | |
| 107 | function test_query_xml_outputs_subrule_implicit_deps() { |
| 108 | bazel query --output xml //subrule_testing:foo &> $TEST_log || fail "query failed" |
| 109 | expect_log '<rule-input name="//some:label"/>' |
Googler | eb098e5 | 2023-09-08 09:14:24 -0700 | [diff] [blame] | 110 | expect_log '<rule-input name="//some:label_1"/>' |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 111 | } |
| 112 | |
Googler | 575dc85 | 2023-10-11 06:04:22 -0700 | [diff] [blame] | 113 | function test_query_xml_outputs_subrule_implicit_deps_via_aspect() { |
| 114 | bazel query --output xml --xml:default_values //subrule_testing:foo_with_aspect &> $TEST_log || fail "query failed" |
| 115 | expect_log '<rule-input name="//some:label"/>' |
| 116 | expect_log '<rule-input name="//some:label_1"/>' |
| 117 | } |
| 118 | |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 119 | function test_query_xml_outputs_subrule_attributes() { |
| 120 | bazel query --output xml --xml:default_values //subrule_testing:foo &> $TEST_log || fail "query failed" |
Googler | de2f0d48 | 2023-10-11 06:01:21 -0700 | [diff] [blame] | 121 | expect_log '<label name="$//subrule_testing:rule.bzl%my_subrule%_foo" value="//some:label"/>' |
| 122 | expect_log '<label name="$//subrule_testing:rule.bzl%my_subrule%_bar" value="//some:label_1"/>' |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | # native.existing_rules skips all implicit attributes so this is trivially true |
| 126 | function test_subrule_attributes_are_not_visible_to_native.existing_rules() { |
| 127 | cat > subrule_testing/helper.bzl <<EOF |
| 128 | def print_rules(): |
| 129 | rules = native.existing_rules() |
| 130 | for name, rule in rules.items(): |
| 131 | for attr, value in rule.items(): |
| 132 | print('rule:', name + ', attr:', attr + ', value:', value) |
| 133 | EOF |
| 134 | cat > subrule_testing/BUILD <<EOF |
| 135 | load(":rule.bzl", "my_rule") |
| 136 | load(":helper.bzl", "print_rules") |
| 137 | my_rule(name = 'foo') |
| 138 | print_rules() |
| 139 | EOF |
Googler | f417aa9 | 2024-05-13 03:49:09 -0700 | [diff] [blame] | 140 | bazel shutdown # Google-internal testing hook assumes --experimental_rule_extension_api never changes |
| 141 | bazel build --experimental_rule_extension_api --nobuild //subrule_testing:foo &> $TEST_log || fail "analysis failed" |
Googler | afb05cc | 2023-09-08 03:38:51 -0700 | [diff] [blame] | 142 | expect_log 'rule: foo, attr: kind, value: my_rule' |
| 143 | expect_not_log '_foo' |
| 144 | } |
| 145 | |
| 146 | run_suite "Tests for subrules" |