Skip to content

Commit

Permalink
feat(link): add --yes and --scope flags to link (#9466)
Browse files Browse the repository at this point in the history
### Description

Adds `--yes` and `--scope` flags

### Testing Instructions

Added tests for parsing those flags
  • Loading branch information
NicholasLYang authored Nov 19, 2024
1 parent 316b94e commit ccf1c2f
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 13 deletions.
4 changes: 3 additions & 1 deletion crates/turborepo-lib/src/cli/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use turborepo_telemetry::events::command::CommandEventBuilder;
use turborepo_ui::{color, BOLD, GREY};

use crate::{
commands::{bin, generate, ls, prune, run::get_signal, CommandBase},
commands::{bin, generate, link, ls, prune, run::get_signal, CommandBase},
daemon::DaemonError,
query,
rewrite_json::RewriteError,
Expand Down Expand Up @@ -45,6 +45,8 @@ pub enum Error {
#[diagnostic(transparent)]
Ls(#[from] ls::Error),
#[error(transparent)]
Link(#[from] link::Error),
#[error(transparent)]
#[diagnostic(transparent)]
Prune(#[from] prune::Error),
#[error(transparent)]
Expand Down
106 changes: 102 additions & 4 deletions crates/turborepo-lib/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,13 @@ pub enum Command {
#[clap(long)]
no_gitignore: bool,

/// The scope, i.e. Vercel team, to which you are linking
#[clap(long)]
scope: Option<String>,

/// Answer yes to all prompts (default false)
#[clap(long, short)]
yes: bool,
/// Specify what should be linked (default "remote cache")
#[clap(long, value_enum, default_value_t = LinkTarget::RemoteCache)]
target: LinkTarget,
Expand Down Expand Up @@ -1299,23 +1306,30 @@ pub async fn run(
}
Command::Link {
no_gitignore,
scope,
yes,
target,
} => {
CommandEventBuilder::new("link")
.with_parent(&root_telemetry)
.track_call();

if cli_args.team.is_some() {
warn!("team flag does not set the scope for linking. Use --scope instead.");
}

if cli_args.test_run {
println!("Link test run successful");
return Ok(0);
}

let modify_gitignore = !*no_gitignore;
let to = *target;
let yes = *yes;
let scope = scope.clone();
let mut base = CommandBase::new(cli_args, repo_root, version, color_config);

if let Err(err) = link::link(&mut base, modify_gitignore, to).await {
error!("error: {}", err.to_string())
}
link::link(&mut base, scope, modify_gitignore, yes, to).await?;

Ok(0)
}
Expand Down Expand Up @@ -1469,7 +1483,7 @@ mod test {
use itertools::Itertools;
use pretty_assertions::assert_eq;

use crate::cli::{ExecutionArgs, RunArgs};
use crate::cli::{ExecutionArgs, LinkTarget, RunArgs};

struct CommandTestCase {
command: &'static str,
Expand Down Expand Up @@ -2300,6 +2314,90 @@ mod test {
.test();
}

#[test]
fn test_parse_link() {
assert_eq!(
Args::try_parse_from(["turbo", "link"]).unwrap(),
Args {
command: Some(Command::Link {
no_gitignore: false,
scope: None,
yes: false,
target: LinkTarget::RemoteCache,
}),
..Args::default()
}
);

CommandTestCase {
command: "link",
command_args: vec![],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
no_gitignore: false,
scope: None,
yes: false,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--yes"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: true,
no_gitignore: false,
scope: None,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--scope", "foo"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: false,
no_gitignore: false,
scope: Some("foo".to_string()),
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();

CommandTestCase {
command: "link",
command_args: vec![vec!["--no-gitignore"]],
global_args: vec![vec!["--cwd", "../examples/with-yarn"]],
expected_output: Args {
command: Some(Command::Link {
yes: false,
no_gitignore: true,
scope: None,
target: LinkTarget::RemoteCache,
}),
cwd: Some(Utf8PathBuf::from("../examples/with-yarn")),
..Args::default()
},
}
.test();
}

#[test]
fn test_parse_login() {
assert_eq!(
Expand Down
20 changes: 16 additions & 4 deletions crates/turborepo-lib/src/commands/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ pub(crate) async fn verify_caching_enabled<'a>(

pub async fn link(
base: &mut CommandBase,
scope: Option<String>,
modify_gitignore: bool,
yes: bool,
target: LinkTarget,
) -> Result<(), Error> {
let homedir_path = home_dir().ok_or_else(|| Error::HomeDirectoryNotFound)?;
Expand All @@ -183,7 +185,7 @@ pub async fn link(
REMOTE_CACHING_URL
);

if !should_link_remote_cache(base, &repo_root_with_tilde)? {
if !yes && !should_link_remote_cache(base, &repo_root_with_tilde)? {
return Err(Error::NotLinking);
}

Expand All @@ -203,7 +205,17 @@ pub async fn link(
.await
.map_err(Error::TeamsRequest)?;

let selected_team = select_team(base, &teams_response.teams)?;
let selected_team = if let Some(team_slug) = scope {
SelectedTeam::Team(
teams_response
.teams
.iter()
.find(|team| team.slug == team_slug)
.ok_or_else(|| Error::TeamNotFound(team_slug.to_string()))?,
)
} else {
select_team(base, &teams_response.teams)?
};

let team_id = match selected_team {
SelectedTeam::User => user_response.user.id.as_str(),
Expand Down Expand Up @@ -632,7 +644,7 @@ mod test {
)
.unwrap();

link::link(&mut base, false, LinkTarget::RemoteCache)
link::link(&mut base, None, false, false, LinkTarget::RemoteCache)
.await
.unwrap();

Expand Down Expand Up @@ -707,7 +719,7 @@ mod test {
)
.unwrap();

link::link(&mut base, false, LinkTarget::Spaces)
link::link(&mut base, None, false, false, LinkTarget::Spaces)
.await
.unwrap();

Expand Down
9 changes: 8 additions & 1 deletion crates/turborepo-lib/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,14 @@ impl Diagnostic for RemoteCacheDiagnostic {
return;
};
stopped.await.unwrap();
let link_res = link(&mut base, false, crate::cli::LinkTarget::RemoteCache).await;
let link_res = link(
&mut base,
None,
false,
false,
crate::cli::LinkTarget::RemoteCache,
)
.await;
resume.send(()).unwrap();
link_res
};
Expand Down
10 changes: 9 additions & 1 deletion docs/repo-docs/reference/link.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ The selected owner (either a user or an organization) will be able to share [cac

Specifies the URL of your Remote Cache provider.

### `--yes`

Answer yes to all prompts

### `--scope <scope>`

The scope, i.e. Vercel team, to which you are linking

```bash title="Terminal"
turbo link --api https://acme.com
```
```
8 changes: 8 additions & 0 deletions turborepo-tests/integration/tests/command-link.t
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@ Link Test Run
$ ${TURBO} link --__test-run
Link test run successful

$ ${TURBO} link --__test-run --yes
Link test run successful

$ ${TURBO} link --__test-run --team=my-team
WARNING team flag does not set the scope for linking. Use --scope instead.
Link test run successful


8 changes: 6 additions & 2 deletions turborepo-tests/integration/tests/turbo-help.t
Original file line number Diff line number Diff line change
Expand Up @@ -329,14 +329,18 @@ Test help flag for link command
Do not create or modify .gitignore (default false)
--version

--scope <SCOPE>
The scope, i.e. Vercel team, to which you are linking
--skip-infer
Skip any attempts to infer which version of Turbo the project is configured to use
--target <TARGET>
Specify what should be linked (default "remote cache") [default: remote-cache] [possible values: remote-cache, spaces]
--no-update-notifier
Disable the turbo update notification
-y, --yes
Answer yes to all prompts (default false)
--api <API>
Override the endpoint for API calls
--target <TARGET>
Specify what should be linked (default "remote cache") [default: remote-cache] [possible values: remote-cache, spaces]
--color
Force color usage in the terminal
--cwd <CWD>
Expand Down

0 comments on commit ccf1c2f

Please sign in to comment.