-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add convenience API to std::process::Command #89004
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1029,6 +1029,84 @@ impl Command { | |
pub fn get_current_dir(&self) -> Option<&Path> { | ||
self.inner.get_current_dir() | ||
} | ||
|
||
/// Convenience wrapper around [`Command::status`]. | ||
/// | ||
/// Returns an error if the command exited with non-zero status. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```no_run | ||
/// # #![feature(command_easy_api)] | ||
/// use std::process::Command; | ||
/// | ||
/// let res = Command::new("cat") | ||
/// .arg("no-such-file.txt") | ||
/// .run(); | ||
/// assert!(res.is_err()); | ||
/// ``` | ||
#[unstable(feature = "command_easy_api", issue = "none")] | ||
pub fn run(&mut self) -> io::Result<()> { | ||
let status = self.status()?; | ||
self.check_status(status) | ||
} | ||
|
||
/// Convenience wrapper around [`Command::output`] to get the contents of | ||
/// standard output as [`String`]. | ||
/// | ||
/// The final newline (`\n`) is stripped from the output. Unlike | ||
/// [`Command::output`], `stderr` is inherited by default. | ||
/// | ||
/// Returns an error if the command exited with non-zero status or if the | ||
/// output was not valid UTF-8. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```no_run | ||
/// # #![feature(command_easy_api)] | ||
/// use std::process::Command; | ||
/// let output = Command::new("git") | ||
/// .args(["rev-parse", "--short", "1.0.0"]) | ||
/// .read_stdout()?; | ||
/// | ||
/// assert_eq!(output, "55bd4f8ff2b"); | ||
/// # Ok::<(), std::io::Error>(()) | ||
/// ``` | ||
#[unstable(feature = "command_easy_api", issue = "none")] | ||
pub fn read_stdout(&mut self) -> io::Result<String> { | ||
// FIXME: This shouldn't override the stderr to inherit, and merely use | ||
// a default. | ||
self.stderr(Stdio::inherit()); | ||
|
||
let output = self.output()?; | ||
self.check_status(output.status)?; | ||
let mut stdout = output.stdout; | ||
if stdout.last() == Some(&b'\n') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe use strip.suffix instead? |
||
stdout.pop(); | ||
} | ||
String::from_utf8(stdout).map_err(|_| { | ||
io::Error::new_const( | ||
io::ErrorKind::InvalidData, | ||
format!("command {:?} produced non-UTF-8 output"), | ||
) | ||
}) | ||
} | ||
|
||
fn check_status(&self, status: ExitStatus) -> io::Result<()> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if this would be usefully |
||
if status.success() { | ||
Ok(()) | ||
} else { | ||
Err(io::Error::new_const( | ||
io::ErrorKind::Uncategorized, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think |
||
match status.code() { | ||
Some(code) => { | ||
format!("command {:?} exited with non zero status ({})", self, code) | ||
} | ||
None => format!("command {:?} was terminated", self), | ||
}, | ||
)) | ||
} | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bikeshed: I suggest
get_stdout
for the name? To me,read_stdout
fails to suggest that it also waits for termination.