Skip to content
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

Proposal: use bazel's cquery in place of query for queryForSourceFiles checks #305

Closed
josephperrott opened this issue Dec 3, 2019 · 8 comments · Fixed by #374
Closed

Comments

@josephperrott
Copy link
Collaborator

Currently ibazel uses bazel query to determine if the build graph has changed. However bazel query does not allow for configurations to be considered.

If you set a --define flag for your builds, every time ibazel runs bazel query, the analysis cache is invalidated in determining the query results only to have the results invalidated again by the next build.

If bazel cquery is used instead, the --define flag is now considered/valid and the correct graph is created.

cquery inherits all of its flags from build (as does run and test) which leads to all supported flags in ibazel being able to be forwarded to the "query" checks


Under the hood the commands that are called by ibazel in this instance look something like this:

Calls: bazel build //path/to/module:target
      ^ creates analysis cache using `--define` flag configuration

Change made to a file

Calls: bazel query //path/to/module:target
      ^ creates new analysis cache without `--define` flag, throwing out old cache
Calls: bazel build //path/to/module:target
      ^ creates new analysis cache using `--define` flag, throwing out old cache

with cquery it would instead be:

Calls: bazel build //path/to/module:target
      ^ creates analysis cache using `--define` flag configuration

Change made to a file

Calls: bazel cquery //path/to/module:target
      ^ uses analysis cache already created, updating as necessary
Calls: bazel build //path/to/module:target
      ^ uses analysis cache already created
@achew22
Copy link
Member

achew22 commented Dec 17, 2019

@josephperrott, I think this would be a really really great feature to add. I've been doing some repo cleanup with the goal of engaging you on this issue. How could I help get you engaged?

All the code for controlling the query operation lives inside a small block inside the bazel lib.

// Executes a query language expression over a specified subgraph of the
// build dependency graph.
//
// For example, to show all C++ test rules in the strings package, use:
//
// res, err := b.Query('kind("cc_.*test", strings:*)')
//
// or to find all dependencies of //path/to/package:target, use:
//
// res, err := b.Query('deps(//path/to/package:target)')
//
// or to find a dependency path between //path/to/package:target and //dependency:
//
// res, err := b.Query('somepath(//path/to/package:target, //dependency)')
func (b *bazel) Query(args ...string) (*blaze_query.QueryResult, error) {
blazeArgs := append([]string(nil), "--output=proto", "--order_output=no", "--color=no")
blazeArgs = append(blazeArgs, args...)
b.WriteToStderr(true)
b.WriteToStdout(false)
stdoutBuffer, _ := b.newCommand("query", blazeArgs...)
err := b.cmd.Run()
if err != nil {
return nil, err
}
return b.processQuery(stdoutBuffer.Bytes())
}

It doesn't look to me like it would be that hard to add a new method cquery and then change all the callers over. Is this a thing I could interest you in?

I'm about to do a release that will add colors (YAY!) and fix a lot of the output formatting issues (YAY!) but would love to do a v0.11.1 as early as this afternoon if you're interested.

@github-actions
Copy link

Stale issue message

@IgorMinar
Copy link
Contributor

IgorMinar commented Feb 18, 2020 via email

@github-actions
Copy link

Stale issue message

@IgorMinar
Copy link
Contributor

not stale

achew22 added a commit that referenced this issue Apr 22, 2020
@devversion
Copy link
Contributor

devversion commented May 8, 2020

@achew22 Thanks for working on this. I think unfortunately it's not improving things as there is still a bazel query call for determining the build files. This causes the analysis cache to be still discarded.

The goal would be that the analysis cache is not discarded. We could achieve this by using cquery for determining the build files, or by always using bazel query and allowing define variables.

cquery does not support buildfiles, but maybe we could make that work with upstream changes in bazel? Ideally though, bazel query would just support --define for the sake of not discarding analysis cache, unless I miss something here. This makes me wonder why the analysis cache is even discarded at all if standard bazel query is supposed to just run as part of the loading phase.

@achew22
Copy link
Member

achew22 commented May 8, 2020

@devversion this sounds like a great issue to open upstream on the Bazel main repo. Unfortunately I don't have enough time to spin up on that particular issue, but I would be interested in seeing what they say. It could be something as simple as changing a Boolean value somewhere. That's something I would be happy to do.

@juliexxia
Copy link

Hey y'all, bazel engineer here. @devversion is right, query just runs the loading phase which is why it doesn't respect any build flags (like --define). That also means it shouldn't be invalidating the analysis cache because it doesn't run the analysis phase.

Out of curiosity, you're running two query commands one after another and you're seeing symptoms that looks like analysis cache invalidation? What are those symptoms?

As for bazel changes, adding --define respect to query isn't an option. cquery was created to be a query that respects build flags. But adding buildfiles() support to cquery seems possible to me. If I remember correctly, there wasn't any major technical reason this didn't happen, we just figured we'd implement when a need arose:
https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java;l=480

Here's the implementation in query:
https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/query2/query/BlazeQueryEnvironment.java;l=410

Bazel team probably doesn't have the cycles to own this but If you wanted to investigate/make this change in the bazel repo I'd be happy to shepherd your PRs through.

leoluk pushed a commit to monogon-dev/monogon that referenced this issue Jul 5, 2021
This is a Windows-specific package being pulled in by github.com/spf13/cobra.

We don't need it, and we don't ever build it (it's behind a select()
gate depending on the Windows platform), but its lack causes us to not
be able to perform Bazel queries against anything that stumbles upon
this select statement.

Notably, things like ibazel don't work without the ability to query
dependencies of a target. In theory, cquery could be used of query (and
cquery would know that it's not running on a windows platform and not
attempt to resolve the missing package). This might happen some day,
but:

  1) cquery currently does not support the buildfiles() function, which
     is needed by tools like ibazel to find not only source/data/target
     dependencies for a taret, but also every BUILD/.bzl file that
     influenced that target.

     See: bazelbuild/bazel-watcher#305 (comment)

  2) It's generally good practice to not have missing objects in our
     dependency graph, I think. We will sooner or later start using this
     data in CI and other automation, and it might be useful to make an
     assumption, at some point, that we don't ever have a broken
     target dependency graph.

Testing plan: the following now works:

   bazel query 'deps(set(//...))' --output=xml

Change-Id: Ic45e293b868b0aaa707f31384b4b24626ba23e29
Reviewed-on: https://review.monogon.dev/c/monogon/+/200
Reviewed-by: Leopold Schabel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants