use std::collections::BTreeMap;use std::fs;use std::path::Path;use anyhow::{Context as _, 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()) .is_some_and(|grandparent_dir| grandparent_dir.ends_with("extensions")); let cargo_toml = read_cargo_toml(&package.manifest_path)?; let is_using_workspace_lints = cargo_toml.lints.is_some_and(|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 || package.name == "zed_extension_api" { 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(|| format!("reading Cargo.toml at {path:?}"))}
use std::collections::BTreeMap;
use std::fs;
use std::path::Path;
use anyhow::{Context as _, 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())
.is_some_and(|grandparent_dir| grandparent_dir.ends_with("extensions"));
let cargo_toml = read_cargo_toml(&package.manifest_path)?;
let is_using_workspace_lints = cargo_toml.lints.is_some_and(|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 || package.name == "zed_extension_api" {
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(|| format!("reading Cargo.toml at {path:?}"))
}