-
-
Notifications
You must be signed in to change notification settings - Fork 678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trim transitioned Go settings on non-Go dependencies #3108
Changes from 3 commits
31bf619
8d3d3ca
e567994
3859f9d
b2608bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,6 +37,18 @@ load( | |||||||||||
"platform_from_crosstool", | ||||||||||||
) | ||||||||||||
|
||||||||||||
# A list of rules_go settings that are possibly set by go_transition. | ||||||||||||
# Keep their package name in sync with the implementation of | ||||||||||||
# _original_setting_key. | ||||||||||||
TRANSITIONED_GO_SETTING_KEYS = [ | ||||||||||||
"@io_bazel_rules_go//go/config:static", | ||||||||||||
"@io_bazel_rules_go//go/config:msan", | ||||||||||||
"@io_bazel_rules_go//go/config:race", | ||||||||||||
"@io_bazel_rules_go//go/config:pure", | ||||||||||||
"@io_bazel_rules_go//go/config:linkmode", | ||||||||||||
"@io_bazel_rules_go//go/config:tags", | ||||||||||||
] | ||||||||||||
|
||||||||||||
def filter_transition_label(label): | ||||||||||||
"""Transforms transition labels for the current workspace. | ||||||||||||
|
||||||||||||
|
@@ -54,6 +66,14 @@ def filter_transition_label(label): | |||||||||||
else: | ||||||||||||
return str(Label(label)) | ||||||||||||
|
||||||||||||
def _original_setting_key(key): | ||||||||||||
if not "//go/config:" in key: | ||||||||||||
return None | ||||||||||||
name = key.split(":")[1] | ||||||||||||
return filter_transition_label("@io_bazel_rules_go//go/private/rules:original_" + name) | ||||||||||||
|
||||||||||||
_ORIGINAL_SETTING_KEYS = [_original_setting_key(setting) for setting in TRANSITIONED_GO_SETTING_KEYS] | ||||||||||||
|
||||||||||||
def go_transition_wrapper(kind, transition_kind, name, **kwargs): | ||||||||||||
"""Wrapper for rules that may use transitions. | ||||||||||||
|
||||||||||||
|
@@ -111,11 +131,15 @@ def go_transition_rule(**kwargs): | |||||||||||
return rule(**kwargs) | ||||||||||||
|
||||||||||||
def _go_transition_impl(settings, attr): | ||||||||||||
# NOTE: Keep the list of rules_go settings set by this transition in sync | ||||||||||||
# with POTENTIALLY_TRANSITIONED_SETTINGS. | ||||||||||||
# | ||||||||||||
# NOTE(bazelbuild/bazel#11409): Calling fail here for invalid combinations | ||||||||||||
# of flags reports an error but does not stop the build. | ||||||||||||
# 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 +197,26 @@ def _go_transition_impl(settings, attr): | |||||||||||
linkmode_label = filter_transition_label("@io_bazel_rules_go//go/config:linkmode") | ||||||||||||
settings[linkmode_label] = linkmode | ||||||||||||
|
||||||||||||
for key, value in settings.items(): | ||||||||||||
original_key = _original_setting_key(key) | ||||||||||||
if not original_key: | ||||||||||||
continue | ||||||||||||
|
||||||||||||
# If the outgoing configuration would differ from the incoming one in a | ||||||||||||
# value, record the old value in the special original_* key so that the | ||||||||||||
# real setting can be reset to this value before the new configuration | ||||||||||||
# would cross a non-deps dependency edge. | ||||||||||||
if value != original_settings[key]: | ||||||||||||
# Encoding as JSON makes it possible to embed settings of arbitrary | ||||||||||||
# types (currently bool, string and string_list) into a single type | ||||||||||||
# of setting (string) with the information preserved whether the | ||||||||||||
# original setting wasn't set explicitly (empty string) or was set | ||||||||||||
# explicitly to its default (always a non-empty string with JSON | ||||||||||||
# encoding, e.g. "\"\"" or "[]"). | ||||||||||||
settings[original_key] = json.encode(original_settings[key]) | ||||||||||||
else: | ||||||||||||
settings[original_key] = "" | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you set this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That doesn't work: Since the setting have type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you tried
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried it, it does indeed return an error with Bazel 4.2.1. |
||||||||||||
|
||||||||||||
return settings | ||||||||||||
|
||||||||||||
def _request_nogo_transition(settings, attr): | ||||||||||||
|
@@ -203,25 +247,13 @@ go_transition = transition( | |||||||||||
"//command_line_option:cpu", | ||||||||||||
"//command_line_option:crosstool_top", | ||||||||||||
"//command_line_option:platforms", | ||||||||||||
"@io_bazel_rules_go//go/config:static", | ||||||||||||
"@io_bazel_rules_go//go/config:msan", | ||||||||||||
"@io_bazel_rules_go//go/config:race", | ||||||||||||
"@io_bazel_rules_go//go/config:pure", | ||||||||||||
"@io_bazel_rules_go//go/config:tags", | ||||||||||||
"@io_bazel_rules_go//go/config:linkmode", | ||||||||||||
]], | ||||||||||||
] + TRANSITIONED_GO_SETTING_KEYS], | ||||||||||||
outputs = [filter_transition_label(label) for label in [ | ||||||||||||
"//command_line_option:platforms", | ||||||||||||
"@io_bazel_rules_go//go/config:static", | ||||||||||||
"@io_bazel_rules_go//go/config:msan", | ||||||||||||
"@io_bazel_rules_go//go/config:race", | ||||||||||||
"@io_bazel_rules_go//go/config:pure", | ||||||||||||
"@io_bazel_rules_go//go/config:tags", | ||||||||||||
"@io_bazel_rules_go//go/config:linkmode", | ||||||||||||
]], | ||||||||||||
] + TRANSITIONED_GO_SETTING_KEYS + _ORIGINAL_SETTING_KEYS], | ||||||||||||
) | ||||||||||||
|
||||||||||||
_common_reset_transition_dict = { | ||||||||||||
_common_reset_transition_dict = dict({ | ||||||||||||
"@io_bazel_rules_go//go/config:static": False, | ||||||||||||
"@io_bazel_rules_go//go/config:msan": False, | ||||||||||||
"@io_bazel_rules_go//go/config:race": False, | ||||||||||||
|
@@ -230,7 +262,7 @@ _common_reset_transition_dict = { | |||||||||||
"@io_bazel_rules_go//go/config:debug": False, | ||||||||||||
"@io_bazel_rules_go//go/config:linkmode": LINKMODE_NORMAL, | ||||||||||||
"@io_bazel_rules_go//go/config:tags": [], | ||||||||||||
} | ||||||||||||
}, **{setting: "" for setting in _ORIGINAL_SETTING_KEYS}) | ||||||||||||
|
||||||||||||
_reset_transition_dict = dict(_common_reset_transition_dict, **{ | ||||||||||||
"@io_bazel_rules_go//go/private:bootstrap_nogo": True, | ||||||||||||
|
@@ -366,6 +398,39 @@ go_transition. | |||||||||||
""", | ||||||||||||
) | ||||||||||||
|
||||||||||||
def _non_go_transition_impl(settings, attr): | ||||||||||||
"""Sets all Go settings to the values they had before the last go_transition. | ||||||||||||
|
||||||||||||
non_go_transition sets all of the //go/config settings to the value they had | ||||||||||||
before the last go_transition. This should be used on all attributes of | ||||||||||||
go_library/go_binary/go_test that are built in the target configuration and | ||||||||||||
do not constitute advertise any Go providers. | ||||||||||||
|
||||||||||||
Examples: This transition is applied to the 'data' attribute of go_binary so | ||||||||||||
that other Go binaries used at runtime aren't affected by a non-standard | ||||||||||||
link mode set on the go_binary target, but still use the same top-level | ||||||||||||
settings such as e.g. race instrumentation. | ||||||||||||
""" | ||||||||||||
new_settings = {} | ||||||||||||
for key in TRANSITIONED_GO_SETTING_KEYS: | ||||||||||||
original_key = _original_setting_key(key) | ||||||||||||
original_value = settings[original_key] | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
So you can skip There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could implement that change, but could you explain why you think it's needed? If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, adding a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added a commit that pushed the conversion into the construction of a dict that contains the mapping and added a fail in the conversion function. What do you think? |
||||||||||||
if original_value: | ||||||||||||
# Reset to the original value and clear it. | ||||||||||||
new_settings[key] = json.decode(original_value) | ||||||||||||
new_settings[original_key] = "" | ||||||||||||
fmeum marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
else: | ||||||||||||
new_settings[key] = settings[key] | ||||||||||||
new_settings[original_key] = settings[original_key] | ||||||||||||
fmeum marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
return new_settings | ||||||||||||
|
||||||||||||
non_go_transition = transition( | ||||||||||||
implementation = _non_go_transition_impl, | ||||||||||||
inputs = TRANSITIONED_GO_SETTING_KEYS + _ORIGINAL_SETTING_KEYS, | ||||||||||||
outputs = TRANSITIONED_GO_SETTING_KEYS + _ORIGINAL_SETTING_KEYS, | ||||||||||||
fmeum marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
) | ||||||||||||
|
||||||||||||
def _check_ternary(name, value): | ||||||||||||
if value not in ("on", "off", "auto"): | ||||||||||||
fail('{}: must be "on", "off", or "auto"'.format(name)) | ||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems
filter_transition_label
does nothing to a string like this, right? In addition, bazelbuild/bazel#10499 is already fixed. Do we still needfilter_transition_label
at all?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It converts
@io_bazel_rules_go//go/config:race
to//go/config:race
whenio_bazel_rules_go
is the main repo and returns it unchanged otherwise. It may not be necessary here since the "original_" settings are never reference on the command-line, but using it for some settings and not others seemed even more confusing to me - it would also affect the way transition inputs/outputs are declared below.The bug is fixed, but the full fix is only available in Bazel 5+. Once the minimum version has been updated to 5.0.0,
filter_transition_label
can be dropped.