Skip to content

Commit f047661

Browse files
committed
improve output
1 parent 1a74d73 commit f047661

File tree

8 files changed

+124
-87
lines changed

8 files changed

+124
-87
lines changed

.cargo/config.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
linker = "aarch64-linux-gnu-gcc"
33

44
[alias]
5-
regress = "run -p svd2rust-regress --"
5+
regress = "run -p svd2rust-regress --"

.github/workflows/diff.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818

1919
- name: Cache
2020
uses: Swatinem/rust-cache@v2
21+
with:
22+
shared-key: "diff"
2123

2224
- run: cargo regress ci
2325
id: regress-ci
@@ -41,13 +43,14 @@ jobs:
4143
- name: Cache
4244
uses: Swatinem/rust-cache@v2
4345
with:
44-
cache-on-failure: true
46+
shared-key: "diff"
4547

4648
- uses: taiki-e/install-action@v2
4749
if: matrix.needs_semver_checks
4850
with:
4951
tool: cargo-semver-checks
5052

53+
# if a new line is added here, make sure to update the `summary` job to reference the new step index
5154
- uses: taiki-e/install-action@v2
5255
with:
5356
tool: git-delta
@@ -59,8 +62,8 @@ jobs:
5962
GIT_PAGER: delta --hunk-header-style omit
6063
summary:
6164
runs-on: ubuntu-latest
62-
needs: [diff]
63-
if: always()
65+
needs: [diff, generate]
66+
if: always() && needs.generate.outputs.diffs != '{}' && needs.generate.outputs.diffs != '[]' && needs.generate.outputs.diffs != ''
6467
steps:
6568
- uses: actions/checkout@v4
6669

ci/svd2rust-regress/src/command.rs

