Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 55 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ enum Cli {

#[derive(Deserialize, Debug)]
struct Cargotoml {
package: Package,
package: Option<WithMetadata>,
workspace: Option<WithMetadata>,
}

#[derive(Deserialize, Debug)]
struct Package {
struct WithMetadata {
metadata: Metadata,
}

Expand Down Expand Up @@ -102,11 +103,7 @@ fn get_commands(command: &str) -> Result<Vec<(String, String)>, 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);

Expand All @@ -121,3 +118,54 @@ fn get_commands(command: &str) -> Result<Vec<(String, String)>, String> {

Ok(commands)
}

fn get_commands_from_str(cargo_str: &str) -> Result<HashMap<String, String>, String> {
let cargo_toml: Cargotoml =
toml::from_str(&cargo_str[..]).or(Err("Could not find commands in Cargo.toml"))?;

let mut cargo_commands: HashMap<String, String> = 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()));
}
}