Reputation: 1816
According to https://docs.bazel.build/versions/master/query-how-to.html#What_build_rule_contains_file_ja,
fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
will tell me which target bar.java
belongs to.
How can I get the set of targets that multiple files belong to? I.e. map set(files) -> set(targets). I could do this in serial, but each bazel call is fairly expensive and slow---I want to get it done in one call.
Context: I'd like to do this (build targets pertaining to a few files):
git diff HEAD~ | xargs bazel query "get targets for set(files)" | xargs bazel build
I feel like this capability must already exist, but I haven't been able to find it.
Upvotes: 1
Views: 617
Reputation: 5006
Using query
will work, but you can also use aquery
for a more direct approach.
https://docs.bazel.build/versions/master/aquery.html
BUILD
:
genrule(
name = "gen1",
srcs = ["a"],
outs = ["gen1.out"],
cmd = "echo foo > $@",
)
pkg/BUILD
:
genrule(
name = "gen2",
srcs = ["b"],
outs = ["gen2.out"],
cmd = "echo foo > $@",
)
$ bazel aquery "inputs('a|pkg/b', ...)" --include_artifacts=false --include_commandline=false
INFO: Analyzed 2 targets (6 packages loaded, 10 targets configured).
INFO: Found 2 targets...
action 'Executing genrule //pkg:gen2'
Mnemonic: Genrule
Target: //pkg:gen2
Configuration: k8-fastbuild
ActionKey: 8d7d05620bfd8303aa66488e0cd6586d8e978197126cdb41c5fc8c49c81988ef
action 'Executing genrule //:gen1'
Mnemonic: Genrule
Target: //:gen1
Configuration: k8-fastbuild
ActionKey: d4c76a6b6913ce5d887829dbc00d101c1cf5b0ff5240ed13ea328c26e4b41960
INFO: Elapsed time: 0.198s
INFO: 0 processes.
INFO: Build completed successfully, 0 total actions
inputs
(like attr
) accepts a regular expression, so you can "or" the files together with |
. Then just filter for Target:
, or use one of the other outputs (--output=(proto|textproto|jsonproto)
)
This has the advantages that:
attr
in query operates on labels).aquery
queries after the analysis phase, so your results are more accurate because it accounts for configuration (flags, etc).On the other hand, since aquery
runs loading + analysis, it might take longer than query
, since query
just runs the loading phase.
Upvotes: 2