-
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
bazel query "deps(//:target)"
returns //:target
#17777
Comments
https://bazel.build/query/language#deps says "For example, the value of deps(//foo) is the dependency graph rooted at the single node foo, including all its dependencies." |
Ah sorry, I managed to miss that (was looking under the Is there any particular reason for including the input targets? I gave a concrete example above for why this can be difficult to work with. What is the benefit to including the input target as well? Is there historical reasoning for this? |
We can't change the behavior of the |
A type of query I have personally been interested in is "all targets matching a given pattern that aren't dependencies of targets matching that pattern", i.e., getting the root nodes of the build graph. It's something that would be very easy to build if |
I also have run into this issue in the past. The task I was trying to accomplish was get a list of targets of a class that improperly depend (directly, but particularly transitively) on other members of that class. It doesn't use deps, but it does touch on the fundamental issue here—disconnected nodes in the graph are returned unexpectedly in the query. Here's an example that reduces the issue: Given a subgraph with nodes A, B, C, D, E, but only one edge among them, say B → D; when performing the query: The only thing I could think of as a workaround was to perform n+1 queries, one to get the list of items in the class, and then one for each target in the class, using |
Hey @tjgq! Agreed that this would be a very nuanced breaking change and might be infeasible for that reason. As for one concrete scenario, I can point at dgp1130/rules_prerender#40 (comment), where I was hoping to create a genquery test to identify bad dependency edges, but which is fundamentally impossible because of this "feature" of Ultimately I suspect there are a number of users who simply don't know about this behavior and may even be encountering the bug without realizing it. I know I've done |
I don't think it is feasible to change the semantics here, since it will likely break many people who rely on this functionality. Not to mention, the behavior of including the input targets is similar across other query functions (e.g. W.r.t historical reasons, I don't have any concrete reason as to why this was the case to begin with. Closing this, but feel free to re-open if you would like to continue the discussion. |
Description of the bug:
I'm not sure if this is intended behavior or not, but I personally find it quite annoying and couldn't find any issue or documentation stating that this was intended.
If you run a
bazel query
and usedeps()
orrdeps()
on some inputs, you will always get the inputs in the result (plus the actual dependencies / reverse dependencies). I don't think this makes logical sense as a target does not have a "dependency" on itself (that would be a self-edge and generally banned).The common workaround for this is to
except
the inputs like so:However, this can lose information when querying the dependencies of multiple inputs. Consider the example:
Here,
//:foo
has a dependency on//:bar
. Thereforedeps(//:foo) except //:foo
returns//:bar
and//:baz
, working as expected. However, this model falls apart with multiple inputs such as:IMHO, the "correct" output here is
//:bar
and//:baz
. At least one input (//:foo
) depends on//:bar
and is not//:bar
itself, therefore//:bar
should be included in the output.//:baz
is depended upon by both. Currently it actually outputs//:foo
,//:bar
, and//:baz
. That means we need to manually exclude the inputs, so let's try:However this only returns
//:baz
and drops//:bar
. Dependency information between targets in the input set is lost because this query assumes they do not depend on each other. As a result,deps()
andrdeps()
are returning incorrect results, and the obvious workaround ofexcept
doesn't actually work around the problem.What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Should return:
But actually returns:
Which operating system are you running Bazel on?
WSL2 on Windows
What is the output of
bazel info release
?release 6.0.0
If
bazel info release
returnsdevelopment 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 master; git rev-parse HEAD
?No response
Have you found anything relevant by searching the web?
I was not able to find any existing issue or documentation which explicitly mentioned this "self-edge" in
deps()
andrdeps()
.Any other information, logs, or outputs that you want to share?
No response
The text was updated successfully, but these errors were encountered: