From f8e9dc11377682e4f98b87525e1da91b0f74b025 Mon Sep 17 00:00:00 2001
From: dorimedini-starkware <dori@starkware.co>
Date: Sun, 17 Nov 2024 10:19:46 +0200
Subject: [PATCH] chore(ci): enforce crate directory name match + take version
 from workspace (#2014)

Signed-off-by: Dori Medini <dori@starkware.co>
---
 crates/starknet_mempool_p2p/Cargo.toml       |  2 +-
 crates/starknet_mempool_p2p_types/Cargo.toml |  2 +-
 workspace_tests/main.rs                      |  1 +
 workspace_tests/package_integrity_test.rs    | 26 +++++++++++++++
 workspace_tests/toml_utils.rs                |  9 ++++++
 workspace_tests/version_integrity_test.rs    | 34 +++++++++++++++++++-
 6 files changed, 71 insertions(+), 3 deletions(-)
 create mode 100644 workspace_tests/package_integrity_test.rs

diff --git a/crates/starknet_mempool_p2p/Cargo.toml b/crates/starknet_mempool_p2p/Cargo.toml
index 4d3b45e8c57..5e5b278e499 100644
--- a/crates/starknet_mempool_p2p/Cargo.toml
+++ b/crates/starknet_mempool_p2p/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "starknet_mempool_p2p"
-version = "0.0.0"
+version.workspace = true
 edition.workspace = true
 license.workspace = true
 repository.workspace = true
diff --git a/crates/starknet_mempool_p2p_types/Cargo.toml b/crates/starknet_mempool_p2p_types/Cargo.toml
index ffc6c04e897..352de1ab630 100644
--- a/crates/starknet_mempool_p2p_types/Cargo.toml
+++ b/crates/starknet_mempool_p2p_types/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "starknet_mempool_p2p_types"
-version = "0.0.0"
+version.workspace = true
 edition.workspace = true
 license.workspace = true
 repository.workspace = true
diff --git a/workspace_tests/main.rs b/workspace_tests/main.rs
index c754aaeccbf..dce1c1efde0 100644
--- a/workspace_tests/main.rs
+++ b/workspace_tests/main.rs
@@ -1,5 +1,6 @@
 #![cfg(test)]
 
 pub mod lints_test;
+pub mod package_integrity_test;
 pub mod toml_utils;
 pub mod version_integrity_test;
diff --git a/workspace_tests/package_integrity_test.rs b/workspace_tests/package_integrity_test.rs
new file mode 100644
index 00000000000..3c76f6fe4f6
--- /dev/null
+++ b/workspace_tests/package_integrity_test.rs
@@ -0,0 +1,26 @@
+use std::path::PathBuf;
+
+use crate::toml_utils::{PackageEntryValue, ROOT_TOML};
+
+#[test]
+fn test_package_names_match_directory() {
+    let mismatched_packages: Vec<_> = ROOT_TOML
+        .member_cargo_tomls()
+        .into_iter()
+        .filter_map(|(path_str, toml)| {
+            let path = PathBuf::from(&path_str);
+            let directory_name = path.file_name()?.to_str()?;
+            match toml.package.get("name") {
+                Some(PackageEntryValue::String(package_name)) if package_name == directory_name => {
+                    None
+                }
+                _ => Some(path_str),
+            }
+        })
+        .collect();
+    assert!(
+        mismatched_packages.is_empty(),
+        "The following crates have package names that do not match their directory names, or are \
+         missing a name field: {mismatched_packages:?}."
+    );
+}
diff --git a/workspace_tests/toml_utils.rs b/workspace_tests/toml_utils.rs
index ee98dd6c7e6..ba102d747c5 100644
--- a/workspace_tests/toml_utils.rs
+++ b/workspace_tests/toml_utils.rs
@@ -35,8 +35,17 @@ pub(crate) struct CargoToml {
     workspace: WorkspaceFields,
 }
 
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(untagged)]
+pub(crate) enum PackageEntryValue {
+    String(String),
+    Object { workspace: bool },
+    Other(toml::Value),
+}
+
 #[derive(Clone, Debug, Serialize, Deserialize)]
 pub(crate) struct CrateCargoToml {
+    pub(crate) package: HashMap<String, PackageEntryValue>,
     dependencies: Option<HashMap<String, DependencyValue>>,
     #[serde(rename = "dev-dependencies")]
     dev_dependencies: Option<HashMap<String, DependencyValue>>,
diff --git a/workspace_tests/version_integrity_test.rs b/workspace_tests/version_integrity_test.rs
index f3d0c614597..2f30127a686 100644
--- a/workspace_tests/version_integrity_test.rs
+++ b/workspace_tests/version_integrity_test.rs
@@ -1,4 +1,4 @@
-use crate::toml_utils::{DependencyValue, LocalCrate, ROOT_TOML};
+use crate::toml_utils::{DependencyValue, LocalCrate, PackageEntryValue, ROOT_TOML};
 
 #[test]
 fn test_path_dependencies_are_members() {
@@ -27,6 +27,38 @@ fn test_version_alignment() {
     );
 }
 
+#[test]
+fn validate_crate_version_is_workspace() {
+    let crates_without_workspace_version: Vec<String> = ROOT_TOML
+        .member_cargo_tomls()
+        .into_iter()
+        .flat_map(|(member, toml)| match toml.package.get("version") {
+            // No `version` field.
+            None => Some(member),
+            Some(version) => match version {
+                // version = "x.y.z".
+                PackageEntryValue::String(_) => Some(member),
+                // version.workspace = (true | false).
+                PackageEntryValue::Object { workspace } => {
+                    if *workspace {
+                        None
+                    } else {
+                        Some(member)
+                    }
+                }
+                // Unknown version object.
+                PackageEntryValue::Other(_) => Some(member),
+            },
+        })
+        .collect();
+
+    assert!(
+        crates_without_workspace_version.is_empty(),
+        "The following crates don't have `version.workspace = true` in the [package] section: \
+         {crates_without_workspace_version:?}."
+    );
+}
+
 #[test]
 fn validate_no_path_dependencies() {
     let all_path_deps_in_crate_tomls: Vec<String> =