From f038f728e12d293363a8aa8c8d5028c5df37312a Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Fri, 8 Apr 2022 15:38:39 +0200 Subject: [PATCH] Store pre-go_transition setting values This makes it possible to return to the original settings for non-Go dependencies, e.g. those in srcs or data. Using this transition on such an attribute realizes "configuration trimming" when combined with --experimental_output_directory_naming_scheme=diff_against_baseline. --- go/config/BUILD.bazel | 14 ++++++++ go/private/rules/transition.bzl | 59 ++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/go/config/BUILD.bazel b/go/config/BUILD.bazel index b832742767..da34f14b02 100644 --- a/go/config/BUILD.bazel +++ b/go/config/BUILD.bazel @@ -4,11 +4,16 @@ load( "bool_setting", "string_flag", "string_list_flag", + "string_setting", ) load( "//go/private:mode.bzl", "LINKMODE_NORMAL", ) +load( + "//go/private/rules:transition.bzl", + "TRANSITIONED_FLAGS", +) bool_flag( name = "static", @@ -58,6 +63,15 @@ string_list_flag( visibility = ["//visibility:public"], ) +[ + string_setting( + name = "original_" + flag, + build_setting_default = "", + visibility = ["//visibility:public"], + ) + for flag in TRANSITIONED_FLAGS +] + filegroup( name = "all_files", testonly = True, diff --git a/go/private/rules/transition.bzl b/go/private/rules/transition.bzl index 370b737bc1..7e6edaf8af 100644 --- a/go/private/rules/transition.bzl +++ b/go/private/rules/transition.bzl @@ -37,6 +37,15 @@ load( "platform_from_crosstool", ) +TRANSITIONED_FLAGS = [ + "static", + "race", + "msan", + "pure", + "linkmode", + "tags", +] + def filter_transition_label(label): """Transforms transition labels for the current workspace. @@ -54,6 +63,22 @@ def filter_transition_label(label): else: return str(Label(label)) +def _current_setting(attr): + return filter_transition_label("@io_bazel_rules_go//go/config:" + attr) + +def _original_setting(attr): + return filter_transition_label("@io_bazel_rules_go//go/config:original_" + attr) + +_TRANSITIONED_SETTINGS = [ + _current_setting(attr) + for attr in TRANSITIONED_FLAGS +] + +_TRANSITIONED_ORIGINAL_SETTINGS = [ + _original_setting(attr) + for attr in TRANSITIONED_FLAGS +] + def go_transition_wrapper(kind, transition_kind, name, **kwargs): """Wrapper for rules that may use transitions. @@ -116,6 +141,7 @@ def _go_transition_impl(settings, attr): # In any case, get_mode should mainly be responsible for reporting # invalid modes, since it also takes --features flags into account. + original_settings = settings settings = dict(settings) _set_ternary(settings, attr, "static") @@ -173,6 +199,15 @@ def _go_transition_impl(settings, attr): linkmode_label = filter_transition_label("@io_bazel_rules_go//go/config:linkmode") settings[linkmode_label] = linkmode + for setting, value in settings.items(): + if not "//go/config:" in setting: + continue + attr = setting.split(":")[1] + if value != original_settings[setting]: + settings[_original_setting(attr)] = json.encode(value) + else: + settings[_original_setting(attr)] = "" + return settings def _request_nogo_transition(settings, attr): @@ -218,7 +253,7 @@ go_transition = transition( "@io_bazel_rules_go//go/config:pure", "@io_bazel_rules_go//go/config:tags", "@io_bazel_rules_go//go/config:linkmode", - ]], + ]] + _TRANSITIONED_ORIGINAL_SETTINGS, ) _common_reset_transition_dict = { @@ -372,6 +407,28 @@ so we can apply both transitions. """, ) +def _go_non_go_reset_transition_impl(settings, attr): + new_settings = {} + for flag in TRANSITIONED_FLAGS: + setting = _current_setting(flag) + original_setting = _original_setting(flag) + original_value = settings[original_setting] + if original_value: + # Reset to the original value and clear it. + new_settings[setting] = json.decode(original_value) + new_settings[original_setting] = "" + else: + new_settings[setting] = settings[setting] + new_settings[original_setting] = settings[original_setting] + + return new_settings + +go_non_go_reset_transition = transition( + implementation = _go_non_go_reset_transition_impl, + inputs = _TRANSITIONED_SETTINGS + _TRANSITIONED_ORIGINAL_SETTINGS, + outputs = _TRANSITIONED_SETTINGS + _TRANSITIONED_ORIGINAL_SETTINGS, +) + def _check_ternary(name, value): if value not in ("on", "off", "auto"): fail('{}: must be "on", "off", or "auto"'.format(name))