Skip to content

Commit

Permalink
feat(ci): enforce workspace lints in crate tomls (#1922)
Browse files Browse the repository at this point in the history
Signed-off-by: Dori Medini <dori@starkware.co>
  • Loading branch information
dorimedini-starkware authored Nov 12, 2024
1 parent 8127efd commit 6b3bd58
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 10 deletions.
3 changes: 3 additions & 0 deletions workspace_tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ toml.workspace = true
[[test]]
name = "workspace_tests"
path = "main.rs"

[lints]
workspace = true
37 changes: 37 additions & 0 deletions workspace_tests/lints_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::collections::HashMap;

use crate::toml_utils::{CrateCargoToml, LintValue, ROOT_TOML};

#[test]
fn test_lints_section_exists() {
let crates_without_lints: Vec<_> = ROOT_TOML
.member_cargo_tomls()
.into_iter()
.filter(|(_, CrateCargoToml { lints, .. })| lints.is_none())
.map(|(crate_name, _)| crate_name)
.collect();
assert!(
crates_without_lints.is_empty(),
"The following crates are missing a [lints] section: {crates_without_lints:#?}."
);
}

#[test]
fn test_lints_from_workspace() {
let expected_lints_entry =
HashMap::<String, LintValue>::from([("workspace".into(), LintValue::Bool(true))]);
let crates_without_workspace_lints: Vec<_> = ROOT_TOML
.member_cargo_tomls()
.into_iter()
.filter(|(_, CrateCargoToml { lints, .. })| match lints {
None => false,
Some(lints) => lints != &expected_lints_entry,
})
.map(|(crate_name, _)| crate_name)
.collect();
assert!(
crates_without_workspace_lints.is_empty(),
"The following crates don't use `workspace = true` in the [lints] section: \
{crates_without_workspace_lints:?}."
);
}
1 change: 1 addition & 0 deletions workspace_tests/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![cfg(test)]

pub mod lints_test;
pub mod toml_utils;
pub mod version_integrity_test;
16 changes: 11 additions & 5 deletions workspace_tests/toml_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ use std::sync::LazyLock;

use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub(crate) enum LintValue {
Bool(bool),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub(crate) enum DependencyValue {
Expand Down Expand Up @@ -34,6 +40,7 @@ pub(crate) struct CrateCargoToml {
dependencies: Option<HashMap<String, DependencyValue>>,
#[serde(rename = "dev-dependencies")]
dev_dependencies: Option<HashMap<String, DependencyValue>>,
pub(crate) lints: Option<HashMap<String, LintValue>>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -73,19 +80,18 @@ impl CargoToml {
})
}

pub(crate) fn member_cargo_tomls(&self) -> Vec<CrateCargoToml> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let crates_dir = format!("{}/../", manifest_dir);
pub(crate) fn member_cargo_tomls(&self) -> HashMap<String, CrateCargoToml> {
let crates_dir = Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/../"));
self.members()
.iter()
.map(|member| {
let cargo_toml_path = Path::new(&crates_dir).join(member).join("Cargo.toml");
let cargo_toml_path = crates_dir.join(member).join("Cargo.toml");

let cargo_toml_content = fs::read_to_string(&cargo_toml_path)
.unwrap_or_else(|_| panic!("Failed to read {:?}", cargo_toml_path));

let cargo_toml: CrateCargoToml = toml::from_str(&cargo_toml_content).unwrap();
cargo_toml
(member.clone(), cargo_toml)
})
.collect()
}
Expand Down
8 changes: 3 additions & 5 deletions workspace_tests/version_integrity_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ fn test_version_alignment() {

#[test]
fn validate_no_path_dependencies() {
let mut all_path_deps_in_crate_tomls: Vec<String> = Vec::new();
for crate_cargo_toml in ROOT_TOML.member_cargo_tomls().iter() {
let crate_paths: Vec<String> = crate_cargo_toml.path_dependencies().collect();
all_path_deps_in_crate_tomls.extend(crate_paths);
}
let all_path_deps_in_crate_tomls: Vec<String> =
ROOT_TOML.member_cargo_tomls().values().flat_map(|toml| toml.path_dependencies()).collect();

assert!(
all_path_deps_in_crate_tomls.is_empty(),
"The following crates have path dependency {all_path_deps_in_crate_tomls:?}."
Expand Down

0 comments on commit 6b3bd58

Please sign in to comment.