-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
bazelrc: Allow "common" lines to always accept any legal Bazel options #3054
Comments
SGTM. @lfpino : What do you think? Any reasons against the suggested behavior? Any difficulties you anticipate? |
Unfortunately, with the current OptionsParser, knowing which flags exist for other commands is not possible and it would be a very invasive change. Here's an alternative: --invocation_policy is a feature that allows users to control what flags get passed (for some definitions of control) and does allow setting non-existent flags (it just ignores them.) If you have the following policy,
it will apply to all commands where the flag is defined unless the user specified their own --package_path |
Was just about to create an issue for this. +1 we want this too. |
This would be a very nice feature. |
+1 |
Currently there are 16 commands. Whenever you add an option to bazelrc, you must figure which of those 16 commands it applies to. |
Here is an extreme case which I think illustrates why the requested change is worthwhile. I always want to set a disk cache location, regardless of what command is invoked.
With this setting, (The workaround was to do as @pauldraper said, which involves a fair amount of scrolling around the command line reference documentation.) |
My current workaround to save scrolling is this script: bazel-option-commands
Example: bazel-option-commands workspace_status_command aquery
build
canonicalize-flags
clean
coverage
cquery
info
mobile-install
print_action
run
test Maybe someone will create a utility to add these automatically. |
This is a huge pain. |
My Bash isn't great but here is a version of @pauldraper 's script that handles inheritance of options between commands.
#!/usr/bin/env bash
set -e -u -o pipefail
# Commands that don't inherit any options
base_commands=(
analyze-profile
build
dump
fetch
help
license
query
shutdown
sync
version
)
# Commands that inherit options from build
build_commands=(
aquery
canonicalize-flags
clean
info
mobile-install
print_action
run
"test"
# It is not documented that config inherits from build but it does
config
)
# Commands that inherit options from test
test_commands=(
coverage
cquery
)
option="$1"
all_commands_match=true
function command_has_option {
local help_content
if ! help_content="$(bazel help --short "$1")"; then
exit $?
fi
grep -qE "^ --(\\[no\\])?$option\$" <<<"$help_content"
}
function test_command {
if command_has_option "$1"; then
echo "$1"
else
all_commands_match=false
fi
}
for command in "${base_commands[@]}"; do
test_command "$command"
done
if ! command_has_option build; then
for command in "${build_commands[@]}"; do
test_command "$command"
done
fi
if ! command_has_option test; then
for command in "${test_commands[@]}"; do
test_command "$command"
done
fi
if [ "$all_commands_match" = true ]; then
echo "(all commands match, you can put this in \"common\" in .bazelrc)"
fi
|
I brought up this issue with several groups at BazelCon this year, including the first community day unconference session and the rules authors SIG meeting. There was wide consensus that accidental external repository invalidations and analysis cache discards is a high-priority usability issue. Recent posts on this thread highlight the infeasibility of existing workarounds. @katre agreed that it's reasonable to solve this as @mmorearty proposed in the OP: ignore flags that aren't available on the given command. I believe that is non-breaking for users, since the only behavior change is for bazel invocation that would fail under existing versions of bazel. However he feels that there may be some design discussion required. @gregestren is likely the other expert on this who could help to propose or evaluate designs that can fix it. |
What's the plan for implementing this? |
My understanding is @mmorearty isn't working in Bazel related stuff now. Bazel knows the complete list of flags, e.g. from running |
True. I was worried about a slight performance penalty for doing that in a naive manner, due to how internally Bazel uses lots of reflection to express command options. After running some benchmarks and not seeing that reflection usage show up in a profiler, I realized I had forgotten we already cache the results which is great because that's the approach I would have recommended we take for this FR :) Anyway, I took a skim at the relevant code and I think this FR will be feasible to implement. |
Just as FYI: I should link to @illicitonion work on using |
tl;dr - The current approach lets users convey their intent, albeit in an annoying manner. The proposed approach is ambiguous here.
This is true, and is a good point. I'm concerned about the opposite direction though. Pretend [Bear with me for a moment] We actually had something similar to my above example internally at Google a few quarters ago. Our company-wide Therefore I'm inclined to introduce a new way to specify options in
The above is just my personal inclination. I'll leave it to the assignee of this FR (and their code reviewer) to come to their own opinions. On that note, we'd be open to a community contribution for this FR. Otherwise |
Over at #18130, I am implementing a new pseudo command that is inherited by all commands, but with unsupported options ignored instead of failing with an error. This command is currently called |
The debate about the right naming of the pseudo-commands has led me to think more about @haxorz example in which the distinction between
It would be interesting to learn why
It definitely would, but having such an option on some but not all commands would seem more like an inconsistency (or even bug?) in Bazel than something users should need to be aware of. The situation is of course different for google3 and especially for Bazel developers, but if the average user then finds that While I agree that it should remain possible to express this intent explicitly, does it really need to be the default way? Having it not be the default way would perhaps even make this expression of intent even more explicit. All in all, I think I now lean towards the following approach:
This allows users to benefit from the new Edit: We could hide the new behavior behind an experimental flag for Bazel 6.3.0 so that everyone gets a chance to try it out and report issues. Then we could flip it on for Bazel 7. |
@fmeum Thank you very much for carefully thinking through this issue!
It's a pretty messy story. (Googlers, start reading from comment # 3 in buganizer entry # 131156929.) Originally Support for changing values of was added in 5ef93ef but then we never went back to I acknowledge this is a messy and silly story. I also acknowledge my point in my Jan 11 comment was hypothetical ("...Now imagine it weren't a common command option..."), so therefore I acknowledge my point is not very compelling.
No, it doesn't. It is the way it is for historical purposes. If we were starting from scratch I don't think we'd end up where we are now.
Good point.
I'm fine with this risk as long as the RELNOTES and docs are good.
I vote for
Quis custodiet ipsos custodes: "Who configures the command line configuration parser?" :P Seems sketchy to have flag parsing code's behavior be controlled by a flag. What's your plan there? Have the options parser code first do a pass looking for a special sentinel option? Seems pretty messy to properly support that in Unless I'm missing something obvious, an environment variable might be the way to go here. If you do this, please have |
@justinhorvitz Tagging you since you're not on this issue thread but you are on the PR thread. |
I think it's fine to make I don't see any immediate need for replacing the current semantics of |
As it turns out, importing #18130 is going to require changing some RC lines from |
Could you share an example of such a case? This would be helpful in determining the possible impact of this change to Bazel users. |
Yes - some details still to be ironed out, but here's a summary. We have some tools that use an rc parsing library which uses only a small subset of the options classes used in blaze. To be explicit, it uses only:
With your change, it is valid to specify an option from some other options class with |
@fmeum, fwiw this is the thing I alluded to in my comment last week (ctrl+f "This is because"). Sorry for not foreseeing this complication! |
Thanks @fmeum for tackling this one! Also thank you to the rules authors SIG funders who paid for this work under https://opencollective.com/bazel-rules-authors-sig |
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
Fixes bazelbuild#3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes bazelbuild#18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968
) (#18609) * Change --memory_profile_stable_heap_parameters to accept more than one GC specification Currently memory_profile_stable_heap_parameters expects 2 ints and runs that many GCs with pauses between them 2nd param. This CL doesn't change that, but allows any arbitrary number of pairs to be provided that will run the same logic for each pair. This allows experimenting with forcing longer pauses on that thread before doing the quick GCs that allow for cleaner memory measurement. PiperOrigin-RevId: 485646588 Change-Id: Iff4f17cdaae409854f99397b4271bb5f87c4c404 * Let `common` ignore unsupported options Fixes #3054 RELNOTES: Options specified on the pseudo-command `common` in `.rc` files are now ignored by commands that do not support them as long as they are valid options for *any* Bazel command. Previously, commands that did not support all options given for `common` would fail to run. These previous semantics of `common` are now available via the new `always` pseudo-command. Closes #18130. PiperOrigin-RevId: 534940403 Change-Id: I2ae268ae84de3f2b07ff3d1e36bf382bce714968 --------- Co-authored-by: Googler <kkress@google.com> Co-authored-by: Fabian Meumertzheim <fabian@meumertzhe.im>
Description of the problem / feature request / question:
Currently, if a bazelrc file contains a
common
line, then all of the specified options are passed to every bazel command that is run. I propose that thecommon
line always allow all legal options that can apply to any command, but silently ignore the ones that don't apply to the current command.The current behavior can easily lead to unnecessary error messages, and greatly hampers the usefulness of the
common
feature.For one thing, there are very few Bazel options that are actually common across every command.
Also, although bazelrc supports inheritance (e.g.
test
andrun
will automatically inherit from anybuild
lines), that inheritance isn't always enough. For example, suppose I want to have a custom--package_path
for every Bazel command that supports that flag. It's not sufficient to writebecause that will apply to
build
,test
, andrun
, but not tofetch
,info
, andquery
, which do not inherit frombuild
but do support the--package_path
option.I could write
But that is (a) messy, (b) requires me to do a lot of research to carefully figure out which commands support
--package_path
, and (c) could break in the future if I upgrade to a newer version of Bazel that supports--package_path
for additional commands.What I really want is to write
but I can't, because that breaks any command that doesn't support that flag, such as
bazel help
.I think probably the best way to address this is what I proposed above: The
common
line always allows all legal options that can apply to any command, but silently ignores the ones that don't apply to the current command.So
common --package_path ...
would never cause an error, butcommon --invalid_flag
would cause an error.Environment info
OS X
bazel info release
):0.4.5
The text was updated successfully, but these errors were encountered: