Skip to content

Commit

Permalink
feat(prune): add ability to specify scopes via argument instead of fl…
Browse files Browse the repository at this point in the history
…ag (#6022)

### Description

As per @nathanhammond's suggestion, `--scope` should be an arg since it
is required.

UI change: 
We now have help text for the `SCOPE` argument, wording isn't great, but
it matches the wording used for the overall prune command.

Clap will now complain about missing scopes for prune before our error
message in `prune.rs` where we check if [`scopes` is
empty](https://github.com/vercel/turbo/blob/main/crates/turborepo-lib/src/commands/prune.rs#L234C12-L234C12).
All existing usages of `turbo prune` will continue working just a
different error message:

Old:
```
[1 olszewski@chriss-mbp] /Users/olszewski/code/vercel/turborepo/turborepo-tests/integration $ turbo prune
Turbo error: at least one target must be specified
```

New:
```
[0 olszewski@chriss-mbp] /Users/olszewski/code/vercel/turborepo/turborepo-tests/integration $ turbo_dev prune
 ERROR  the following required arguments were not provided:
  <SCOPE>...

Usage: turbo prune <SCOPE>...

For more information, try '--help'.
```

### Testing Instructions

Added new unit tests that use the arg variant and a new test to make
sure users can't mix the two ways to specify scope.


Closes TURBO-1357

Co-authored-by: Chris Olszewski <Chris Olszewski>
  • Loading branch information
chris-olszewski authored and Zertsov committed Sep 27, 2023
1 parent d063cca commit 64b693f
Showing 1 changed file with 53 additions and 16 deletions.
69 changes: 53 additions & 16 deletions crates/turborepo-lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,15 @@ pub enum Command {
Logout {},
/// Prepare a subset of your monorepo.
Prune {
#[clap(long)]
scope: Vec<String>,
#[clap(hide = true, long)]
scope: Option<Vec<String>>,
/// Workspaces that should be included in the subset
#[clap(
required_unless_present("scope"),
conflicts_with("scope"),
value_name = "SCOPE"
)]
scope_arg: Option<Vec<String>>,
#[clap(long)]
docker: bool,
#[clap(long = "out-dir", default_value_t = String::from("out"), value_parser)]
Expand Down Expand Up @@ -782,10 +789,15 @@ pub async fn run(
}
Command::Prune {
scope,
scope_arg,
docker,
output_dir,
} => {
let scope = scope.clone();
let scope = scope_arg
.as_ref()
.or(scope.as_ref())
.cloned()
.unwrap_or_default();
let docker = *docker;
let output_dir = output_dir.clone();
let base = CommandBase::new(cli_args, repo_root, version, ui)?;
Expand Down Expand Up @@ -1638,13 +1650,14 @@ mod test {
#[test]
fn test_parse_prune() {
let default_prune = Command::Prune {
scope: Vec::new(),
scope: None,
scope_arg: Some(vec!["foo".into()]),
docker: false,
output_dir: "out".to_string(),
};

assert_eq!(
Args::try_parse_from(["turbo", "prune"]).unwrap(),
Args::try_parse_from(["turbo", "prune", "foo"]).unwrap(),
Args {
command: Some(default_prune.clone()),
..Args::default()
Expand All @@ -1653,7 +1666,7 @@ mod test {

CommandTestCase {
command: "prune",
command_args: vec![],
command_args: vec![vec!["foo"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(default_prune),
Expand All @@ -1667,7 +1680,21 @@ mod test {
Args::try_parse_from(["turbo", "prune", "--scope", "bar"]).unwrap(),
Args {
command: Some(Command::Prune {
scope: vec!["bar".to_string()],
scope: Some(vec!["bar".to_string()]),
scope_arg: None,
docker: false,
output_dir: "out".to_string(),
}),
..Args::default()
}
);

assert_eq!(
Args::try_parse_from(["turbo", "prune", "foo", "bar"]).unwrap(),
Args {
command: Some(Command::Prune {
scope: None,
scope_arg: Some(vec!["foo".to_string(), "bar".to_string()]),
docker: false,
output_dir: "out".to_string(),
}),
Expand All @@ -1676,10 +1703,11 @@ mod test {
);

assert_eq!(
Args::try_parse_from(["turbo", "prune", "--docker"]).unwrap(),
Args::try_parse_from(["turbo", "prune", "--docker", "foo"]).unwrap(),
Args {
command: Some(Command::Prune {
scope: Vec::new(),
scope: None,
scope_arg: Some(vec!["foo".into()]),
docker: true,
output_dir: "out".to_string(),
}),
Expand All @@ -1688,10 +1716,11 @@ mod test {
);

assert_eq!(
Args::try_parse_from(["turbo", "prune", "--out-dir", "dist"]).unwrap(),
Args::try_parse_from(["turbo", "prune", "--out-dir", "dist", "foo"]).unwrap(),
Args {
command: Some(Command::Prune {
scope: Vec::new(),
scope: None,
scope_arg: Some(vec!["foo".into()]),
docker: false,
output_dir: "dist".to_string(),
}),
Expand All @@ -1701,11 +1730,12 @@ mod test {

CommandTestCase {
command: "prune",
command_args: vec![vec!["--out-dir", "dist"], vec!["--docker"]],
command_args: vec![vec!["foo"], vec!["--out-dir", "dist"], vec!["--docker"]],
global_args: vec![],
expected_output: Args {
command: Some(Command::Prune {
scope: Vec::new(),
scope: None,
scope_arg: Some(vec!["foo".into()]),
docker: true,
output_dir: "dist".to_string(),
}),
Expand All @@ -1716,11 +1746,12 @@ mod test {

CommandTestCase {
command: "prune",
command_args: vec![vec!["--out-dir", "dist"], vec!["--docker"]],
command_args: vec![vec!["foo"], vec!["--out-dir", "dist"], vec!["--docker"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Prune {
scope: Vec::new(),
scope: None,
scope_arg: Some(vec!["foo".into()]),
docker: true,
output_dir: "dist".to_string(),
}),
Expand All @@ -1740,7 +1771,8 @@ mod test {
global_args: vec![],
expected_output: Args {
command: Some(Command::Prune {
scope: vec!["foo".to_string()],
scope: Some(vec!["foo".to_string()]),
scope_arg: None,
docker: true,
output_dir: "dist".to_string(),
}),
Expand Down Expand Up @@ -1792,6 +1824,11 @@ mod test {
);
}

#[test]
fn test_parse_prune_no_mixed_arg_and_flag() {
assert!(Args::try_parse_from(["turbo", "prune", "foo", "--scope", "bar"]).is_err(),);
}

#[test]
fn test_verbosity_serialization() -> Result<(), serde_json::Error> {
assert_eq!(
Expand Down

0 comments on commit 64b693f

Please sign in to comment.