From 5aed63f615b97c79092c0c55019ac39227105cfa Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 10:26:20 -0400 Subject: [PATCH 1/7] Add selection command line arguments to show status. --- src/cli/directories.rs | 2 +- src/cli/status.rs | 47 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/src/cli/directories.rs b/src/cli/directories.rs index 631fa07..38d030a 100644 --- a/src/cli/directories.rs +++ b/src/cli/directories.rs @@ -43,7 +43,7 @@ pub struct Arguments { #[arg(long, display_order = 0)] completed: bool, - /// Show submitted + /// Show submitted directories. #[arg(long, display_order = 0)] submitted: bool, diff --git a/src/cli/status.rs b/src/cli/status.rs index 07085b1..3739093 100644 --- a/src/cli/status.rs +++ b/src/cli/status.rs @@ -16,6 +16,7 @@ use row::project::{Project, Status}; use row::workflow::ResourceCost; use row::MultiProgressContainer; +#[allow(clippy::struct_excessive_bools)] #[derive(Args, Debug)] pub struct Arguments { /// Select the actions to summarize with a wildcard pattern. @@ -28,6 +29,26 @@ pub struct Arguments { /// Select directories to summarize (defaults to all). Use 'status -' to read from stdin. directories: Vec, + + /// Show actions with completed directories. + #[arg(long, display_order = 0, conflicts_with = "all")] + completed: bool, + + /// Show actions with submitted directories. + #[arg(long, display_order = 0, conflicts_with = "all")] + submitted: bool, + + /// Show actions with eligible directories. + #[arg(long, display_order = 0, conflicts_with = "all")] + eligible: bool, + + /// Show actions with waiting directories. + #[arg(long, display_order = 0, conflicts_with = "all")] + waiting: bool, + + /// Show all actions (even those with 0 directories) + #[arg(long, display_order = 0)] + all: bool, } /// Format a status string for non-terminal outputs. @@ -84,6 +105,19 @@ pub fn status( output: &mut W, ) -> Result<(), Box> { debug!("Showing the workflow's status."); + + // Show directories with selected statuses. + let mut show_completed = args.completed; + let mut show_submitted = args.submitted; + let mut show_eligible = args.eligible; + let mut show_waiting = args.waiting; + if !show_completed && !show_submitted && !show_eligible && !show_waiting { + show_completed = true; + show_submitted = true; + show_eligible = true; + show_waiting = true; + } + let action_matcher = WildMatch::new(&args.action); let mut project = Project::open(options.io_threads, &options.cluster, multi_progress)?; @@ -134,9 +168,16 @@ pub fn status( cost = cost + action.resources.cost(group.len()); } - table - .rows - .push(Row::Items(make_row(action.name(), &status, &cost))); + if args.all + || (!status.completed.is_empty() && show_completed) + || (!status.submitted.is_empty() && show_submitted) + || (!status.eligible.is_empty() && show_eligible) + || (!status.waiting.is_empty() && show_waiting) + { + table + .rows + .push(Row::Items(make_row(action.name(), &status, &cost))); + } } if matching_action_count == 0 { From a8a283d06d1be9c5b18b8cbd06e47f5abfa10628 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 10:33:10 -0400 Subject: [PATCH 2/7] Document show status selection arguments. --- doc/src/row/show/status.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/doc/src/row/show/status.md b/doc/src/row/show/status.md index b43947c..a817204 100644 --- a/doc/src/row/show/status.md +++ b/doc/src/row/show/status.md @@ -30,16 +30,40 @@ echo "dir1" | row show status - Set `--action ` to choose which actions to display by name. By default, **row** shows the status of all actions. `` is a wildcard pattern. +### `-`all` + +Show all actions. Even those with 0 directories. + +### `--completed` + +Show actions with *completed* directories. + +### `--eligible` + +Show actions with *eligible* directories. + ### `--no-header` Hide the header in the output. +### `--submitted` + +Show actions with *submitted* directories. + +### `--waiting` + +Show actions with *waiting* directories. + ## Examples * Show the status of the entire workspace: ```bash row show status ``` +* Show the status of all actions that have eligible directories: + ```bash + row show status --eligible + ``` * Show the status of a specific action: ```bash row show status --action=action From ce105ff05284b03e97b4c55a09475892071e1f8f Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 12:13:32 -0400 Subject: [PATCH 3/7] Update change log. --- doc/src/release-notes.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/src/release-notes.md b/doc/src/release-notes.md index 27f169a..09e5db7 100644 --- a/doc/src/release-notes.md +++ b/doc/src/release-notes.md @@ -5,11 +5,15 @@ *Added:* * Edit links to documentation pages. +* New arguments to `show status` display actions that are in the requested states: + `--completed`, `--eligible`, `--submitted`, and `--waiting`. *Changed:* * Show `import` lines in Python examples. * Improve the verbose output from `submit`. +* `show status` hides actions with 0 directories by default. Pass `--all` to show all + actions. *Fixed:* From 1807bb62df9b504c1b01528afc9585b1ccbad4b0 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 12:18:03 -0400 Subject: [PATCH 4/7] Add unit tests. --- tests/cli.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/cli.rs b/tests/cli.rs index 08901b6..4bd9dc2 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -146,6 +146,50 @@ fn status() -> Result<(), Box> { Ok(()) } +#[test] +#[parallel] +fn status_waiting() -> Result<(), Box> { + let temp = TempDir::new()?; + let _ = setup_sample_workflow(&temp, 10); + + Command::cargo_bin("row")? + .args(["show", "status"]) + .args(["--cluster", "none"]) + .args(["--waiting"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success() + .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?.not()) + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?); + + Ok(()) +} + +#[test] +#[parallel] +fn status_eligible() -> Result<(), Box> { + let temp = TempDir::new()?; + let _ = setup_sample_workflow(&temp, 10); + + Command::cargo_bin("row")? + .args(["show", "status"]) + .args(["--cluster", "none"]) + .args(["--eligible"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success() + .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?) + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?.not()); + + Ok(()) +} + #[test] #[parallel] fn status_action_selection() -> Result<(), Box> { From 020f83754091c8ff9ed2a3d296d7b37311d069e6 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 12:30:48 -0400 Subject: [PATCH 5/7] More testing. --- tests/cli.rs | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/tests/cli.rs b/tests/cli.rs index 4bd9dc2..0ec30b6 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -44,6 +44,13 @@ name = "two" command = "touch workspace/{directory}/two" products = ["two"] previous_actions = ["one"] + +[[action]] +name = "three" +command = "touch workspace/{directory}/three" +products = ["three"] +[[action.group.include]] +condition = ["/v", "<", 0] "#, )?; @@ -141,7 +148,8 @@ fn status() -> Result<(), Box> { .assert() .success() .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?) - .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?); + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?) + .stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not()); Ok(()) } @@ -163,7 +171,8 @@ fn status_waiting() -> Result<(), Box> { .assert() .success() .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?.not()) - .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?); + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?) + .stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not()); Ok(()) } @@ -185,7 +194,86 @@ fn status_eligible() -> Result<(), Box> { .assert() .success() .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?) - .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?.not()); + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?.not()) + .stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not()); + + Ok(()) +} + +#[test] +#[parallel] +fn status_submitted() -> Result<(), Box> { + let temp = TempDir::new()?; + let _ = setup_sample_workflow(&temp, 10); + + Command::cargo_bin("row")? + .args(["show", "status"]) + .args(["--cluster", "none"]) + .args(["--submitted"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success() + .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?.not()) + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?.not()) + .stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not()); + + Ok(()) +} + +#[test] +#[parallel] +fn status_all() -> Result<(), Box> { + let temp = TempDir::new()?; + let _ = setup_sample_workflow(&temp, 10); + + Command::cargo_bin("row")? + .args(["show", "status"]) + .args(["--cluster", "none"]) + .args(["--all"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success() + .stdout(predicate::str::is_match("(?m)^one +0 +0 +10 +0")?) + .stdout(predicate::str::is_match("(?m)^two +0 +0 +0 +10")?) + .stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?); + + Ok(()) +} + +#[test] +#[parallel] +fn status_completed() -> Result<(), Box> { + let temp = TempDir::new()?; + let _ = setup_sample_workflow(&temp, 10); + + Command::cargo_bin("row")? + .arg("submit") + .args(["--cluster", "none"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success(); + + Command::cargo_bin("row")? + .args(["show", "status"]) + .args(["--cluster", "none"]) + .args(["--completed"]) + .current_dir(temp.path()) + .env_remove("ROW_COLOR") + .env_remove("CLICOLOR") + .env("ROW_HOME", "/not/a/path") + .assert() + .success() + .stdout(predicate::str::is_match("(?m)^one +10 +0 +0 +0")?) + .stdout(predicate::str::is_match("(?m)^two +0 +0 +10 +0")?.not()); Ok(()) } From ce7eb671b78800c603a90979e91b28f5c1ae3146 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 12:38:38 -0400 Subject: [PATCH 6/7] Revise documentation. --- doc/src/row/show/status.md | 6 +++--- src/cli.rs | 6 +++++- src/cli/status.rs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/src/row/show/status.md b/doc/src/row/show/status.md index a817204..3c13f15 100644 --- a/doc/src/row/show/status.md +++ b/doc/src/row/show/status.md @@ -5,7 +5,7 @@ Usage: row show status [OPTIONS] [DIRECTORIES] ``` -`row show status` prints a summary of all directories in the workspace. +`row show status` prints a summary of actions in the workflow. The summary includes the number of directories in each [status](../../guide/concepts/status.md) and an estimate of the remaining cost in either CPU-hours or GPU-hours based on the number of submitted, eligible, and waiting jobs and @@ -30,9 +30,9 @@ echo "dir1" | row show status - Set `--action ` to choose which actions to display by name. By default, **row** shows the status of all actions. `` is a wildcard pattern. -### `-`all` +### `-all` -Show all actions. Even those with 0 directories. +Show all actions. By default, `show status` hides actions with 0 matching directories. ### `--completed` diff --git a/src/cli.rs b/src/cli.rs index 3d95cfd..e575bf9 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -70,7 +70,7 @@ pub enum ColorMode { pub enum ShowCommands { /// Show the current state of the workflow. /// - /// `row show status` prints a summary of all directories in the workspace. + /// `row show status` prints a summary of all actions in the workflow. /// The summary includes the number of directories in each status and an /// estimate of the remaining cost in either CPU-hours or GPU-hours based /// on the number of submitted, eligible, and waiting jobs and the @@ -82,6 +82,10 @@ pub enum ShowCommands { /// /// row show status /// + /// * Show the status of all actions with eligible directories + /// + /// row show status --eligible + /// /// * Show the status of a specific action: /// /// row show status --action=action diff --git a/src/cli/status.rs b/src/cli/status.rs index 3739093..ba47d3c 100644 --- a/src/cli/status.rs +++ b/src/cli/status.rs @@ -46,7 +46,7 @@ pub struct Arguments { #[arg(long, display_order = 0, conflicts_with = "all")] waiting: bool, - /// Show all actions (even those with 0 directories) + /// Show all actions. #[arg(long, display_order = 0)] all: bool, } From b862fb91d4a24102a004bc34b64b57d363a2fde3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Anderson" Date: Tue, 13 Aug 2024 12:40:56 -0400 Subject: [PATCH 7/7] More documentation revisions. --- doc/src/row/show/status.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/row/show/status.md b/doc/src/row/show/status.md index 3c13f15..2dfdf8d 100644 --- a/doc/src/row/show/status.md +++ b/doc/src/row/show/status.md @@ -5,7 +5,7 @@ Usage: row show status [OPTIONS] [DIRECTORIES] ``` -`row show status` prints a summary of actions in the workflow. +`row show status` summarizes actions in the workflow. The summary includes the number of directories in each [status](../../guide/concepts/status.md) and an estimate of the remaining cost in either CPU-hours or GPU-hours based on the number of submitted, eligible, and waiting jobs and @@ -60,7 +60,7 @@ Show actions with *waiting* directories. ```bash row show status ``` -* Show the status of all actions that have eligible directories: +* Show the status of all actions with eligible directories: ```bash row show status --eligible ```