fn query_package_dependencies()

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))
    }