Skip to content

Commit

Permalink
feat: --output=collect
Browse files Browse the repository at this point in the history
  • Loading branch information
EdJoPaTo committed Aug 24, 2024
1 parent 64e16a6 commit bf79f2d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add `--path-style` with `base-dir` (default), `canonical`, `dirname`, `short` and `working-dir`. Replacement for `--canonical` and `--relative`.
- Add options for command output handling:
- `--no-header`
- `--output` with `inherit`, `line-prefix` and `null`
- `--output` with `inherit`, `line-prefix`, `collect` and `null`
- `--result` with `always`, `never` and `non-zero`
- `--line-prefix` as a shortcut for `--no-header --output=line-prefix`
- `--only-result` as a shortcut for `--no-header --output=null`
Expand Down
2 changes: 2 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ pub enum CommandOutput {
Inherit,
/// Print the output prefixed per line with the directory of the process it outputted.
LinePrefix,
/// Collect the output and print it once the command finishes.
Collect,
/// Similar to attaching `/dev/null` to stdout / stderr.
Null,
}
Expand Down
9 changes: 8 additions & 1 deletion src/command.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ffi::OsString;
use std::io::Write;
use std::path::Path;
use std::process::{Command as OsCommand, ExitStatus, Stdio};
use std::process::{Command as OsCommand, ExitStatus, Output, Stdio};
use std::thread::Scope;
use std::time::{Duration, Instant};

Expand Down Expand Up @@ -85,6 +85,13 @@ impl Command {

(output.status, took)
}

pub fn output(mut self) -> (Output, Duration) {
let start = Instant::now();
let output = self.0.output().unwrap_or_else(|err| self.failed(&err));
let took = start.elapsed();
(output, took)
}
}

fn scope_spawn<'scope, F>(scope: &'scope Scope<'scope, '_>, name: &str, func: F)
Expand Down
30 changes: 30 additions & 0 deletions src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,36 @@ impl<'a> Harness<'a> {
format!("{:width$} ", self.path())
}

pub fn collect(&self, stdout: &[u8], stderr: &[u8]) {
let any_output = !stdout.is_empty() || !stderr.is_empty();

let need_linesplit = self
.config
.need_linesplit
.swap(any_output, Ordering::Relaxed);
if need_linesplit || any_output {
println!();
}
if let Some(last) = stdout.last() {
if !self.config.no_header {
println!("{} Stdout:", self.path());
}
std::io::stdout().write_all(stdout).unwrap();
if *last != b'\n' {
std::io::stdout().write_all(b"\n").unwrap();
}
}
if let Some(last) = stderr.last() {
if !self.config.no_header {
eprintln!("{} Stderr:", self.path());
}
std::io::stderr().write_all(stderr).unwrap();
if *last != b'\n' {
std::io::stderr().write_all(b"\n").unwrap();
}
}
}

pub fn result(&self, took: Duration, status: ExitStatus) {
if self.config.result.print(status.success()) {
let took = DDuration(took);
Expand Down
24 changes: 18 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,27 @@ fn main() {
commandpool(threads, &rx, |path| {
let command = command::Command::new(&matches.command, &path);
let harness = harness.create(&path);
let (status, took) = match matches.output {
match matches.output {
CommandOutput::Inherit => {
harness.inherit_header();
command.inherit()
let (status, took) = command.inherit();
harness.result(took, status);
}
CommandOutput::LinePrefix => command.lineprefixed(&harness.line_prefix()),
CommandOutput::Null => command.null(),
};
harness.result(took, status);
CommandOutput::LinePrefix => {
let (status, took) = command.lineprefixed(&harness.line_prefix());
harness.result(took, status);
}
CommandOutput::Collect => {
let (output, took) = command.output();
let _stdout = std::io::stdout().lock();
harness.collect(&output.stdout, &output.stderr);
harness.result(took, output.status);
}
CommandOutput::Null => {
let (status, took) = command.null();
harness.result(took, status);
}
}
});
}
}
Expand Down

0 comments on commit bf79f2d

Please sign in to comment.