1use std::fs;
2use std::path::{Path, PathBuf};
3use toml::Value;
4
5pub fn is_workspace_manifest(manifest_path: &Path) -> bool {
8 if let Ok(content) = fs::read_to_string(manifest_path) {
9 for line in content.lines() {
11 if line.trim_start().starts_with("[workspace]") {
12 return true;
13 }
14 }
15 }
16 false
17}
18
19pub fn get_workspace_member_manifest_paths(manifest_path: &Path) -> Option<Vec<(String, PathBuf)>> {
24 let content = fs::read_to_string(manifest_path).ok()?;
26 let parsed: Value = content.parse().ok()?;
27
28 let workspace = parsed.get("workspace")?;
30 let members = workspace.get("members")?.as_array()?;
31
32 let workspace_root = manifest_path.parent()?;
34
35 let mut member_paths = Vec::new();
36
37 for member in members {
38 if let Some(s) = member.as_str() {
39 if s.ends_with("/*") {
40 let base = workspace_root.join(s.trim_end_matches("/*"));
42 if let Ok(entries) = fs::read_dir(&base) {
44 for entry in entries.flatten() {
45 let path = entry.path();
46 if path.is_dir() {
47 let cargo_toml = path.join("Cargo.toml");
48 if cargo_toml.exists() {
49 if let Some(member_name) =
51 path.file_name().and_then(|os| os.to_str())
52 {
53 member_paths.push((
54 format!(
55 "{}/{}",
56 s.trim_end_matches("/*"),
57 member_name.to_string()
58 ),
59 cargo_toml,
60 ));
61 }
62 }
63 }
64 }
65 }
66 } else {
67 let member_path = workspace_root.join(s);
69 let member_manifest = member_path.join("Cargo.toml");
70 if member_manifest.exists() {
71 let mut member_name = Path::new(s)
72 .file_name()
73 .and_then(|os| os.to_str())
74 .unwrap_or(s)
75 .to_string();
76 if member_name.eq("src-tauri") {
77 member_name = member_path
79 .parent()
80 .and_then(|p| p.file_name())
81 .and_then(|os| os.to_str())
82 .unwrap_or(s)
83 .to_string();
84 }
85 member_paths.push((member_name, member_manifest));
86 }
87 }
88 }
89 }
90
91 if member_paths.is_empty() {
92 None
93 } else {
94 Some(member_paths)
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use std::fs;
102 use tempfile::TempDir;
103
104 #[test]
105 fn test_workspace_member_manifest_paths_found() {
106 let temp_dir = TempDir::new().unwrap();
108
109 let workspace_manifest_path = temp_dir.path().join("Cargo.toml");
111 let workspace_manifest_content = r#"
112[workspace]
113members = ["cargo-e", "addendum/e_crate_version_checker"]
114 "#;
115 fs::write(&workspace_manifest_path, workspace_manifest_content).unwrap();
116
117 let cargo_e_dir = temp_dir.path().join("cargo-e");
119 fs::create_dir_all(&cargo_e_dir).unwrap();
120 fs::write(cargo_e_dir.join("Cargo.toml"), "dummy content").unwrap();
121
122 let e_crate_dir = temp_dir
124 .path()
125 .join("addendum")
126 .join("e_crate_version_checker");
127 fs::create_dir_all(&e_crate_dir).unwrap();
128 fs::write(e_crate_dir.join("Cargo.toml"), "dummy content").unwrap();
129
130 let result = get_workspace_member_manifest_paths(&workspace_manifest_path);
132 assert!(result.is_some());
133 let members = result.unwrap();
134 assert_eq!(members.len(), 2);
135
136 for (_, path) in members {
138 assert!(path.ends_with("Cargo.toml"));
139 }
140 }
141
142 #[test]
143 fn test_workspace_member_manifest_paths_not_found() {
144 let temp_dir = TempDir::new().unwrap();
146
147 let workspace_manifest_path = temp_dir.path().join("Cargo.toml");
149 let workspace_manifest_content = r#"
150[workspace]
151members = ["cargo-e", "addendum/e_crate_version_checker"]
152 "#;
153 fs::write(&workspace_manifest_path, workspace_manifest_content).unwrap();
154
155 let result = get_workspace_member_manifest_paths(&workspace_manifest_path);
159 assert!(result.is_none());
160 }
161}