bazelbuild / bazel

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

Relaxing scope rules for genquery() #22244

Open ahmedyarub opened 6 months ago

ahmedyarub commented 6 months ago

Description of the feature request:

Relax the requirement for scopes in some cases, for instance, if we only care about packages.

Which category does this issue belong to?

Rules API

What underlying problem are you trying to solve with this feature?

Ability to simulate the command: bazel query "//...:all" --output package I did test that locally in my machine (removing all the scope checks) and it worked without any problem.

genquery(
    name = "genquery",
    expression = "//services/...:all",
    opts = [
        "--output=package",
    ],
    scope = ["all"],
    strict = False,
)

Which operating system are you running Bazel on?

Microsoft Windows [Version 10.0.26200.5001]

What is the output of bazel info 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 ?

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

comius commented 5 months ago

Core team is more familiar with genquery and query functionality.

haxorz commented 5 months ago

Can you please clarify:

(removing all the scope checks) and it worked without any problem.

This is going to be unsound in general. What's the plan for supporting

# p1/BUILD
genquery(
    name = "genquery",
    expression = "//p2/...",
    scope = <fill me in>,
)
$ bazel build //p1:genquery

?

ahmedyarub commented 5 months ago

Can you please clarify:

  • What you mean by "if we only care about scopes"?
  • What you mean by scope = ["all"]?

(removing all the scope checks) and it worked without any problem.

This is going to be unsound in general. What's the plan for supporting

# p1/BUILD
genquery(
    name = "genquery",
    expression = "//p2/...",
    scope = <fill me in>,
)
$ bazel build //p1:genquery

?

Sorry that was a typo. I meant packages.

haxorz commented 5 months ago

Okay.

Not sure what your motivation is, but just in case https://bazel.build/reference/be/functions#subpackages is sufficient, did you consider using that instead of genquery?

ahmedyarub commented 5 months ago

Okay.

Not sure what your motivation is, but just in case https://bazel.build/reference/be/functions#subpackages is sufficient, did you consider using that instead of genquery?

I would like to create a .projectview file that contains all the packages of a workspace. That function does seem to be promising but how can I use it to list all the packages in the workspace?

haxorz commented 5 months ago

That function does seem to be promising but how can I use it to list all the packages in the workspace?

[Annoying I know, ] You'd have to instill the convention that all the packages in your workspace use subpackages to [recursively] enumerate packages beneath them. Then you could aggregate all this information at the root package.

I would like to create a .projectview file that contains all the packages of a workspace.

Simplest would be to do this outside of Bazel, but using Bazel e.g. bazel query --output=package //... 2> /dev/null > blah.projectview.

ahmedyarub commented 5 months ago

I would rather use rules because I'm considering adding that functionality to the Bazel plugin for IntelliJ. The real question here is: why can the query command do it but not the rules?

haxorz commented 5 months ago

The query command is given the additional information of the query expression (in your case //...), so it knows what it needs to do.

The build command is given the set of top-level targets (bazel build //p:t), and then recursively visits their transitive closure. For each target visited, Bazel does the rule logic after visiting its children. For a genquery target, the children are the targets specified by the scope attribute value and the "rule logic" is "evaluate the query expression in expression. This is why genquery.scope needs to be a list of labels, and why the query evaluation is bounded within the transitive closure of those targets: Recursively visiting those targets first means their transitive closures have already been visited by the time we want to evaluate the query expression.

These restrictions of genquery allow it to fit naturally in Bazel's computational model and incrementality model.