Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit output of show status #33

Merged
merged 7 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/src/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:*

Expand Down
26 changes: 25 additions & 1 deletion doc/src/row/show/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` 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
Expand All @@ -30,16 +30,40 @@ echo "dir1" | row show status -
Set `--action <pattern>` to choose which actions to display by name. By default, **row**
shows the status of all actions. `<pattern>` is a wildcard pattern.

### `-all`

Show all actions. By default, `show status` hides actions with 0 matching 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 with eligible directories:
```bash
row show status --eligible
```
* Show the status of a specific action:
```bash
row show status --action=action
Expand Down
6 changes: 5 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/cli/directories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
47 changes: 44 additions & 3 deletions src/cli/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -28,6 +29,26 @@ pub struct Arguments {

/// Select directories to summarize (defaults to all). Use 'status -' to read from stdin.
directories: Vec<PathBuf>,

/// 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.
#[arg(long, display_order = 0)]
all: bool,
}

/// Format a status string for non-terminal outputs.
Expand Down Expand Up @@ -84,6 +105,19 @@ pub fn status<W: Write>(
output: &mut W,
) -> Result<(), Box<dyn Error>> {
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)?;
Expand Down Expand Up @@ -134,9 +168,16 @@ pub fn status<W: Write>(
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 {
Expand Down
134 changes: 133 additions & 1 deletion tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
"#,
)?;

Expand Down Expand Up @@ -141,7 +148,132 @@ fn status() -> Result<(), Box<dyn std::error::Error>> {
.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(())
}

#[test]
#[parallel]
fn status_waiting() -> Result<(), Box<dyn std::error::Error>> {
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")?)
.stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not());

Ok(())
}

#[test]
#[parallel]
fn status_eligible() -> Result<(), Box<dyn std::error::Error>> {
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())
.stdout(predicate::str::is_match("(?m)^three +0 +0 +0 +0")?.not());

Ok(())
}

#[test]
#[parallel]
fn status_submitted() -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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(())
}
Expand Down