fn check_crate_policies()

in src/main.rs [3052:3131]


fn check_crate_policies(cfg: &Config, store: &Store) -> Result<(), CratePolicyErrors> {
    // All defined policy package names (to be removed).
    let mut policy_crates: SortedSet<&PackageName> = store.config.policy.package.keys().collect();

    // All defined policy (name, version) pairs (to be visited and removed).
    let mut versioned_policy_crates: SortedSet<(PackageName, VetVersion)> = store
        .config
        .policy
        .iter()
        .filter_map(|(name, version, _)| version.map(|version| (name.clone(), version.clone())))
        .collect();

    // The set of all third-party packages (for lookup of whether a crate has any third-party
    // versions in use).
    let third_party_packages = foreign_packages_strict(&cfg.metadata, &store.config)
        .map(|p| &p.name)
        .collect::<SortedSet<_>>();

    // The set of all packages which have a `dependency-criteria` specified in a policy.
    let dependency_criteria_packages = store
        .config
        .policy
        .iter()
        .filter_map(|(name, _, entry)| (!entry.dependency_criteria.is_empty()).then_some(name))
        .collect::<SortedSet<_>>();

    let mut needs_policy_version_errors = Vec::new();

    for package in &cfg.metadata.packages {
        policy_crates.remove(&package.name);

        let versioned_policy_exists =
            versioned_policy_crates.remove(&(package.name.clone(), package.vet_version()));

        // If a crate has at least one third-party package and some crate policy specifies a
        // `dependency-criteria`, a versioned policy for all used versions must exist.
        if third_party_packages.contains(&package.name)
            && dependency_criteria_packages.contains(&package.name)
            && !versioned_policy_exists
        {
            needs_policy_version_errors.push(PackageError {
                package: package.name.clone(),
                version: Some(package.vet_version()),
            });
        }
    }

    let unused_policy_version_errors: Vec<_> = policy_crates
        .into_iter()
        .map(|name| PackageError {
            package: name.clone(),
            version: None,
        })
        .chain(
            versioned_policy_crates
                .into_iter()
                .map(|(package, version)| PackageError {
                    package,
                    version: Some(version),
                }),
        )
        .collect();

    if !needs_policy_version_errors.is_empty() || !unused_policy_version_errors.is_empty() {
        let mut errors = Vec::new();
        if !needs_policy_version_errors.is_empty() {
            errors.push(CratePolicyError::NeedsVersion(NeedsPolicyVersionErrors {
                errors: needs_policy_version_errors,
            }));
        }
        if !unused_policy_version_errors.is_empty() {
            errors.push(CratePolicyError::UnusedVersion(UnusedPolicyVersionErrors {
                errors: unused_policy_version_errors,
            }));
        }
        Err(CratePolicyErrors { errors })
    } else {
        Ok(())
    }
}