77 lines · 2.3 KB · Rust
RawDownload
use std::collections::BTreeMap;use std::fs;use std::path::Path; use anyhow::{anyhow, Context, Result};use cargo_toml::{Dependency, Manifest};use clap::Parser; use crate::workspace::load_workspace; #[derive(Parser)]pub struct PackageConformityArgs {} pub fn run_package_conformity(_args: PackageConformityArgs) -> Result<()> {    let workspace = load_workspace()?;     let mut non_workspace_dependencies = BTreeMap::new();     for package in workspace.workspace_packages() {        let is_extension = package            .manifest_path            .parent()            .and_then(|parent| parent.parent())            .map_or(false, |grandparent_dir| {                grandparent_dir.ends_with("extensions")            });         let cargo_toml = read_cargo_toml(&package.manifest_path)?;         let is_using_workspace_lints = cargo_toml.lints.map_or(false, |lints| lints.workspace);        if !is_using_workspace_lints {            eprintln!(                "{package:?} is not using workspace lints",                package = package.name            );        }         // Extensions should not use workspace dependencies.        if is_extension {            continue;        }         for dependencies in [            &cargo_toml.dependencies,            &cargo_toml.dev_dependencies,            &cargo_toml.build_dependencies,        ] {            for (name, dependency) in dependencies {                if let Dependency::Inherited(_) = dependency {                    continue;                }                 non_workspace_dependencies                    .entry(name.to_owned())                    .or_insert_with(Vec::new)                    .push(package.name.clone());            }        }    }     for (dependency, packages) in non_workspace_dependencies {        eprintln!(            "{dependency} is being used as a non-workspace dependency: {}",            packages.join(", ")        );    }     Ok(())} /// Returns the contents of the `Cargo.toml` file at the given path.fn read_cargo_toml(path: impl AsRef<Path>) -> Result<Manifest> {    let path = path.as_ref();    let cargo_toml_bytes = fs::read(&path)?;    Manifest::from_slice(&cargo_toml_bytes)        .with_context(|| anyhow!("failed to read Cargo.toml at {path:?}"))}