From 7ca6ecb1eceda9587a967db039c9f0d262ff9e94 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Sun, 21 Jul 2024 00:33:11 +0200 Subject: [PATCH 01/14] WIP --- examples/MODULE.bazel | 1 + examples/args_location_expansion/BUILD.bazel | 25 ++++++++ .../doubly_transitioned_test.bzl | 6 ++ .../args_location_expansion/pkg/BUILD.bazel | 18 ++++++ .../args_location_expansion/rules/BUILD.bazel | 13 +++++ .../args_location_expansion/rules/defs.bzl | 57 +++++++++++++++++++ examples/args_location_expansion/test_bin.sh | 18 ++++++ 7 files changed, 138 insertions(+) create mode 100644 examples/args_location_expansion/BUILD.bazel create mode 100644 examples/args_location_expansion/doubly_transitioned_test.bzl create mode 100644 examples/args_location_expansion/pkg/BUILD.bazel create mode 100644 examples/args_location_expansion/rules/BUILD.bazel create mode 100644 examples/args_location_expansion/rules/defs.bzl create mode 100755 examples/args_location_expansion/test_bin.sh diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel index 56620a5..10e8125 100644 --- a/examples/MODULE.bazel +++ b/examples/MODULE.bazel @@ -6,6 +6,7 @@ local_path_override( path = "..", ) +bazel_dep(name = "bazel_skylib", version = "1.6.1") bazel_dep(name = "contrib_rules_jvm", version = "0.27.0") bazel_dep(name = "platforms", version = "0.0.10") bazel_dep(name = "rules_cc", version = "0.0.9") diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel new file mode 100644 index 0000000..1fa2f54 --- /dev/null +++ b/examples/args_location_expansion/BUILD.bazel @@ -0,0 +1,25 @@ +load(":doubly_transitioned_test.bzl", "doubly_transitioned_test") +load("//args_location_expansion/rules:defs.bzl", "write_settings_rule") + +write_settings_rule( + name = "single_rule", +) + +doubly_transitioned_test( + name = "doubly_transitioned_test", + binary = ":test_bin", + args = [ + "$(rlocationpath :single_rule)", + "$(rlocationpaths //args_location_expansion/pkg:all_rules)", + ], + data = [ + ":single_rule", + "//args_location_expansion/pkg:all_rules", + ], +) + +sh_binary( + name = "test_bin", + srcs = ["test_bin.sh"], + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/examples/args_location_expansion/doubly_transitioned_test.bzl b/examples/args_location_expansion/doubly_transitioned_test.bzl new file mode 100644 index 0000000..8fae382 --- /dev/null +++ b/examples/args_location_expansion/doubly_transitioned_test.bzl @@ -0,0 +1,6 @@ +load("@with_cfg.bzl", "with_cfg") +load("//args_location_expansion/rules:defs.bzl", "transitioned_test") + +_builder = with_cfg(transitioned_test) +_builder.set(Label("//args_location_expansion/rules:with_cfg_setting"), "set by with_cfg") +doubly_transitioned_test, _doubly_transitioned_test_ = _builder.build() diff --git a/examples/args_location_expansion/pkg/BUILD.bazel b/examples/args_location_expansion/pkg/BUILD.bazel new file mode 100644 index 0000000..ab3fc95 --- /dev/null +++ b/examples/args_location_expansion/pkg/BUILD.bazel @@ -0,0 +1,18 @@ +load("//args_location_expansion/rules:defs.bzl", "write_settings_rule") + +write_settings_rule( + name = "some_rule", +) + +write_settings_rule( + name = "other_rule", +) + +filegroup( + name = "all_rules", + srcs = [ + ":some_rule", + ":other_rule", + ], + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/examples/args_location_expansion/rules/BUILD.bazel b/examples/args_location_expansion/rules/BUILD.bazel new file mode 100644 index 0000000..21ea27f --- /dev/null +++ b/examples/args_location_expansion/rules/BUILD.bazel @@ -0,0 +1,13 @@ +load("@bazel_skylib//rules:common_settings.bzl", "string_setting") + +string_setting( + name = "rule_setting", + build_setting_default = "unset", + visibility = ["//visibility:public"], +) + +string_setting( + name = "with_cfg_setting", + build_setting_default = "unset", + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/examples/args_location_expansion/rules/defs.bzl b/examples/args_location_expansion/rules/defs.bzl new file mode 100644 index 0000000..10aafbb --- /dev/null +++ b/examples/args_location_expansion/rules/defs.bzl @@ -0,0 +1,57 @@ +def _write_settings_rule_impl(ctx): + # type: (ctx) -> None + out = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write(out, +"""\ +name = {} +rule_setting = {} +with_cfg_setting = {} +""".format(ctx.label.name, ctx.attr._rule_setting, ctx.attr._with_cfg_setting)) + return [DefaultInfo(files = depset([out]))] + +write_settings_rule = rule( + implementation = _write_settings_rule_impl, + attrs = { + "_rule_setting": attr.label(default = ":rule_setting"), + "_with_cfg_setting": attr.label(default = ":with_cfg_setting"), + }, +) + +def _data_transition_impl(_settings, _attr): + return { + "//args_location_expansion/rules:rule_setting": "set by rule transition", + } + +_data_transition = transition( + implementation = _data_transition_impl, + inputs = ["//args_location_expansion/rules:rule_setting"], + outputs = ["//args_location_expansion/rules:rule_setting"], +) + +def _transitioned_test_impl(ctx): + # type: (ctx) -> None + executable = ctx.actions.declare_file(ctx.label.name) + ctx.actions.symlink(output = executable, target_file = ctx.executable.binary) + runfiles = ctx.runfiles().merge_all([target[DefaultInfo].default_runfiles for target in ctx.attr.data]) + runfiles = runfiles.merge(ctx.attr.binary[DefaultInfo].default_runfiles) + return [ + DefaultInfo( + executable = executable, + runfiles = runfiles, + ), + ] + +transitioned_test = rule( + implementation = _transitioned_test_impl, + attrs = { + "binary": attr.label( + cfg = "target", + executable = True, + ), + "data": attr.label_list( + cfg = _data_transition, + allow_files = True, + ), + }, + test = True, +) diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh new file mode 100755 index 0000000..7b1baf4 --- /dev/null +++ b/examples/args_location_expansion/test_bin.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +# shellcheck disable=SC1090 +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- + +for arg in "$@"; do + path=$(rlocation "$arg") + cat "$path" +done \ No newline at end of file From b852dd96b8239db0bfa81d93b10f9ae51c4ecbaf Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Sun, 21 Jul 2024 21:39:18 +0200 Subject: [PATCH 02/14] Better test --- examples/args_location_expansion/BUILD.bazel | 7 +++--- .../doubly_transitioned_test.bzl | 2 +- .../args_location_expansion/rules/defs.bzl | 25 ++++++++++++------- examples/args_location_expansion/test_bin.sh | 16 ++++++++++-- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel index 1fa2f54..f72090b 100644 --- a/examples/args_location_expansion/BUILD.bazel +++ b/examples/args_location_expansion/BUILD.bazel @@ -1,5 +1,5 @@ -load(":doubly_transitioned_test.bzl", "doubly_transitioned_test") load("//args_location_expansion/rules:defs.bzl", "write_settings_rule") +load(":doubly_transitioned_test.bzl", "doubly_transitioned_test") write_settings_rule( name = "single_rule", @@ -7,11 +7,11 @@ write_settings_rule( doubly_transitioned_test( name = "doubly_transitioned_test", - binary = ":test_bin", args = [ "$(rlocationpath :single_rule)", "$(rlocationpaths //args_location_expansion/pkg:all_rules)", ], + binary = ":test_bin", data = [ ":single_rule", "//args_location_expansion/pkg:all_rules", @@ -21,5 +21,6 @@ doubly_transitioned_test( sh_binary( name = "test_bin", srcs = ["test_bin.sh"], + data = ["@bazel_tools//tools/bash/runfiles"], visibility = ["//visibility:public"], -) \ No newline at end of file +) diff --git a/examples/args_location_expansion/doubly_transitioned_test.bzl b/examples/args_location_expansion/doubly_transitioned_test.bzl index 8fae382..4a9d374 100644 --- a/examples/args_location_expansion/doubly_transitioned_test.bzl +++ b/examples/args_location_expansion/doubly_transitioned_test.bzl @@ -2,5 +2,5 @@ load("@with_cfg.bzl", "with_cfg") load("//args_location_expansion/rules:defs.bzl", "transitioned_test") _builder = with_cfg(transitioned_test) -_builder.set(Label("//args_location_expansion/rules:with_cfg_setting"), "set by with_cfg") +_builder.set(Label("//args_location_expansion/rules:with_cfg_setting"), "with_cfg") doubly_transitioned_test, _doubly_transitioned_test_ = _builder.build() diff --git a/examples/args_location_expansion/rules/defs.bzl b/examples/args_location_expansion/rules/defs.bzl index 10aafbb..56ad5c5 100644 --- a/examples/args_location_expansion/rules/defs.bzl +++ b/examples/args_location_expansion/rules/defs.bzl @@ -1,12 +1,16 @@ +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + def _write_settings_rule_impl(ctx): # type: (ctx) -> None - out = ctx.actions.declare_file(ctx.label.name) - ctx.actions.write(out, -"""\ -name = {} -rule_setting = {} -with_cfg_setting = {} -""".format(ctx.label.name, ctx.attr._rule_setting, ctx.attr._with_cfg_setting)) + rule_setting = ctx.attr._rule_setting[BuildSettingInfo].value + # if rule_setting == "unset": + # fail("rule_setting is unset") + with_cfg_setting = ctx.attr._with_cfg_setting[BuildSettingInfo].value + # if with_cfg_setting == "unset": + # fail("with_cfg_setting is unset") + + out = ctx.actions.declare_file(ctx.label.name + "_" + rule_setting[0] + "_" + with_cfg_setting[0]) + ctx.actions.write(out, "name:{},rule_setting:{},with_cfg_setting:{}\n".format(ctx.label.name, rule_setting, with_cfg_setting)) return [DefaultInfo(files = depset([out]))] write_settings_rule = rule( @@ -19,7 +23,7 @@ write_settings_rule = rule( def _data_transition_impl(_settings, _attr): return { - "//args_location_expansion/rules:rule_setting": "set by rule transition", + "//args_location_expansion/rules:rule_setting": "rule", } _data_transition = transition( @@ -32,8 +36,11 @@ def _transitioned_test_impl(ctx): # type: (ctx) -> None executable = ctx.actions.declare_file(ctx.label.name) ctx.actions.symlink(output = executable, target_file = ctx.executable.binary) - runfiles = ctx.runfiles().merge_all([target[DefaultInfo].default_runfiles for target in ctx.attr.data]) + runfiles = ctx.runfiles() runfiles = runfiles.merge(ctx.attr.binary[DefaultInfo].default_runfiles) + for target in ctx.attr.data: + runfiles = runfiles.merge(ctx.runfiles(transitive_files = target[DefaultInfo].files)) + runfiles = runfiles.merge(target[DefaultInfo].data_runfiles) return [ DefaultInfo( executable = executable, diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index 7b1baf4..c5161a5 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -12,7 +12,19 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e # --- end runfiles.bash initialization v3 --- +function check_runfile() { + real_path=$(rlocation "$1" || { >&2 echo "$1 not found"; exit 1; }) + basename=$(basename "$1") + if [ "$(cat "$real_path")" != "name:$basename,rule_setting:rule,with_cfg_setting:with_cfg" ]; then + echo "Runfile content mismatch: $1" + exit 1 + fi +} + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + exit 1 +fi for arg in "$@"; do - path=$(rlocation "$arg") - cat "$path" + check_runfile "$arg" done \ No newline at end of file From 0aca4e193a5b2ab214e2aa7dc3dfd8b41c87b0a7 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 10:09:14 +0200 Subject: [PATCH 03/14] Start work on args.bzl --- with_cfg/private/args.bzl | 110 +++++++++++++++++++++++ with_cfg/private/rewrite.bzl | 8 +- with_cfg/private/transitioning_alias.bzl | 2 + 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 with_cfg/private/args.bzl diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl new file mode 100644 index 0000000..6f30925 --- /dev/null +++ b/with_cfg/private/args.bzl @@ -0,0 +1,110 @@ +load(":rewrite.bzl", "rewrite_locations_in_single_value") + +visibility("private") + +def escape_label(label): + # type: (Label) -> str + # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/actions/Actions.java#L375-L381 + path = label.package + ":" + label.name + if label.repo_name: + path = label.repo_name + "@" + path + return path.replace("_", "_U").replace("/", "_S").replace("\\", "_B").replace(":", "_C").replace("@", "_A") + +_LOCATION_EXPANSION_ARGS = [ + # keep sorted + "data", + "deps", + "implementation_deps", + "srcs", + "tools", +] + +_OUTPUT_GROUPS_PREFIX = "_with_cfg.bzl_args__" + +def _args_aspect_impl(target, ctx): + # type: (Target, ctx) -> list[Provider] + if not hasattr(ctx.rule.attr, "args"): + return [] + + execpaths_expansion_to_files = {} + targets = {} + + # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java#L446-L516 + for attr in _LOCATION_EXPANSION_ARGS: + deps = getattr(ctx.rule.attr, attr, []) + if type(deps) != type([]): + continue + for target in deps: + default_info = target[DefaultInfo] + if default_info.files_to_run and default_info.files_to_run.executable: + files = depset([default_info.files_to_run.executable]) + else: + files = default_info.files + + # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/analysis/LocationExpander.java#L338-L348 + sorted_paths = sorted([_callable_path_string(f) for f in files.to_list()]) + execpaths_expansion = " ".join([_shell_escape(p) for p in sorted_paths]) + execpaths_expansion_to_files[execpaths_expansion] = files + targets[target] = None + + labels = {} + def collect_label(label): + labels[label] = None + return label + for arg in ctx.rule.attr.args: + rewrite_locations_in_single_value(arg, collect_label) + + labels_to_files = {} + for label in labels.keys(): + execpaths_expansion = ctx.expand_location("$(execpaths {})".format(label), targets = targets.keys()) + labels_to_files[label] = execpaths_expansion_to_files[execpaths_expansion] + + return [ + OutputGroupInfo(**{_OUTPUT_GROUPS_PREFIX + l: f for l, f in labels_to_files.items()}), + ] + +args_aspect = aspect( + implementation = _args_aspect_impl, +) + +def _callable_path_string(file): + # type: (File) -> str + # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java#L625-L631 + path = file.path + if not path: + return "." + if not "/" in path: + return "./" + path + return path + +# Based on +# https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/starlark/builtins_bzl/common/java/java_helper.bzl#L365-L386 +# Modified to handle ~ analogous to +# https://github.com/bazelbuild/bazel/blob/30f6c8238f39c4a396b3cb56a98c1a2e79d10bb9/src/main/java/com/google/devtools/build/lib/util/ShellEscaper.java#L106-L108 +def _shell_escape(s): + """Shell-escape a string + + Quotes a word so that it can be used, without further quoting, as an argument + (or part of an argument) in a shell command. + + Args: + s: (str) the string to escape + + Returns: + (str) the shell-escaped string + """ + if not s: + # Empty string is a special case: needs to be quoted to ensure that it + # gets treated as a separate argument. + return "''" + must_escape = s.startswith("~") + for c in s.elems(): + # We do this positively so as to be sure we don't inadvertently forget + # any unsafe characters. + if not c.isalnum() and c not in "@%-_+:,./~": + must_escape = True + break + if must_escape: + return "'" + s.replace("'", "'\\''") + "'" + else: + return s \ No newline at end of file diff --git a/with_cfg/private/rewrite.bzl b/with_cfg/private/rewrite.bzl index e7a9806..ff73e5f 100644 --- a/with_cfg/private/rewrite.bzl +++ b/with_cfg/private/rewrite.bzl @@ -22,7 +22,7 @@ def _rewrite_locations_in_value(value, label_rewriter): return value if is_dict(value): return { - _rewrite_locations_in_single_value(k, label_rewriter): _rewrite_locations_in_list_or_single_value(v, label_rewriter) + rewrite_locations_in_single_value(k, label_rewriter): _rewrite_locations_in_list_or_single_value(v, label_rewriter) for k, v in value.items() } return _rewrite_locations_in_list_or_single_value(value, label_rewriter) @@ -31,13 +31,13 @@ def _rewrite_locations_in_list_or_single_value(value, label_rewriter): if not value: return value if is_list(value): - return [_rewrite_locations_in_single_value(v, label_rewriter) for v in value] - return _rewrite_locations_in_single_value(value, label_rewriter) + return [rewrite_locations_in_single_value(v, label_rewriter) for v in value] + return rewrite_locations_in_single_value(value, label_rewriter) # Based on: # https://github.com/bazelbuild/bazel/blob/9bf8f396db5c8b204c61b34638ca15ece0328fc0/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl#L777C1-L830C27 # SPDX: Apache-2.0 -def _rewrite_locations_in_single_value(expression, label_rewriter): +def rewrite_locations_in_single_value(expression, label_rewriter): if not is_string(expression): return expression if "$(" not in expression: diff --git a/with_cfg/private/transitioning_alias.bzl b/with_cfg/private/transitioning_alias.bzl index d1979de..9edc4cc 100644 --- a/with_cfg/private/transitioning_alias.bzl +++ b/with_cfg/private/transitioning_alias.bzl @@ -1,3 +1,4 @@ +load(":args.bzl", "args_aspect") load(":providers.bzl", "FrontendInfo", "OriginalSettingsInfo") load(":setting.bzl", "get_attr_type", "validate_and_get_attr_name") @@ -30,6 +31,7 @@ def make_transitioning_alias(*, providers, transition, values, original_settings "exports": attr.label( allow_files = True, cfg = transition, + aspects = [args_aspect], ), "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", From 7755a80f3f565bf8bace510baf463662b5544f01 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 11:40:53 +0200 Subject: [PATCH 04/14] Passing test --- examples/args_location_expansion/BUILD.bazel | 20 +++++- .../args_location_expansion/pkg/BUILD.bazel | 21 +++++- .../args_location_expansion/rules/defs.bzl | 10 +-- examples/args_location_expansion/test_bin.sh | 9 +-- with_cfg/private/args.bzl | 66 ++++++++++++------- with_cfg/private/frontend.bzl | 1 + with_cfg/private/wrapper.bzl | 44 ++++++------- 7 files changed, 110 insertions(+), 61 deletions(-) diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel index f72090b..bf2715a 100644 --- a/examples/args_location_expansion/BUILD.bazel +++ b/examples/args_location_expansion/BUILD.bazel @@ -3,18 +3,34 @@ load(":doubly_transitioned_test.bzl", "doubly_transitioned_test") write_settings_rule( name = "single_rule", + tags = ["manual"], +) + +alias( + name = "alias_target", + actual = "//args_location_expansion/pkg:aliased_rule", + tags = ["manual"], ) doubly_transitioned_test( name = "doubly_transitioned_test", args = [ "$(rlocationpath :single_rule)", - "$(rlocationpaths //args_location_expansion/pkg:all_rules)", + "$(rlocationpaths //args_location_expansion/pkg:multiple_rules)", + "$(rlocationpath alias_target)", + "$(rlocationpath :alias_target)", + "$(rlocationpath @bazel_tools//tools/bash/runfiles)", + "$(rlocationpath //args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule)", + "_main/$(rootpath :single_rule)", + "_main/$(location :single_rule)", ], binary = ":test_bin", data = [ + ":alias_target", ":single_rule", - "//args_location_expansion/pkg:all_rules", + "//args_location_expansion/pkg:multiple_rules", + "//args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule", + "@bazel_tools//tools/bash/runfiles", ], ) diff --git a/examples/args_location_expansion/pkg/BUILD.bazel b/examples/args_location_expansion/pkg/BUILD.bazel index ab3fc95..82150ed 100644 --- a/examples/args_location_expansion/pkg/BUILD.bazel +++ b/examples/args_location_expansion/pkg/BUILD.bazel @@ -2,17 +2,32 @@ load("//args_location_expansion/rules:defs.bzl", "write_settings_rule") write_settings_rule( name = "some_rule", + tags = ["manual"], ) write_settings_rule( name = "other_rule", + tags = ["manual"], ) filegroup( - name = "all_rules", + name = "multiple_rules", srcs = [ - ":some_rule", ":other_rule", + ":some_rule", ], visibility = ["//visibility:public"], -) \ No newline at end of file +) + +write_settings_rule( + name = "aliased_rule", + tags = ["manual"], + visibility = ["//visibility:public"], +) + +write_settings_rule( + # Omits ')' as it doesn't seem to be supported with location expansion. + name = "special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule", + tags = ["manual"], + visibility = ["//visibility:public"], +) diff --git a/examples/args_location_expansion/rules/defs.bzl b/examples/args_location_expansion/rules/defs.bzl index 56ad5c5..2db3bb8 100644 --- a/examples/args_location_expansion/rules/defs.bzl +++ b/examples/args_location_expansion/rules/defs.bzl @@ -3,14 +3,14 @@ load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") def _write_settings_rule_impl(ctx): # type: (ctx) -> None rule_setting = ctx.attr._rule_setting[BuildSettingInfo].value - # if rule_setting == "unset": - # fail("rule_setting is unset") + if rule_setting == "unset": + fail("rule_setting is unset") with_cfg_setting = ctx.attr._with_cfg_setting[BuildSettingInfo].value - # if with_cfg_setting == "unset": - # fail("with_cfg_setting is unset") + if with_cfg_setting == "unset": + fail("with_cfg_setting is unset") out = ctx.actions.declare_file(ctx.label.name + "_" + rule_setting[0] + "_" + with_cfg_setting[0]) - ctx.actions.write(out, "name:{},rule_setting:{},with_cfg_setting:{}\n".format(ctx.label.name, rule_setting, with_cfg_setting)) + ctx.actions.write(out, "name:{},rule_setting:{},with_cfg_setting:{}\n".format(out.basename, rule_setting, with_cfg_setting)) return [DefaultInfo(files = depset([out]))] write_settings_rule = rule( diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index c5161a5..e071649 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -15,14 +15,15 @@ source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ function check_runfile() { real_path=$(rlocation "$1" || { >&2 echo "$1 not found"; exit 1; }) basename=$(basename "$1") - if [ "$(cat "$real_path")" != "name:$basename,rule_setting:rule,with_cfg_setting:with_cfg" ]; then - echo "Runfile content mismatch: $1" + want="name:$basename,rule_setting:rule,with_cfg_setting:with_cfg" + if [[ $1 != bazel_tools/* && "$(cat "$real_path")" != "$want" ]]; then + echo "Runfile content mismatch in $1: got '$(cat "$real_path")', want '$want'" exit 1 fi } -if [ "$#" -ne 3 ]; then - echo "Usage: $0 " +if [ "$#" -ne 9 ]; then + echo "Unexpected number of arguments: $#, want 9" exit 1 fi for arg in "$@"; do diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index 6f30925..b5f64c7 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -1,25 +1,28 @@ -load(":rewrite.bzl", "rewrite_locations_in_single_value") +load(":rewrite.bzl", "rewrite_locations_in_attr", "rewrite_locations_in_single_value") visibility("private") -def escape_label(label): - # type: (Label) -> str - # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/actions/Actions.java#L375-L381 - path = label.package + ":" + label.name - if label.repo_name: - path = label.repo_name + "@" + path - return path.replace("_", "_U").replace("/", "_S").replace("\\", "_B").replace(":", "_C").replace("@", "_A") - -_LOCATION_EXPANSION_ARGS = [ - # keep sorted - "data", - "deps", - "implementation_deps", - "srcs", - "tools", -] - -_OUTPUT_GROUPS_PREFIX = "_with_cfg.bzl_args__" +def rewrite_args(name, args, testonly): + # type: (string, list[string], bool) -> tuple[list[string], list[Label]] + seen_labels = {} + filegroup_labels = [] + + def rewrite_label(label_string): + # type: (string) -> string + escaped_label = _escape_label(label_string) + filegroup_name = name + "__args__" + escaped_label + if label_string not in seen_labels: + seen_labels[label_string] = None + native.filegroup( + name = filegroup_name, + srcs = [":" + name], + output_group = _OUTPUT_GROUPS_PREFIX + label_string, + testonly = testonly, + ) + filegroup_labels.append(native.package_relative_label(filegroup_name)) + return ":" + filegroup_name + + return rewrite_locations_in_attr(args, rewrite_label), filegroup_labels def _args_aspect_impl(target, ctx): # type: (Target, ctx) -> list[Provider] @@ -48,9 +51,11 @@ def _args_aspect_impl(target, ctx): targets[target] = None labels = {} + def collect_label(label): labels[label] = None return label + for arg in ctx.rule.attr.args: rewrite_locations_in_single_value(arg, collect_label) @@ -60,13 +65,24 @@ def _args_aspect_impl(target, ctx): labels_to_files[label] = execpaths_expansion_to_files[execpaths_expansion] return [ - OutputGroupInfo(**{_OUTPUT_GROUPS_PREFIX + l: f for l, f in labels_to_files.items()}), + OutputGroupInfo(**{_OUTPUT_GROUPS_PREFIX + label: f for label, f in labels_to_files.items()}), ] args_aspect = aspect( implementation = _args_aspect_impl, ) +_LOCATION_EXPANSION_ARGS = [ + # keep sorted + "data", + "deps", + "implementation_deps", + "srcs", + "tools", +] + +_OUTPUT_GROUPS_PREFIX = "_with_cfg.bzl_args__" + def _callable_path_string(file): # type: (File) -> str # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java#L625-L631 @@ -79,9 +95,9 @@ def _callable_path_string(file): # Based on # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/starlark/builtins_bzl/common/java/java_helper.bzl#L365-L386 -# Modified to handle ~ analogous to +# Modified to handle ~ in the same way as # https://github.com/bazelbuild/bazel/blob/30f6c8238f39c4a396b3cb56a98c1a2e79d10bb9/src/main/java/com/google/devtools/build/lib/util/ShellEscaper.java#L106-L108 -def _shell_escape(s): +def _shell_escape(s): # type: (string) -> string """Shell-escape a string Quotes a word so that it can be used, without further quoting, as an argument @@ -107,4 +123,8 @@ def _shell_escape(s): if must_escape: return "'" + s.replace("'", "'\\''") + "'" else: - return s \ No newline at end of file + return s + +def _escape_label(label_string): # type: (string) -> string + # https://github.com/bazelbuild/bazel/blob/af8deb85cbc627a507605e67aa71e829f7db630f/src/main/java/com/google/devtools/build/lib/actions/Actions.java#L375-L381 + return label_string.replace("_", "_U").replace("/", "_S").replace("\\", "_B").replace(":", "_C").replace("@", "_A") diff --git a/with_cfg/private/frontend.bzl b/with_cfg/private/frontend.bzl index 0ba98b8..c5fb36f 100644 --- a/with_cfg/private/frontend.bzl +++ b/with_cfg/private/frontend.bzl @@ -69,6 +69,7 @@ def _clean_run_environment_info(run_environment_info): ) _frontend_attrs = { + "data": attr.label_list(allow_files = True), "env": attr.string_dict(), "env_inherit": attr.string_list(), # This attribute name is internal only, so it can only help to choose a diff --git a/with_cfg/private/wrapper.bzl b/with_cfg/private/wrapper.bzl index 33a10b2..e0c6200 100644 --- a/with_cfg/private/wrapper.bzl +++ b/with_cfg/private/wrapper.bzl @@ -1,3 +1,4 @@ +load(":args.bzl", "rewrite_args") load(":rewrite.bzl", "make_label_rewriter", "rewrite_locations_in_attr") load(":select.bzl", "map_attr") load(":setting.bzl", "validate_and_get_attr_name") @@ -40,22 +41,13 @@ _COMMON_ATTRS = [ "toolchains", ] -# Attributes common to all executable and test rules. -# These attributes are applied to the original target and the frontend if the original target is -# executable. -# env and env_inherit are covered by the forwarded RunEnvironmentInfo instead. -_EXECUTABLE_ATTRS = [ - # keep sorted - "args", -] - # Attributes common to all test rules. # These attributes are applied to the original target and the frontend if the original target is a # test. +# args is treated specially. # env and env_inherit are covered by the forwarded RunEnvironmentInfo instead. _TEST_ATTRS = [ # keep sorted - "args", "flaky", "local", "shard_count", @@ -73,6 +65,14 @@ def _wrapper( values, original_settings_label, attrs_to_reset): + dirname, separator, basename = name.rpartition("/") + original_name = "{dirname}{separator}{basename}_/{basename}".format( + dirname = dirname, + separator = separator, + basename = basename, + ) + alias_name = name + "_with_cfg" + tags = kwargs.pop("tags", None) if not tags: tags_with_manual = ["manual"] @@ -101,12 +101,6 @@ def _wrapper( for attr in _TEST_ATTRS if attr in kwargs } - elif rule_info.executable: - extra_attrs = { - attr: kwargs.pop(attr) - for attr in _EXECUTABLE_ATTRS - if attr in kwargs - } else: extra_attrs = {} @@ -118,13 +112,15 @@ def _wrapper( if "env_inherit" in kwargs: extra_attrs["env_inherit"] = kwargs.pop("env_inherit") - dirname, separator, basename = name.rpartition("/") - original_name = "{dirname}{separator}{basename}_/{basename}".format( - dirname = dirname, - separator = separator, - basename = basename, - ) - alias_name = name + "_with_cfg" + frontend_attrs = {} + if "args" in kwargs: + # Leave the args attribute in place on the original rule in case it processes it in a + # non-standard way. + frontend_attrs["args"], frontend_attrs["data"] = rewrite_args( + alias_name, + kwargs["args"], + common_attrs.get("testonly", False), + ) processed_kwargs = _process_attrs_for_reset( attrs = kwargs, @@ -164,7 +160,7 @@ def _wrapper( exports = ":" + alias_name, tags = tags, visibility = visibility, - **(common_attrs | extra_attrs) + **(common_attrs | extra_attrs | frontend_attrs) ) for implicit_target in rule_info.implicit_targets: From 67252c44efb52a9429fe36bfda3659c71657b051 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 11:42:12 +0200 Subject: [PATCH 05/14] Test source file --- examples/args_location_expansion/BUILD.bazel | 2 ++ examples/args_location_expansion/source_file.txt | 1 + examples/args_location_expansion/test_bin.sh | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 examples/args_location_expansion/source_file.txt diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel index bf2715a..c71a8c8 100644 --- a/examples/args_location_expansion/BUILD.bazel +++ b/examples/args_location_expansion/BUILD.bazel @@ -15,6 +15,7 @@ alias( doubly_transitioned_test( name = "doubly_transitioned_test", args = [ + "$(rlocationpath :source_file.txt)", "$(rlocationpath :single_rule)", "$(rlocationpaths //args_location_expansion/pkg:multiple_rules)", "$(rlocationpath alias_target)", @@ -28,6 +29,7 @@ doubly_transitioned_test( data = [ ":alias_target", ":single_rule", + ":source_file.txt", "//args_location_expansion/pkg:multiple_rules", "//args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule", "@bazel_tools//tools/bash/runfiles", diff --git a/examples/args_location_expansion/source_file.txt b/examples/args_location_expansion/source_file.txt new file mode 100644 index 0000000..a9c2200 --- /dev/null +++ b/examples/args_location_expansion/source_file.txt @@ -0,0 +1 @@ +name:source_file.txt,rule_setting:rule,with_cfg_setting:with_cfg diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index e071649..7e17b96 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -22,8 +22,8 @@ function check_runfile() { fi } -if [ "$#" -ne 9 ]; then - echo "Unexpected number of arguments: $#, want 9" +if [ "$#" -ne 10 ]; then + echo "Unexpected number of arguments: $#, want 10" exit 1 fi for arg in "$@"; do From 5ed9d970f320730e5b6fcbe383cae286fe2b32e0 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 11:48:28 +0200 Subject: [PATCH 06/14] Add test for select and refactor --- examples/args_location_expansion/BUILD.bazel | 10 ++++++++-- examples/args_location_expansion/pkg/BUILD.bazel | 12 ++++++++++++ examples/args_location_expansion/test_bin.sh | 4 ++-- with_cfg/private/args.bzl | 7 +++---- with_cfg/private/wrapper.bzl | 9 ++++++++- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel index c71a8c8..cf01437 100644 --- a/examples/args_location_expansion/BUILD.bazel +++ b/examples/args_location_expansion/BUILD.bazel @@ -24,7 +24,10 @@ doubly_transitioned_test( "$(rlocationpath //args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule)", "_main/$(rootpath :single_rule)", "_main/$(location :single_rule)", - ], + ] + select({ + "@platforms//os:linux": ["$(rlocationpath //args_location_expansion/pkg:linux_only_rule)"], + "//conditions:default": ["$(rlocationpath //args_location_expansion/pkg:generic_rule)"], + }), binary = ":test_bin", data = [ ":alias_target", @@ -33,7 +36,10 @@ doubly_transitioned_test( "//args_location_expansion/pkg:multiple_rules", "//args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule", "@bazel_tools//tools/bash/runfiles", - ], + ] + select({ + "@platforms//os:linux": ["//args_location_expansion/pkg:linux_only_rule"], + "//conditions:default": ["//args_location_expansion/pkg:generic_rule"], + }), ) sh_binary( diff --git a/examples/args_location_expansion/pkg/BUILD.bazel b/examples/args_location_expansion/pkg/BUILD.bazel index 82150ed..9e47d99 100644 --- a/examples/args_location_expansion/pkg/BUILD.bazel +++ b/examples/args_location_expansion/pkg/BUILD.bazel @@ -31,3 +31,15 @@ write_settings_rule( tags = ["manual"], visibility = ["//visibility:public"], ) + +write_settings_rule( + name = "linux_only_rule", + tags = ["manual"], + visibility = ["//visibility:public"], +) + +write_settings_rule( + name = "generic_rule", + tags = ["manual"], + visibility = ["//visibility:public"], +) diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index 7e17b96..8339063 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -22,8 +22,8 @@ function check_runfile() { fi } -if [ "$#" -ne 10 ]; then - echo "Unexpected number of arguments: $#, want 10" +if [ "$#" -ne 11 ]; then + echo "Unexpected number of arguments: $#, want 11" exit 1 fi for arg in "$@"; do diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index b5f64c7..08469c3 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -2,8 +2,8 @@ load(":rewrite.bzl", "rewrite_locations_in_attr", "rewrite_locations_in_single_v visibility("private") -def rewrite_args(name, args, testonly): - # type: (string, list[string], bool) -> tuple[list[string], list[Label]] +def rewrite_args(name, args, make_filegroup): + # type: (string, list[string], Any) -> tuple[list[string], list[Label]] seen_labels = {} filegroup_labels = [] @@ -13,11 +13,10 @@ def rewrite_args(name, args, testonly): filegroup_name = name + "__args__" + escaped_label if label_string not in seen_labels: seen_labels[label_string] = None - native.filegroup( + make_filegroup( name = filegroup_name, srcs = [":" + name], output_group = _OUTPUT_GROUPS_PREFIX + label_string, - testonly = testonly, ) filegroup_labels.append(native.package_relative_label(filegroup_name)) return ":" + filegroup_name diff --git a/with_cfg/private/wrapper.bzl b/with_cfg/private/wrapper.bzl index e0c6200..ad1485c 100644 --- a/with_cfg/private/wrapper.bzl +++ b/with_cfg/private/wrapper.bzl @@ -119,7 +119,14 @@ def _wrapper( frontend_attrs["args"], frontend_attrs["data"] = rewrite_args( alias_name, kwargs["args"], - common_attrs.get("testonly", False), + lambda *, name, srcs, output_group: native.filegroup( + name = name, + srcs = srcs, + output_group = output_group, + testonly = common_attrs.get("testonly", False), + tags = ["manual"], + visibility = ["//visibility:private"], + ), ) processed_kwargs = _process_attrs_for_reset( From 8227a384cc91733977025105dbab4209f7f741a2 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:17:10 +0200 Subject: [PATCH 07/14] Add comment --- with_cfg/private/args.bzl | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index 08469c3..487cda7 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -1,3 +1,36 @@ +""" +Logic for setting "args" on a transitioned rule with location expansion. + +Compared to "env" and "env_inherit", which are backed by a provider, "args" +handling in Bazel is still based on "magic" handling in the core and thus much +more difficult to generically forward. This results in the following +complexities handled by the functions in this file: + +1. The way locations expand in "args" depends on the configuration of the + underlying target, which can be affected by transitions both by with_cfg.bzl + and the rule itself. We thus need to obtain the expanded locations from the + rule context instead of e.g. rewriting labels to helper targets during the + loading phase, which would miss the effect of transitions applied by the rule + itself. + We use a non-recursing aspect on the original rule to collect the files + corresponding to labels mentioned in location expansion in "args" and provide + them to the frontend rule via output groups named after the user-provided + label strings. +2. "args" can only be set at load time via the magic attribute and the only way + to get analysis time information into it is via the hard-coded location + expansion applied to it in + https://github.com/bazelbuild/bazel/blob/9425e365ebf921d4286fcf159b429e38f6b0a48f/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java#L525 + We create a helper `filegroup` target for each unique label string mentioned + in a location expansion expression in "args", add it to the (otherwise + unused) `data` attribute of the frontend and rewrite the label strings to + instead point to the `filegroup` targets. +3. `native.package_relative_label` is not available in the analysis phase and + rule or aspect implementation logic can't see the labels of alias targets, + so the only way to reliably match user-provided labels to the files they + represent is to query `ctx.expand_location("$(execpaths ...)")` and manually + collect the files with the given paths. +""" + load(":rewrite.bzl", "rewrite_locations_in_attr", "rewrite_locations_in_single_value") visibility("private") From 9823b17789339a6a84b81271fe2a126b070d3bd7 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:24:59 +0200 Subject: [PATCH 08/14] Cleanup --- examples/args_location_expansion/rules/BUILD.bazel | 2 +- examples/args_location_expansion/test_bin.sh | 2 +- with_cfg/private/args.bzl | 4 +++- with_cfg/private/wrapper.bzl | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/args_location_expansion/rules/BUILD.bazel b/examples/args_location_expansion/rules/BUILD.bazel index 21ea27f..d928598 100644 --- a/examples/args_location_expansion/rules/BUILD.bazel +++ b/examples/args_location_expansion/rules/BUILD.bazel @@ -10,4 +10,4 @@ string_setting( name = "with_cfg_setting", build_setting_default = "unset", visibility = ["//visibility:public"], -) \ No newline at end of file +) diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index 8339063..8129f53 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -28,4 +28,4 @@ if [ "$#" -ne 11 ]; then fi for arg in "$@"; do check_runfile "$arg" -done \ No newline at end of file +done diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index 487cda7..3ea456d 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -15,7 +15,9 @@ complexities handled by the functions in this file: We use a non-recursing aspect on the original rule to collect the files corresponding to labels mentioned in location expansion in "args" and provide them to the frontend rule via output groups named after the user-provided - label strings. + label strings. As a consequence, we also have to set the "args" attribute on + the underlying target so that the aspect can see it - aspect attributes are + limited to integers and string enums. 2. "args" can only be set at load time via the magic attribute and the only way to get analysis time information into it is via the hard-coded location expansion applied to it in diff --git a/with_cfg/private/wrapper.bzl b/with_cfg/private/wrapper.bzl index ad1485c..73fa461 100644 --- a/with_cfg/private/wrapper.bzl +++ b/with_cfg/private/wrapper.bzl @@ -114,8 +114,8 @@ def _wrapper( frontend_attrs = {} if "args" in kwargs: - # Leave the args attribute in place on the original rule in case it processes it in a - # non-standard way. + # Leave the args attribute in place on the original rule so that they can be read by the + # args_aspect attached to the exports attribute of the transitioning_alias. frontend_attrs["args"], frontend_attrs["data"] = rewrite_args( alias_name, kwargs["args"], From 9b72720c9f46c00d14eceb01d0e298a536a62180 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:30:01 +0200 Subject: [PATCH 09/14] Fix transition --- examples/args_location_expansion/rules/defs.bzl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/args_location_expansion/rules/defs.bzl b/examples/args_location_expansion/rules/defs.bzl index 2db3bb8..09ab4a3 100644 --- a/examples/args_location_expansion/rules/defs.bzl +++ b/examples/args_location_expansion/rules/defs.bzl @@ -59,6 +59,9 @@ transitioned_test = rule( cfg = _data_transition, allow_files = True, ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), }, test = True, ) From 4e43f75c80b260f36a08722f29faea1d3c085181 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:32:01 +0200 Subject: [PATCH 10/14] Add manual tag --- examples/args_location_expansion/pkg/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/args_location_expansion/pkg/BUILD.bazel b/examples/args_location_expansion/pkg/BUILD.bazel index 9e47d99..16bdafb 100644 --- a/examples/args_location_expansion/pkg/BUILD.bazel +++ b/examples/args_location_expansion/pkg/BUILD.bazel @@ -16,6 +16,7 @@ filegroup( ":other_rule", ":some_rule", ], + tags = ["manual"], visibility = ["//visibility:public"], ) From 9dd31438bd2b084c6ae1fc9e139405b94ff980ed Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:35:42 +0200 Subject: [PATCH 11/14] Work around buildifier issue --- with_cfg/private/args.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index 3ea456d..364fada 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -86,6 +86,8 @@ def _args_aspect_impl(target, ctx): labels = {} + # buildifier thinks that "label" references the variable in the for loop below. + # buildifier: disable=uninitialized def collect_label(label): labels[label] = None return label From dd51d4a4f5af29bc62181046bb6307f42fadf21e Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:40:04 +0200 Subject: [PATCH 12/14] Add bzl_library target --- with_cfg/private/BUILD.bazel | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/with_cfg/private/BUILD.bazel b/with_cfg/private/BUILD.bazel index 5e07905..c556d34 100644 --- a/with_cfg/private/BUILD.bazel +++ b/with_cfg/private/BUILD.bazel @@ -20,6 +20,15 @@ config_setting( }, ) +bzl_library( + name = "args", + srcs = ["args.bzl"], + visibility = ["//with_cfg:__subpackages__"], + deps = [ + ":rewrite", + ], +) + bzl_library( name = "builder", srcs = ["builder.bzl"], @@ -136,6 +145,7 @@ bzl_library( srcs = ["wrapper.bzl"], visibility = ["//with_cfg:__subpackages__"], deps = [ + ":args", ":rewrite", ":select", ":setting", From 64f25e1abd2ffba137ae8e298e0d7e142e7d8293 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 12:46:18 +0200 Subject: [PATCH 13/14] Update buildifier --- MODULE.bazel | 2 +- with_cfg/private/args.bzl | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index ebf76a0..61bb2b6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -8,7 +8,7 @@ bazel_dep(name = "bazel_skylib", version = "1.4.1") bazel_dep(name = "aspect_bazel_lib", version = "1.34.0", dev_dependency = True) bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.4.1", dev_dependency = True) -bazel_dep(name = "buildifier_prebuilt", version = "6.1.0", dev_dependency = True) +bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True) bazel_dep(name = "gazelle", version = "0.33.0", dev_dependency = True, repo_name = "bazel_gazelle") bazel_dep(name = "platforms", version = "0.0.6", dev_dependency = True) bazel_dep(name = "rules_testing", version = "0.4.0", dev_dependency = True) diff --git a/with_cfg/private/args.bzl b/with_cfg/private/args.bzl index 364fada..3ea456d 100644 --- a/with_cfg/private/args.bzl +++ b/with_cfg/private/args.bzl @@ -86,8 +86,6 @@ def _args_aspect_impl(target, ctx): labels = {} - # buildifier thinks that "label" references the variable in the for loop below. - # buildifier: disable=uninitialized def collect_label(label): labels[label] = None return label From de146997451219d584daa6a1a3b58124f1664c0f Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Mon, 22 Jul 2024 15:31:49 +0200 Subject: [PATCH 14/14] exclude --- examples/args_location_expansion/BUILD.bazel | 12 ++++++++++-- examples/args_location_expansion/rules/defs.bzl | 4 ++++ examples/args_location_expansion/test_bin.sh | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/examples/args_location_expansion/BUILD.bazel b/examples/args_location_expansion/BUILD.bazel index cf01437..7bd8415 100644 --- a/examples/args_location_expansion/BUILD.bazel +++ b/examples/args_location_expansion/BUILD.bazel @@ -21,12 +21,14 @@ doubly_transitioned_test( "$(rlocationpath alias_target)", "$(rlocationpath :alias_target)", "$(rlocationpath @bazel_tools//tools/bash/runfiles)", - "$(rlocationpath //args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule)", "_main/$(rootpath :single_rule)", "_main/$(location :single_rule)", ] + select({ "@platforms//os:linux": ["$(rlocationpath //args_location_expansion/pkg:linux_only_rule)"], "//conditions:default": ["$(rlocationpath //args_location_expansion/pkg:generic_rule)"], + }) + select({ + "@platforms//os:windows": [], + "//conditions:default": ["$(rlocationpath //args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule)"], }), binary = ":test_bin", data = [ @@ -34,11 +36,17 @@ doubly_transitioned_test( ":single_rule", ":source_file.txt", "//args_location_expansion/pkg:multiple_rules", - "//args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule", "@bazel_tools//tools/bash/runfiles", ] + select({ "@platforms//os:linux": ["//args_location_expansion/pkg:linux_only_rule"], "//conditions:default": ["//args_location_expansion/pkg:generic_rule"], + }) + select({ + "@platforms//os:windows": [], + "//conditions:default": ["//args_location_expansion/pkg:special_09!%-@^_\"#$&'(*-+,;<=>?[]{|}~/._characters_rule"], + }), + env = select({ + "@platforms//os:windows": {"NUM_RUNFILES": "10"}, + "//conditions:default": {"NUM_RUNFILES": "11"}, }), ) diff --git a/examples/args_location_expansion/rules/defs.bzl b/examples/args_location_expansion/rules/defs.bzl index 09ab4a3..034b104 100644 --- a/examples/args_location_expansion/rules/defs.bzl +++ b/examples/args_location_expansion/rules/defs.bzl @@ -46,6 +46,9 @@ def _transitioned_test_impl(ctx): executable = executable, runfiles = runfiles, ), + RunEnvironmentInfo( + environment = ctx.attr.env, + ), ] transitioned_test = rule( @@ -59,6 +62,7 @@ transitioned_test = rule( cfg = _data_transition, allow_files = True, ), + "env": attr.string_dict(), "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ), diff --git a/examples/args_location_expansion/test_bin.sh b/examples/args_location_expansion/test_bin.sh index 8129f53..b64b353 100755 --- a/examples/args_location_expansion/test_bin.sh +++ b/examples/args_location_expansion/test_bin.sh @@ -22,8 +22,8 @@ function check_runfile() { fi } -if [ "$#" -ne 11 ]; then - echo "Unexpected number of arguments: $#, want 11" +if [ "$#" -ne "$NUM_RUNFILES" ]; then + echo "Unexpected number of arguments: $#, want $NUM_RUNFILES" exit 1 fi for arg in "$@"; do