From f577739df8ba33d5e980815195f845317110fc68 Mon Sep 17 00:00:00 2001 From: Nicholas Yang Date: Thu, 23 Jan 2025 10:52:36 +0530 Subject: [PATCH] fix(watch): correctly derive opts from watch mode args (#9761) ### Description I forgot to derive the `Opts` struct from the watch mode command. This PR does that and adds a test. ### Testing Instructions --- crates/turborepo-cache/src/lib.rs | 6 +- crates/turborepo-lib/src/cli/mod.rs | 4 +- crates/turborepo-lib/src/opts.rs | 55 ++++++++++++++++--- ...__test__turbo_boundaries_--filter_foo.snap | 10 ++++ ...ib__opts__test__turbo_ls_--filter_foo.snap | 10 ++++ ...repo_lib__opts__test__turbo_run_build.snap | 10 ++++ ...po_lib__opts__test__turbo_watch_build.snap | 10 ++++ .../visitor/.command.rs.pending-snap | 5 -- .../src/.lib.rs.pending-snap | 3 - 9 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_boundaries_--filter_foo.snap create mode 100644 crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_ls_--filter_foo.snap create mode 100644 crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_run_build.snap create mode 100644 crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_watch_build.snap delete mode 100644 crates/turborepo-lib/src/task_graph/visitor/.command.rs.pending-snap delete mode 100644 crates/turborepo-microfrontends/src/.lib.rs.pending-snap diff --git a/crates/turborepo-cache/src/lib.rs b/crates/turborepo-cache/src/lib.rs index b0aa4c607ab0f..0de5ae0a99fa0 100644 --- a/crates/turborepo-cache/src/lib.rs +++ b/crates/turborepo-cache/src/lib.rs @@ -108,7 +108,7 @@ pub struct CacheHitMetadata { pub time_saved: u64, } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] pub struct CacheActions { pub read: bool, pub write: bool, @@ -134,7 +134,7 @@ impl CacheActions { } } -#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize)] pub struct CacheConfig { pub local: CacheActions, pub remote: CacheActions, @@ -172,7 +172,7 @@ impl Default for CacheActions { } } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct CacheOpts { pub cache_dir: Utf8PathBuf, pub cache: CacheConfig, diff --git a/crates/turborepo-lib/src/cli/mod.rs b/crates/turborepo-lib/src/cli/mod.rs index 5860dd407e11a..0afce342631b3 100644 --- a/crates/turborepo-lib/src/cli/mod.rs +++ b/crates/turborepo-lib/src/cli/mod.rs @@ -126,7 +126,7 @@ impl LogOrder { } } -#[derive(Copy, Clone, Debug, PartialEq, ValueEnum)] +#[derive(Copy, Clone, Debug, PartialEq, ValueEnum, Serialize)] pub enum DryRunMode { Text, Json, @@ -399,7 +399,7 @@ impl Args { clap_args } - fn parse(os_args: Vec) -> Result { + pub(crate) fn parse(os_args: Vec) -> Result { let (is_single_package, single_package_free) = Self::remove_single_package(os_args); let mut args = Args::try_parse_from(single_package_free)?; // And then only add them back in when we're in `run`. diff --git a/crates/turborepo-lib/src/opts.rs b/crates/turborepo-lib/src/opts.rs index 2b628d600d125..79a9aabbc9e84 100644 --- a/crates/turborepo-lib/src/opts.rs +++ b/crates/turborepo-lib/src/opts.rs @@ -1,6 +1,7 @@ use std::backtrace; use camino::Utf8PathBuf; +use serde::Serialize; use thiserror::Error; use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf, AnchoredSystemPathBuf}; use turborepo_api_client::APIAuth; @@ -43,7 +44,7 @@ pub enum Error { Config(#[from] crate::config::Error), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct APIClientOpts { pub api_url: String, pub timeout: u64, @@ -55,7 +56,7 @@ pub struct APIClientOpts { pub preflight: bool, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct RepoOpts { pub root_turbo_json_path: AbsoluteSystemPathBuf, pub allow_no_package_manager: bool, @@ -65,7 +66,7 @@ pub struct RepoOpts { /// The fully resolved options for Turborepo. This is the combination of config, /// including all the layers (env, args, defaults, etc.), and the command line /// arguments. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct Opts { pub repo_opts: RepoOpts, pub api_client_opts: APIClientOpts, @@ -135,6 +136,7 @@ impl Opts { run_args, execution_args, }) => (execution_args, run_args), + Some(Command::Watch(execution_args)) => (execution_args, &Box::default()), Some(Command::Ls { affected, filter, .. }) => { @@ -191,7 +193,7 @@ struct OptsInputs<'a> { api_auth: &'a Option, } -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Serialize)] pub struct RunCacheOpts { pub(crate) task_output_logs_override: Option, } @@ -204,7 +206,7 @@ impl<'a> From> for RunCacheOpts { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize)] pub struct RunOpts { pub(crate) tasks: Vec, pub(crate) concurrency: u32, @@ -261,19 +263,19 @@ impl<'a> TaskArgs<'a> { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize)] pub enum GraphOpts { Stdout, File(String), } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Serialize)] pub enum ResolvedLogOrder { Stream, Grouped, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize)] pub enum ResolvedLogPrefix { Task, None, @@ -395,7 +397,7 @@ impl From for ResolvedLogPrefix { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize)] pub struct ScopeOpts { pub pkg_inference_root: Option, pub global_deps: Vec, @@ -537,6 +539,9 @@ impl ScopeOpts { #[cfg(test)] mod test { + use clap::Parser; + use itertools::Itertools; + use serde_json::json; use tempfile::TempDir; use test_case::test_case; use turbopath::AbsoluteSystemPathBuf; @@ -826,4 +831,36 @@ mod test { Ok(()) } + + #[test_case( + vec!["turbo", "watch", "build"]; + "watch" + )] + #[test_case( + vec!["turbo", "run", "build"]; + "run" + )] + #[test_case( + vec!["turbo", "ls", "--filter", "foo"]; + "ls" + )] + #[test_case( + vec!["turbo", "boundaries", "--filter", "foo"]; + "boundaries" + )] + fn test_derive_opts_from_args(args_str: Vec<&str>) -> Result<(), anyhow::Error> { + let args = Args::try_parse_from(&args_str)?; + let opts = Opts::new( + &AbsoluteSystemPathBuf::default(), + &args, + ConfigurationOptions::default(), + )?; + + insta::assert_json_snapshot!( + args_str.iter().join("_"), + json!({ "tasks": opts.run_opts.tasks, "filter_patterns": opts.scope_opts.filter_patterns }) + ); + + Ok(()) + } } diff --git a/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_boundaries_--filter_foo.snap b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_boundaries_--filter_foo.snap new file mode 100644 index 0000000000000..a871f1cd4a2ec --- /dev/null +++ b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_boundaries_--filter_foo.snap @@ -0,0 +1,10 @@ +--- +source: crates/turborepo-lib/src/opts.rs +expression: "json!({\n \"tasks\": opts.run_opts.tasks, \"filter_patterns\":\n opts.scope_opts.filter_patterns\n})" +--- +{ + "tasks": [], + "filter_patterns": [ + "foo" + ] +} diff --git a/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_ls_--filter_foo.snap b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_ls_--filter_foo.snap new file mode 100644 index 0000000000000..a871f1cd4a2ec --- /dev/null +++ b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_ls_--filter_foo.snap @@ -0,0 +1,10 @@ +--- +source: crates/turborepo-lib/src/opts.rs +expression: "json!({\n \"tasks\": opts.run_opts.tasks, \"filter_patterns\":\n opts.scope_opts.filter_patterns\n})" +--- +{ + "tasks": [], + "filter_patterns": [ + "foo" + ] +} diff --git a/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_run_build.snap b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_run_build.snap new file mode 100644 index 0000000000000..3f562b17dd5f5 --- /dev/null +++ b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_run_build.snap @@ -0,0 +1,10 @@ +--- +source: crates/turborepo-lib/src/opts.rs +expression: "json!({\n \"tasks\": opts.run_opts.tasks, \"filter_patterns\":\n opts.scope_opts.filter_patterns\n})" +--- +{ + "tasks": [ + "build" + ], + "filter_patterns": [] +} diff --git a/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_watch_build.snap b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_watch_build.snap new file mode 100644 index 0000000000000..3f562b17dd5f5 --- /dev/null +++ b/crates/turborepo-lib/src/snapshots/turborepo_lib__opts__test__turbo_watch_build.snap @@ -0,0 +1,10 @@ +--- +source: crates/turborepo-lib/src/opts.rs +expression: "json!({\n \"tasks\": opts.run_opts.tasks, \"filter_patterns\":\n opts.scope_opts.filter_patterns\n})" +--- +{ + "tasks": [ + "build" + ], + "filter_patterns": [] +} diff --git a/crates/turborepo-lib/src/task_graph/visitor/.command.rs.pending-snap b/crates/turborepo-lib/src/task_graph/visitor/.command.rs.pending-snap deleted file mode 100644 index 367ad859f8f98..0000000000000 --- a/crates/turborepo-lib/src/task_graph/visitor/.command.rs.pending-snap +++ /dev/null @@ -1,5 +0,0 @@ -{"run_id":"1737179308-428315000","line":309,"new":{"module_name":"turborepo_lib__task_graph__visitor__command__test","snapshot_name":"error_short_circuits_factory","metadata":{"source":"crates/turborepo-lib/src/task_graph/visitor/command.rs","assertion_line":309,"expression":"cmd.to_string()"},"snapshot":"Internal errors encountered: oops!"},"old":{"module_name":"turborepo_lib__task_graph__visitor__command__test","metadata":{},"snapshot":"internal errors encountered: oops!"}} -{"run_id":"1737179538-131428000","line":309,"new":null,"old":null} -{"run_id":"1737179603-300467000","line":309,"new":null,"old":null} -{"run_id":"1737179676-323346000","line":309,"new":null,"old":null} -{"run_id":"1737179741-977012000","line":309,"new":null,"old":null} diff --git a/crates/turborepo-microfrontends/src/.lib.rs.pending-snap b/crates/turborepo-microfrontends/src/.lib.rs.pending-snap deleted file mode 100644 index 883186b1f2fd9..0000000000000 --- a/crates/turborepo-microfrontends/src/.lib.rs.pending-snap +++ /dev/null @@ -1,3 +0,0 @@ -{"run_id":"1737179605-821842000","line":208,"new":{"module_name":"turborepo_microfrontends__test","snapshot_name":"unsupported_version","metadata":{"source":"crates/turborepo-microfrontends/src/lib.rs","assertion_line":208,"expression":"err"},"snapshot":"Unsupported microfrontends configuration version: yolo. Supported versions: [\"1\", \"2\"]"},"old":{"module_name":"turborepo_microfrontends__test","metadata":{},"snapshot":"Unsupported micro-frontends configuration version: yolo. Supported versions: [\"1\", \"2\"]"}} -{"run_id":"1737179677-885648000","line":208,"new":{"module_name":"turborepo_microfrontends__test","snapshot_name":"unsupported_version","metadata":{"source":"crates/turborepo-microfrontends/src/lib.rs","assertion_line":208,"expression":"err"},"snapshot":"Unsupported microfrontends configuration version: yolo. Supported versions: [\"1\", \"2\"]"},"old":{"module_name":"turborepo_microfrontends__test","metadata":{},"snapshot":"Unsupported micro-frontends configuration version: yolo. Supported versions: [\"1\", \"2\"]"}} -{"run_id":"1737179744-116940000","line":208,"new":null,"old":null}