diff --git a/crates/turborepo-lib/src/cli.rs b/crates/turborepo-lib/src/cli.rs index fec4e1b0c8849..0d19a30f55cde 100644 --- a/crates/turborepo-lib/src/cli.rs +++ b/crates/turborepo-lib/src/cli.rs @@ -90,6 +90,9 @@ pub struct Args { /// verbosity #[clap(flatten)] pub verbosity: Verbosity, + #[clap(long, global = true, hide = true)] + /// Force a check for a new version of turbo + pub check_for_update: bool, #[clap(long = "__test-run", global = true, hide = true)] pub test_run: bool, #[clap(flatten, next_help_heading = "Run Arguments")] diff --git a/crates/turborepo-lib/src/shim.rs b/crates/turborepo-lib/src/shim.rs index f4551d6322306..50859c6b412a9 100644 --- a/crates/turborepo-lib/src/shim.rs +++ b/crates/turborepo-lib/src/shim.rs @@ -8,6 +8,7 @@ use std::{ process, process::Stdio, str::FromStr, + time::Duration, }; use anyhow::{anyhow, Result}; @@ -33,12 +34,14 @@ static TURBO_PURE_OUTPUT_ARGS: [&str; 6] = [ "--dry-run=json", ]; +static TURBO_SKIP_NOTIFIER_ARGS: [&str; 4] = ["--help", "--h", "--version", "--v"]; static SUPPORTS_SKIP_INFER_SEMVER: &str = ">=1.7.0-canary.0"; #[derive(Debug)] struct ShimArgs { cwd: PathBuf, skip_infer: bool, + force_update_check: bool, remaining_turbo_args: Vec, forwarded_args: Vec, } @@ -48,6 +51,7 @@ impl ShimArgs { let mut found_cwd_flag = false; let mut cwd: Option = None; let mut skip_infer = false; + let mut force_update_check = false; let mut remaining_turbo_args = Vec::new(); let mut forwarded_args = Vec::new(); let mut is_forwarded_args = false; @@ -58,6 +62,8 @@ impl ShimArgs { forwarded_args.push(arg); } else if arg == "--skip-infer" { skip_infer = true; + } else if arg == "--check-for-update" { + force_update_check = true; } else if arg == "--" { // If we've hit `--` we've reached the args forwarded to tasks. is_forwarded_args = true; @@ -95,6 +101,7 @@ impl ShimArgs { Ok(ShimArgs { cwd, skip_infer, + force_update_check, remaining_turbo_args, forwarded_args, }) @@ -102,11 +109,30 @@ impl ShimArgs { } // returns true if any flags result in pure json output to stdout - pub fn has_json_flags(&self) -> bool { + fn has_json_flags(&self) -> bool { self.remaining_turbo_args .iter() .any(|arg| TURBO_PURE_OUTPUT_ARGS.contains(&arg.as_str())) } + + // returns true if any flags should bypass the update notifier + fn has_notifier_skip_flags(&self) -> bool { + self.remaining_turbo_args + .iter() + .any(|arg| TURBO_SKIP_NOTIFIER_ARGS.contains(&arg.as_str())) + } + + pub fn should_check_for_update(&self) -> bool { + if self.force_update_check { + return true; + } + + if self.has_notifier_skip_flags() || self.has_json_flags() { + return false; + } + + true + } } #[derive(Debug, Clone, PartialEq, Serialize)] @@ -305,7 +331,7 @@ pub fn run() -> Result { // global turbo having handled the inference. We can run without any // concerns. - if !args.has_json_flags() { + if args.should_check_for_update() { // custom footer for update message let footer = format!( "Follow {username} for updates: {url}", @@ -313,15 +339,22 @@ pub fn run() -> Result { url = "https://twitter.com/turborepo" ); + let interval = if args.force_update_check { + // force update check + Some(Duration::ZERO) + } else { + // use default (24 hours) + None + }; // check for updates let _ = check_for_updates( "turbo", "https://github.com/vercel/turbo", Some(&footer), get_version(), - // use defaults for timeout and refresh interval (800ms and 1 day respectively) - None, + // use default for timeout (800ms) None, + interval, ); }