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()?;
32
33 let workspace_root = manifest_path.parent()?;
35
36 let member_paths: Vec<(String, PathBuf)> = members
39 .iter()
40 .filter_map(|member| {
41 member.as_str().map(|s| {
42 let member_manifest = workspace_root.join(s).join("Cargo.toml");
44 let member_name = Path::new(s)
46 .file_name()
47 .map(|os_str| os_str.to_string_lossy().into_owned())
48 .unwrap_or_else(|| s.to_string());
49 (member_name, member_manifest)
50 })
51 })
52 .collect();
53
54 if member_paths.is_empty() {
55 None
56 } else {
57 Some(member_paths)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use std::io::Write;
65 use tempfile::NamedTempFile;
66
67 #[test]
68 fn test_get_workspace_member_manifest_paths() {
69 let mut file = NamedTempFile::new().unwrap();
70 writeln!(file, "[workspace]").unwrap();
72 writeln!(
73 file,
74 "members = [\"cargo-e\", \"addendum/e_crate_version_checker\"]"
75 )
76 .unwrap();
77 let paths = get_workspace_member_manifest_paths(file.path());
78 assert!(paths.is_some());
79 let paths = paths.unwrap();
80 assert_eq!(paths.len(), 2);
82 for (_, path) in paths {
84 assert!(path.ends_with("Cargo.toml"));
85 }
86 }
87}