Skip to content

Commit 393077f

Browse files
committed
Add run_json to Execs.
This is a helper to run the process and return a JSON object.
1 parent 3be34cb commit 393077f

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

crates/cargo-test-support/src/lib.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,19 @@ pub fn cargo_exe() -> PathBuf {
439439
*
440440
*/
441441

442+
/// This is the raw output from the process.
443+
///
444+
/// This is similar to `std::process::Output`, however the `status` is
445+
/// translated to the raw `code`. This is necessary because `ProcessError`
446+
/// does not have access to the raw `ExitStatus` because `ProcessError` needs
447+
/// to be serializable (for the Rustc cache), and `ExitStatus` does not
448+
/// provide a constructor.
449+
pub struct RawOutput {
450+
pub code: Option<i32>,
451+
pub stdout: Vec<u8>,
452+
pub stderr: Vec<u8>,
453+
}
454+
442455
#[must_use]
443456
#[derive(Clone)]
444457
pub struct Execs {
@@ -728,6 +741,25 @@ impl Execs {
728741
}
729742
}
730743

744+
/// Runs the process, checks the expected output, and returns the first
745+
/// JSON object on stdout.
746+
#[track_caller]
747+
pub fn run_json(&mut self) -> serde_json::Value {
748+
self.ran = true;
749+
let p = (&self.process_builder).clone().unwrap();
750+
match self.match_process(&p) {
751+
Err(e) => panic!("\n{}", e),
752+
Ok(output) => serde_json::from_slice(&output.stdout).unwrap_or_else(|e| {
753+
panic!(
754+
"\nfailed to parse JSON: {}\n\
755+
output was:\n{}\n",
756+
e,
757+
String::from_utf8_lossy(&output.stdout)
758+
);
759+
}),
760+
}
761+
}
762+
731763
#[track_caller]
732764
pub fn run_output(&mut self, output: &Output) {
733765
self.ran = true;
@@ -763,7 +795,7 @@ impl Execs {
763795
}
764796
}
765797

766-
fn match_process(&self, process: &ProcessBuilder) -> Result<()> {
798+
fn match_process(&self, process: &ProcessBuilder) -> Result<RawOutput> {
767799
println!("running {}", process);
768800
let res = if self.stream_output {
769801
if is_ci() {
@@ -785,7 +817,14 @@ impl Execs {
785817
};
786818

787819
match res {
788-
Ok(out) => self.match_output(&out),
820+
Ok(out) => {
821+
self.match_output(&out)?;
822+
return Ok(RawOutput {
823+
stdout: out.stdout,
824+
stderr: out.stderr,
825+
code: out.status.code(),
826+
});
827+
}
789828
Err(e) => {
790829
if let Some(ProcessError {
791830
stdout: Some(stdout),
@@ -794,10 +833,14 @@ impl Execs {
794833
..
795834
}) = e.downcast_ref::<ProcessError>()
796835
{
797-
return self
798-
.match_status(*code, stdout, stderr)
836+
self.match_status(*code, stdout, stderr)
799837
.and(self.match_stdout(stdout, stderr))
800-
.and(self.match_stderr(stdout, stderr));
838+
.and(self.match_stderr(stdout, stderr))?;
839+
return Ok(RawOutput {
840+
stdout: stdout.to_vec(),
841+
stderr: stderr.to_vec(),
842+
code: *code,
843+
});
801844
}
802845
bail!("could not exec process {}: {:?}", process, e)
803846
}

tests/testsuite/metabuild.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,13 +427,10 @@ fn metabuild_metadata() {
427427
// The metabuild Target is filtered out of the `metadata` results.
428428
let p = basic_project();
429429

430-
let output = p
430+
let meta = p
431431
.cargo("metadata --format-version=1")
432432
.masquerade_as_nightly_cargo()
433-
.exec_with_output()
434-
.expect("cargo metadata failed");
435-
let stdout = str::from_utf8(&output.stdout).unwrap();
436-
let meta: serde_json::Value = serde_json::from_str(stdout).expect("failed to parse json");
433+
.run_json();
437434
let mb_info: Vec<&str> = meta["packages"]
438435
.as_array()
439436
.unwrap()

0 commit comments

Comments
 (0)