in focus/internals/src/lib/target_resolver/incremental_bazel_resolver.rs [89:188]
fn query_package_dependencies(
&self,
app: Arc<App>,
request: &ResolutionRequest,
labels: HashSet<&Label>,
) -> anyhow::Result<(BTreeSet<PathBuf>, BTreeMap<DependencyKey, DependencyValue>)> {
let dep_labels = {
let query = format!(
// Use `deps(...)` so that we preserve the actual names of the
// targets which were declared as dependencies, but also add in
// any `buildfiles` dependencies that might exist in the
// repository. This includes dependencies on `BUILD` or `.bzl`
// files (such as those `load`ed by the other `BUILD` files).
//
// We limit buildfile dependencies to only those in the
// repository, because `.bzl` files, etc., in external
// repositories are typically not supported, so querying them
// fails.
"deps({0}) union kind(rule, filter('^//', buildfiles(deps({0}))))",
bazel_common::make_set(labels.iter().copied())
);
let result =
Self::run_bazel_query(app.clone(), request, &["--noimplicit_deps"], &query)?;
// Initialize `labels` to the set of labels that we were given.
// It's possible that those labels will not appear in the
// `buildfiles(deps(...))` output if the only dependencies for those
// labels are in external repositories, so we need to make sure to
// include them explicitly.
let mut dep_labels: BTreeSet<Label> = labels.iter().copied().cloned().collect();
for line in result.lines() {
dep_labels.insert(Label::from_str(line)?);
}
info!("'{}' requires {} packages", &query, dep_labels.len());
dep_labels
};
let immediate_deps = self.extract_immediate_dependencies(app, request, dep_labels)?;
let recursive_package_queries: BTreeSet<&Label> = labels
.into_iter()
.filter(|label| label.target_name == TargetName::Ellipsis)
.collect();
let recursive_package_query_deps =
self.add_recursive_package_query_deps(recursive_package_queries, &immediate_deps);
let immediate_keys: HashSet<_> = immediate_deps.keys().collect();
let recursive_keys: HashSet<_> = recursive_package_query_deps.keys().collect();
let intersection: HashSet<_> = immediate_keys.intersection(&recursive_keys).collect();
assert!(intersection.is_empty());
let deps: BTreeMap<DependencyKey, DependencyValue> = immediate_deps
.into_iter()
.chain(recursive_package_query_deps.into_iter())
.collect();
let paths = deps
.iter()
.filter_map(|(dep_key, _dep_value)| match dep_key {
DependencyKey::BazelPackage(Label {
external_repository: None,
path_components,
target_name: _,
})
| DependencyKey::BazelBuildFile(Label {
external_repository: None,
path_components,
target_name: _,
}) => {
let path: PathBuf = path_components.iter().collect();
Some(path)
}
DependencyKey::BazelPackage(Label {
external_repository: Some(_),
path_components: _,
target_name: _,
})
| DependencyKey::BazelBuildFile(Label {
external_repository: Some(_),
path_components: _,
target_name: _,
}) => {
// Don't need to materialize external repositories.
None
}
DependencyKey::Path(path) => Some(path.clone()),
key @ DependencyKey::DummyForTesting(_) => {
panic!("Got dummy dependency key: {:?}", key)
}
})
.collect();
Ok((paths, deps))
}