+11-14
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub trait CommandExt {
77
fn run(&mut self, hide: bool) -> Result<(), anyhow::Error>;
88

99
#[track_caller]
10-
fn get_output(&mut self) -> Result<std::process::Output, anyhow::Error>;
10+
fn get_output(&mut self, can_fail: bool) -> Result<std::process::Output, anyhow::Error>;
1111

1212
#[track_caller]
1313
fn get_output_string(&mut self) -> Result<String, anyhow::Error>;
@@ -33,17 +33,11 @@ impl CommandExt for Command {
3333
}
3434

3535
#[track_caller]
36-
fn get_output(&mut self) -> Result<std::process::Output, anyhow::Error> {
37-
let output = self.output().with_context(|| {
38-
format!(
39-
"command `{}{}` couldn't be run",
40-
self.get_current_dir()
41-
.map(|d| format!("{} ", d.display()))
42-
.unwrap_or_default(),
43-
self.display()
44-
)
45-
})?;
46-
if output.status.success() {
36+
fn get_output(&mut self, can_fail: bool) -> Result<std::process::Output, anyhow::Error> {
37+
let output = self
38+
.output()
39+
.with_context(|| format!("command `{}` couldn't be run", self.display()))?;
40+
if output.status.success() || can_fail {
4741
Ok(output)
4842
} else {
4943
anyhow::bail!(
@@ -57,12 +51,15 @@ impl CommandExt for Command {
5751

5852
#[track_caller]
5953
fn get_output_string(&mut self) -> Result<String, anyhow::Error> {
60-
String::from_utf8(self.get_output()?.stdout).map_err(Into::into)
54+
String::from_utf8(self.get_output(true)?.stdout).map_err(Into::into)
6155
}
6256

6357
fn display(&self) -> String {
6458
format!(
65-
"{} {}",
59+
"{}{} {}",
60+
self.get_current_dir()
61+
.map(|d| format!("{} ", d.display()))
62+
.unwrap_or_default(),
6663
self.get_program().to_string_lossy(),
6764
self.get_args()
6865
.map(|s| s.to_string_lossy())

ci/svd2rust-regress/src/diff.rs

+35-17
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ pub struct Diffing {
1313
/// Change the base version by starting with `@` followed by the source.
1414
///
1515
/// supports `@pr` for current pr, `@master` for latest master build, or a version tag like `@v0.30.0`
16-
#[clap(global = true, long, alias = "base")]
16+
#[clap(global = true, long = "baseline", alias = "base")]
1717
pub baseline: Option<String>,
1818

19-
#[clap(global = true, long, alias = "head")]
19+
#[clap(global = true, long = "current", alias = "head")]
2020
pub current: Option<String>,
2121

2222
/// Enable formatting with `rustfmt`
@@ -72,6 +72,17 @@ pub struct Diffing {
7272
pub enum DiffingMode {
7373
Semver,
7474
Diff,
75+
Pr,
76+
}
77+
78+
impl DiffingMode {
79+
/// Returns `true` if the diffing mode is [`Pr`].
80+
///
81+
/// [`Pr`]: DiffingMode::Pr
82+
#[must_use]
83+
pub fn is_pr(&self) -> bool {
84+
matches!(self, Self::Pr)
85+
}
7586
}
7687

7788
type Source<'s> = Option<&'s str>;
@@ -83,7 +94,7 @@ impl Diffing {
8394
.make_case(opts)
8495
.with_context(|| "couldn't setup test case")?;
8596
match self.sub.unwrap_or(DiffingMode::Diff) {
86-
DiffingMode::Diff => {
97+
DiffingMode::Diff | DiffingMode::Pr => {
8798
let mut command;
8899
if let Some(pager) = &self.pager {
89100
if self.use_pager_directly {
@@ -156,27 +167,34 @@ impl Diffing {
156167
}
157168
})
158169
.collect::<Vec<_>>();
159-
if tests.len() != 1 {
160-
let error = anyhow::anyhow!("diff requires exactly one test case");
161-
let len = tests.len();
162-
return Err(match len {
163-
0 => error.context("matched no tests"),
164-
10.. => error.context(format!("matched multiple ({len}) tests")),
165-
_ => error.context(format!(
166-
"matched multiple ({len}) tests\n{:?}",
167-
tests.iter().map(|t| t.name()).collect::<Vec<_>>()
168-
)),
169-
});
170-
}
170+
let test = match (tests.len(), self.sub) {
171+
(1, _) => tests[0],
172+
(1.., Some(DiffingMode::Pr)) => tests
173+
.iter()
174+
.find(|t| t.chip == "STM32F401")
175+
.unwrap_or(&tests[0]),
176+
_ => {
177+
let error = anyhow::anyhow!("diff requires exactly one test case");
178+
let len = tests.len();
179+
return Err(match len {
180+
0 => error.context("matched no tests"),
181+
10.. => error.context(format!("matched multiple ({len}) tests")),
182+
_ => error.context(format!(
183+
"matched multiple ({len}) tests\n{:?}",
184+
tests.iter().map(|t| t.name()).collect::<Vec<_>>()
185+
)),
186+
});
187+
}
188+
};
171189

172-
let baseline = tests[0]
190+
let baseline = test
173191
.setup_case(
174192
&opts.output_dir.join("baseline"),
175193
&baseline_bin,
176194
baseline_cmd,
177195
)
178196
.with_context(|| "couldn't create head")?;
179-
let current = tests[0]
197+
let current = test
180198
.setup_case(&opts.output_dir.join("current"), &current_bin, current_cmd)
181199
.with_context(|| "couldn't create base")?;
182200

ci/svd2rust-regress/src/github.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ pub fn get_release_binary_artifact(
148148
Command::new("gzip")
149149
.arg("-d")
150150
.arg(output_dir.join(artifact))
151-
.get_output()?;
151+
.get_output(false)?;
152152
}
153153
}
154154
_ => {

ci/svd2rust-regress/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ fn main() -> Result<(), anyhow::Error> {
348348
tracing_subscriber::fmt()
349349
.pretty()
350350
.with_target(false)
351+
.with_writer(std::io::stderr)
351352
.with_env_filter(
352353
tracing_subscriber::EnvFilter::builder()
353354
.with_default_directive(tracing::level_filters::LevelFilter::INFO.into())

ci/svd2rust-regress/src/svd_test.rs

+68-50
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::io::prelude::*;
66
use std::path::PathBuf;
77
use std::process::{Command, Output};
88
use std::{
9+
fmt::Write as _,
910
fs::{self, File, OpenOptions},
1011
path::Path,
1112
};
@@ -67,7 +68,7 @@ impl std::fmt::Debug for ProcessFailed {
6768

6869
trait CommandHelper {
6970
fn capture_outputs(
70-
&self,
71+
&mut self,
7172
cant_fail: bool,
7273
name: &str,
7374
stdout: Option<&PathBuf>,
@@ -76,26 +77,48 @@ trait CommandHelper {
7677
) -> Result<(), TestError>;
7778
}
7879

79-
impl CommandHelper for Output {
80+
impl CommandHelper for Command {
81+
#[tracing::instrument(skip_all, fields(stdout = tracing::field::Empty, stderr = tracing::field::Empty))]
8082
fn capture_outputs(
81-
&self,
83+
&mut self,
8284
cant_fail: bool,
8385
name: &str,
8486
stdout: Option<&PathBuf>,
8587
stderr: Option<&PathBuf>,
8688
previous_processes_stderr: &[PathBuf],
8789
) -> Result<(), TestError> {
90+
let output = self.get_output(true)?;
91+
let out_payload = String::from_utf8_lossy(&output.stdout);
8892
if let Some(out) = stdout {
89-
let out_payload = String::from_utf8_lossy(&self.stdout);
9093
file_helper(&out_payload, out)?;
9194
};
9295

96+
let err_payload = String::from_utf8_lossy(&output.stderr);
9397
if let Some(err) = stderr {
94-
let err_payload = String::from_utf8_lossy(&self.stderr);
9598
file_helper(&err_payload, err)?;
9699
};
97-
98-
if cant_fail && !self.status.success() {
100+
if cant_fail && !output.status.success() {
101+
let span = tracing::Span::current();
102+
let mut message = format!("Process failed: {}", self.display());
103+
if !out_payload.trim().is_empty() {
104+
span.record(
105+
"stdout",
106+
tracing::field::display(
107+
stdout.map(|p| p.display().to_string()).unwrap_or_default(),
108+
),
109+
);
110+
write!(message, "\nstdout: \n{}", out_payload).unwrap();
111+
}
112+
if !err_payload.trim().is_empty() {
113+
span.record(
114+
"stderr",
115+
tracing::field::display(
116+
stderr.map(|p| p.display().to_string()).unwrap_or_default(),
117+
),
118+
);
119+
write!(message, "\nstderr: \n{}", err_payload).unwrap();
120+
}
121+
tracing::error!(message=%message);
99122
return Err(ProcessFailed {
100123
command: name.into(),
101124
stdout: stdout.cloned(),
@@ -125,18 +148,17 @@ impl TestCase {
125148
.with_context(|| anyhow!("when setting up case for {}", self.name()))?;
126149
// Run `cargo check`, capturing stderr to a log file
127150
let cargo_check_err_file = path_helper_base(&chip_dir, &["cargo-check.err.log"]);
128-
let output = Command::new("cargo")
151+
Command::new("cargo")
129152
.arg("check")
130153
.current_dir(&chip_dir)
131-
.output()
154+
.capture_outputs(
155+
true,
156+
"cargo check",
157+
None,
158+
Some(&cargo_check_err_file),
159+
&process_stderr_paths,
160+
)
132161
.with_context(|| "failed to check")?;
133-
output.capture_outputs(
134-
true,
135-
"cargo check",
136-
None,
137-
Some(&cargo_check_err_file),
138-
&process_stderr_paths,
139-
)?;
140162
process_stderr_paths.push(cargo_check_err_file);
141163
Ok(if opts.verbose > 1 {
142164
Some(process_stderr_paths)
@@ -180,9 +202,8 @@ impl TestCase {
180202
.arg("--vcs")
181203
.arg("none")
182204
.arg(&chip_dir)
183-
.output()
184-
.with_context(|| "Failed to cargo init")?
185-
.capture_outputs(true, "cargo init", None, None, &[])?;
205+
.capture_outputs(true, "cargo init", None, None, &[])
206+
.with_context(|| "Failed to cargo init")?;
186207
let svd_toml = path_helper_base(&chip_dir, &["Cargo.toml"]);
187208
let mut file = OpenOptions::new()
188209
.write(true)
@@ -242,23 +263,22 @@ impl TestCase {
242263
if let Some(command) = command {
243264
svd2rust_bin.arg(command);
244265
}
245-
let output = svd2rust_bin
266+
svd2rust_bin
246267
.args(["-i", &chip_svd])
247268
.args(["--target", target])
248269
.current_dir(&chip_dir)
249-
.get_output()?;
250-
output.capture_outputs(
251-
true,
252-
"svd2rust",
253-
Some(&lib_rs_file).filter(|_| {
254-
!matches!(
255-
self.arch,
256-
Target::CortexM | Target::Msp430 | Target::XtensaLX
257-
)
258-
}),
259-
Some(&svd2rust_err_file),
260-
&[],
261-
)?;
270+
.capture_outputs(
271+
true,
272+
"svd2rust",
273+
Some(&lib_rs_file).filter(|_| {
274+
!matches!(
275+
self.arch,
276+
Target::CortexM | Target::Msp430 | Target::XtensaLX
277+
)
278+
}),
279+
Some(&svd2rust_err_file),
280+
&[],
281+
)?;
262282
process_stderr_paths.push(svd2rust_err_file);
263283
match self.arch {
264284
Target::CortexM | Target::Mips | Target::Msp430 | Target::XtensaLX => {
@@ -287,20 +307,19 @@ impl TestCase {
287307
let new_lib_rs_file = path_helper_base(&chip_dir, &["lib.rs"]);
288308
std::fs::rename(lib_rs_file, &new_lib_rs_file)
289309
.with_context(|| "While moving lib.rs file")?;
290-
let output = Command::new(form_bin_path)
310+
Command::new(form_bin_path)
291311
.arg("--input")
292312
.arg(&new_lib_rs_file)
293313
.arg("--outdir")
294314
.arg(&src_dir)
295-
.output()
315+
.capture_outputs(
316+
true,
317+
"form",
318+
None,
319+
Some(&form_err_file),
320+
&process_stderr_paths,
321+
)
296322
.with_context(|| "failed to form")?;
297-
output.capture_outputs(
298-
true,
299-
"form",
300-
None,
301-
Some(&form_err_file),
302-
&process_stderr_paths,
303-
)?;
304323
std::fs::remove_file(&new_lib_rs_file)
305324
.with_context(|| "While removing lib.rs file after form")?;
306325
}
@@ -322,15 +341,14 @@ impl TestCase {
322341
let output = Command::new(rustfmt_bin_path)
323342
.arg(entry)
324343
.args(["--edition", "2021"])
325-
.output()
344+
.capture_outputs(
345+
false,
346+
"rustfmt",
347+
None,
348+
Some(&rustfmt_err_file),
349+
&process_stderr_paths,
350+
)
326351
.with_context(|| "failed to format")?;
327-
output.capture_outputs(
328-
false,
329-
"rustfmt",
330-
None,
331-
Some(&rustfmt_err_file),
332-
&process_stderr_paths,
333-
)?;
334352
}
335353

336354
process_stderr_paths.push(rustfmt_err_file);

0 commit comments

Comments
 (0)