bazelbuild / bazel

a fast, scalable, multi-language and extensible build system
https://bazel.build
Apache License 2.0
22.56k stars 3.95k forks source link

`alias` rule run bash completion #22347

Open josephrubin opened 2 weeks ago

josephrubin commented 2 weeks ago

Description of the bug:

Alias rule targets aren't available in bash completion for bazel run, only for bazel build.

[BASH] For example, with the setup below, typing bazel build //tool: <TAB> provides autocomplete for bazel build //tool:venv, but typing bazel run //tool: <TAB> does not.

Which category does this issue belong to?

Core

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

In //tool/BUILD.bazel:

alias(
    name = "venv",
    actual = "//tool/development:create_venv",
)

In //tool/development/BUILD.bazel:

sh_binary(
    name = "create_venv",
    srcs = ["create-python-venv.sh"],
    visibility = [
        "//tool:__pkg__",
    ],
)

Which operating system are you running Bazel on?

Ubuntu

What is the output of bazel info release?

release 7.1.1

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?

N/A

Is this a regression? If yes, please try to identify the Bazel commit where the bug was introduced.

No response

Have you found anything relevant by searching the web?

No

Any other information, logs, or outputs that you want to share?

No response

haxorz commented 2 weeks ago

Initial impression: For this to be technically possible, BAZEL_COMPLETION_USE_QUERY needs to be set. And then we'd need to augment the Bash completion script to use a more complicated query expression.

josephrubin commented 1 week ago

I see. So basically we would need to know when doing the completion if the alias'ed thing is executable, so by default we assume that it isn't?

If this is the case, might it be more useful to assume that it is, so that completion happens?

haxorz commented 1 week ago

So basically we would need to know when doing the completion if the alias'ed thing is executable, so by default we assume that it isn't?

Essentially.

The completion script is not fancy. When you type bazel run //foo:<tab> the script looks at the raw contents of foo/BUILD (or foo/BUILD.bazel) (i.e. it's not actually executing BUILD/bzl code code [^1]) and looks for a line like foo_binary(name = 'bar'). Similarly for bazel test //foo:<tab> it looks for a line like foo_test(name = 'bar'). So in other words it's trying to be helpful but is using a very simple heuristic.

[^1]: Unless BAZEL_COMPLETION_USE_QUERY is set. In that case the script uses bazel query under the hood.

If this is the case, might it be more useful to assume that it is, so that completion happens?

Sounds like you want to disable that simple heuristic. We could but then I think we'd get GH issues in the opposite direction: "Why is Bazel's bash completion suggesting things that don't work?".

I'd be open to the script conditionally doing what you want, controlled by an environment variable (default being the current behavior).

josephrubin commented 1 week ago

Understood, thank you.

My reasoning for assuming aliases are executable by default is simply to err on the side of listing targets (when you actually try to run it, Bazel will complain), but I understand that this is not always desired.

If it helps, my envisioned use case is a //tool/BUILD.bazel file which contains aliases to tool binary rule targets that can be placed anywhere in the repo, in order to shorten path names to make it as easy as possible to run tools.

fmeum commented 1 week ago

If it helps, my envisioned use case is a //tool/BUILD.bazel file which contains aliases to tool binary rule targets that can be placed anywhere in the repo, in order to shorten path names to make it as easy as possible to run tools.

In case it's useful for you: I'm working on a small ruleset that gives you a Bazel-managed PATH entry to launch tools from.