axbuild 0.4.14

An OS build lib toolkit used by arceos
Documentation
use std::collections::BTreeSet;

use anyhow::Context;
use cargo_metadata::Metadata;

use super::{
    AXSTD_STD_DEFAULT_FEATURE, AXSTD_STD_PACKAGE, DEFAULT_FEATURE,
    check::{ClippyCheck, ClippyCheckKind},
    env::{clippy_axconfig_override, clippy_env, feature_axconfig_overrides, feature_clippy_env},
    selection::SelectedClippyPackage,
    targets::{docs_rs_targets, feature_supported_on_clippy_target},
};

pub(super) fn expand_clippy_checks(
    packages: &[SelectedClippyPackage],
    metadata: &Metadata,
) -> anyhow::Result<Vec<ClippyCheck>> {
    let mut checks = Vec::new();
    let workspace_root = metadata.workspace_root.clone().into_std_path_buf();

    for selected in packages {
        let package = &selected.package;
        let mut features: BTreeSet<_> = package
            .features
            .keys()
            .filter(|feature| feature.as_str() != DEFAULT_FEATURE)
            .cloned()
            .collect();
        if package.name == AXSTD_STD_PACKAGE {
            features.insert(AXSTD_STD_DEFAULT_FEATURE.to_string());
        }
        let targets = docs_rs_targets(package);
        let target_iter = if targets.is_empty() {
            vec![None]
        } else {
            targets.into_iter().map(Some).collect()
        };
        let env = clippy_env(package);
        let axconfig_overrides = feature_axconfig_overrides(package);

        for target in target_iter {
            checks.push(ClippyCheck {
                package: package.name.to_string(),
                kind: ClippyCheckKind::Base,
                deps_mode: selected.deps_mode.clone(),
                target: target.clone(),
                env: env.clone(),
                axconfig_override: None,
            });

            for feature in &features {
                if !feature_supported_on_clippy_target(package, feature, target.as_deref()) {
                    continue;
                }
                let axconfig_override = axconfig_overrides.get(feature).and_then(|overrides| {
                    clippy_axconfig_override(
                        package,
                        target.as_deref(),
                        feature,
                        overrides,
                        &workspace_root,
                    )
                });
                let feature_env = feature_clippy_env(
                    package,
                    feature,
                    env.clone(),
                    axconfig_override.as_ref(),
                    metadata,
                )
                .with_context(|| {
                    format!(
                        "failed to prepare clippy env for `{}` feature `{feature}`",
                        package.name
                    )
                })?;
                checks.push(ClippyCheck {
                    package: package.name.to_string(),
                    kind: ClippyCheckKind::Feature(feature.clone()),
                    deps_mode: selected.deps_mode.clone(),
                    target: target.clone(),
                    env: feature_env,
                    axconfig_override,
                });
            }
        }
    }

    Ok(checks)
}