diff --git a/README.md b/README.md index a140a27..b9231bc 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,13 @@ You can define your commands in `Cargo.toml` under the `[package.metadata.comman greet = "echo 'Hello, planet!'" ``` +If working with a workspace, you can use the `[workspace.metadata.commands]` table instead: + +```toml +[workspace.metadata.commands] +greet = "echo 'Hello, planet!'" +``` + Now you can run `cargo cmd greet`: ```sh diff --git a/src/main.rs b/src/main.rs index 8952cfa..993aa3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,11 +26,12 @@ enum Cli { #[derive(Deserialize, Debug)] struct Cargotoml { - package: Package, + package: Option, + workspace: Option, } #[derive(Deserialize, Debug)] -struct Package { +struct WithMetadata { metadata: Metadata, } @@ -102,11 +103,7 @@ fn get_commands(command: &str) -> Result, String> { .read_to_string(&mut cargo_str) .or(Err("Could not read the contents of Cargo.toml"))?; - let cargo_toml: Cargotoml = - toml::from_str(&cargo_str[..]).or(Err("Could not find commands in Cargo.toml"))?; - - let cargo_commands = cargo_toml.package.metadata.commands; - + let cargo_commands = get_commands_from_str(&cargo_str)?; for name in names { let command_to_run = &cargo_commands.get(&name); @@ -121,3 +118,54 @@ fn get_commands(command: &str) -> Result, String> { Ok(commands) } + +fn get_commands_from_str(cargo_str: &str) -> Result, String> { + let cargo_toml: Cargotoml = + toml::from_str(&cargo_str[..]).or(Err("Could not find commands in Cargo.toml"))?; + + let mut cargo_commands: HashMap = HashMap::new(); + + if let Some(package) = cargo_toml.package { + cargo_commands.extend(package.metadata.commands); + } else if let Some(workspace) = cargo_toml.workspace { + cargo_commands.extend(workspace.metadata.commands); + } else { + return Err("Could not find commands in Cargo.toml".to_string()); + } + + Ok(cargo_commands) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_commands_from_package_str() { + let cargo_str = r#" + [package] + name = "test" + version = "0.1.0" + [package.metadata.commands] + test = "echo 'test'" + "#; + + let commands = get_commands_from_str(cargo_str).unwrap(); + assert_eq!(commands.len(), 1); + assert_eq!(commands.get("test"), Some(&"echo 'test'".to_string())); + } + + #[test] + fn test_get_commands_from_workspace_str() { + let cargo_str = r#" + [workspace] + members = ["test"] + [workspace.metadata.commands] + test = "echo 'test from workspace'" + "#; + + let commands = get_commands_from_str(cargo_str).unwrap(); + assert_eq!(commands.len(), 1); + assert_eq!(commands.get("test"), Some(&"echo 'test from workspace'".to_string())); + } +}