Skip to content

Commit

Permalink
Add an ability to read exit code and specific streams
Browse files Browse the repository at this point in the history
Signed-off-by: Danil <deniallugo@gmail.com>
  • Loading branch information
Deniallugo committed Jul 1, 2024
1 parent 7242531 commit 6c5cd5e
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
33 changes: 29 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,16 @@ impl Drop for PushEnv<'_> {
}
}

/// The output of a finished process for specific stream. Another stream will be printed to the corresponds system stream
#[derive(Debug)]
pub struct StreamOutput {
/// The status (exit code) of the process.
pub exit_status: ExitStatus,
/// The data that the process wrote to stdout or stderr.
/// Any trailing newline or carriage return will be trimmed.
pub stream_output: String
}

/// A builder object for constructing a subprocess.
///
/// A [`Cmd`] is usually created with the [`cmd!`] macro. The command exists
Expand Down Expand Up @@ -968,21 +978,33 @@ impl<'a> Cmd<'a> {

/// Run the command and return its stdout as a string. Any trailing newline or carriage return will be trimmed.
pub fn read(&self) -> Result<String> {
self.read_stream(false)
Ok(self.read_stream(false)?.stream_output)
}

/// Run the command and return its stderr as a string. Any trailing newline or carriage return will be trimmed.
/// Run the command and return its stderr as a string.
pub fn read_stderr(&self) -> Result<String> {
Ok(self.read_stream(true)?.stream_output)
}

/// Run the command and return its stderr as a string and exit status.
/// Any trailing newline or carriage return will be trimmed.
pub fn read_stderr_output(&self) -> Result<StreamOutput> {
self.read_stream(true)
}

/// Run the command and return its stdout as a string and exit status.
/// Any trailing newline or carriage return will be trimmed.
pub fn read_stdout_output(&self) -> Result<StreamOutput> {
self.read_stream(false)
}

/// Run the command and return its output.
pub fn output(&self) -> Result<Output> {
self.output_impl(true, true)
}
// endregion:running

fn read_stream(&self, read_stderr: bool) -> Result<String> {
fn read_stream(&self, read_stderr: bool) -> Result<StreamOutput> {
let read_stdout = !read_stderr;
let output = self.output_impl(read_stdout, read_stderr)?;
self.check_status(output.status)?;
Expand All @@ -997,7 +1019,10 @@ impl<'a> Cmd<'a> {
stream.pop();
}

Ok(stream)
Ok(StreamOutput{
exit_status: output.status,
stream_output: stream,
})
}

fn output_impl(&self, read_stdout: bool, read_stderr: bool) -> Result<Output> {
Expand Down
26 changes: 26 additions & 0 deletions tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ fn multiline() {
assert_eq!(output, "hello");
}


#[test]
fn read_with_exit_status() {
let sh = setup();
let output = cmd!(
sh,
"
xecho hello
"
)
.read_stdout_output()
.unwrap();
assert_eq!(output.stream_output, "hello");
assert!(output.exit_status.success());
}

#[test]
fn interpolation() {
let sh = setup();
Expand Down Expand Up @@ -185,6 +201,16 @@ fn read_stderr() {
assert!(output.contains("snafu"));
}

#[test]
fn read_stderr_with_exit_code() {
let sh = setup();

let output = cmd!(sh, "xecho -f -e snafu").ignore_status().read_stderr_output().unwrap();
assert!(output.stream_output.contains("snafu"));
assert!(!output.exit_status.success())
}


#[test]
fn unknown_command() {
let sh = setup();
Expand Down

0 comments on commit 6c5cd5e

Please sign in to comment.