Skip to content

Commit 061329d

Browse files
authored
Merge pull request #806 from rust-embedded/regress-improvements
regress improvements
2 parents 121ca49 + 57f6bbe commit 061329d

File tree

9 files changed

+158
-43
lines changed

9 files changed

+158
-43
lines changed

.github/workflows/diff.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ on:
55

66
jobs:
77
generate:
8+
name: |
9+
Generate matrix. ${{ github.event.comment.user.name }}: ${{ github.event.comment.author_association}}
810
runs-on: ubuntu-latest
911
outputs:
1012
diffs: ${{ steps.regress-ci.outputs.diffs }}
@@ -25,7 +27,7 @@ jobs:
2527
id: regress-ci
2628
env:
2729
GITHUB_COMMENT: ${{ github.event.comment.body }}
28-
GITHUB_COMMENT_PR: ${{ github.event.comment.issue_url }}
30+
GITHUB_COMMENT_PR: ${{ github.event.issue.number }}
2931
diff:
3032
runs-on: ubuntu-latest
3133
needs: [generate]
@@ -50,16 +52,17 @@ jobs:
5052
with:
5153
tool: cargo-semver-checks
5254

53-
# if a new line is added here, make sure to update the `summary` job to reference the new step index
5455
- uses: taiki-e/install-action@v2
5556
with:
5657
tool: git-delta
5758

58-
- run: cargo regress diff --use-pager-directly ${{ matrix.command }}
59+
# if a new line is added here, make sure to update the `summary` job to reference the new step index
60+
- run: cargo regress diff ${{ matrix.command }}
61+
- run: cargo regress diff ${{ matrix.command }}
5962
env:
6063
GH_TOKEN: ${{ github.token }}
6164
GITHUB_PR: ${{ matrix.pr }}
62-
GIT_PAGER: delta --hunk-header-style omit
65+
GIT_PAGER: delta --raw
6366
summary:
6467
runs-on: ubuntu-latest
6568
needs: [diff, generate]
@@ -68,9 +71,8 @@ jobs:
6871
- uses: actions/checkout@v4
6972

7073
- run: |
71-
PR_ID=$(echo "${{ github.event.comment.issue_url }}" | grep -o '[0-9]\+$')
7274
gh run view ${{ github.run_id }} --json jobs | \
73-
jq -r '"Diff for [comment]("+$comment+")\n\n" + ([.jobs[] | select(.name | startswith("diff")) | "- [" + (.name | capture("\\((?<name>[^,]+),.*") | .name) + "](" + .url + "?pr=" + $pr_id + "#step:7:45)"] | join("\n"))' --arg pr_id "$PR_ID" --arg comment "${{ github.event.comment.url }}"| \
74-
gh pr comment "$PR_ID" --body "$(< /dev/stdin)"
75+
jq -r '"Diff for [comment]("+$comment+")\n\n" + ([.jobs[] | select(.name | startswith("diff")) | "- [" + (.name | capture("\\((?<name>[^,]+),.*") | .name) + "](" + .url + "?pr=" + $pr_id + "#step:7:47)"] | join("\n"))' --arg pr_id "${{ github.event.issue.number }}" --arg comment "${{ github.event.comment.url }}"| \
76+
gh pr comment "${{ github.event.issue.number }}" --body "$(< /dev/stdin)"
7577
env:
7678
GH_TOKEN: ${{ github.token }}

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,10 @@ features = ["full","extra-traits"]
7373
[workspace]
7474
members = ["ci/svd2rust-regress"]
7575
default-members = ["."]
76-
exclude = ["output"]
76+
exclude = [
77+
"output",
78+
# workaround for https://github.com/rust-lang/cargo/pull/12779, doesn't work for output though
79+
# see https://github.com/rust-lang/cargo/issues/6009#issuecomment-1925445245
80+
"output/baseline/**",
81+
"output/current/**"
82+
]

ci/svd2rust-regress/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ wildmatch = "2.1.1"
2020
which = "5.0.0"
2121
tracing = "0.1.40"
2222
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "fmt"] }
23+
shell-words = "1.1"

ci/svd2rust-regress/src/ci.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub struct Ci {
1111
#[clap(env = "GITHUB_COMMENT")]
1212
pub comment: String,
1313
#[clap(env = "GITHUB_COMMENT_PR")]
14-
pub comment_pr: String,
14+
pub comment_pr: usize,
1515
}
1616

1717
#[derive(serde::Serialize)]
@@ -32,7 +32,7 @@ impl Ci {
3232
diffs.push(Diff {
3333
needs_semver_checks: command.contains("semver"),
3434
command: command.to_owned(),
35-
pr: self.comment_pr.split('/').last().unwrap().parse()?,
35+
pr: self.comment_pr,
3636
});
3737
}
3838
let json = serde_json::to_string(&diffs)?;

ci/svd2rust-regress/src/diff.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ use crate::Opts;
88
#[derive(clap::Parser, Debug)]
99
#[clap(name = "diff")]
1010
pub struct Diffing {
11-
/// The base version of svd2rust to use and the command input, defaults to latest master build
11+
/// The base version of svd2rust to use and the command input, defaults to latest master build: `@master`
1212
///
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`
1616
#[clap(global = true, long = "baseline", alias = "base")]
1717
pub baseline: Option<String>,
1818

19+
/// The head version of svd2rust to use and the command input, defaults to current pr: `@pr`
1920
#[clap(global = true, long = "current", alias = "head")]
2021
pub current: Option<String>,
2122

@@ -27,14 +28,12 @@ pub struct Diffing {
2728
#[clap(global = true, long)]
2829
pub form_split: bool,
2930

30-
#[clap(subcommand)]
31-
pub sub: Option<DiffingMode>,
32-
3331
#[clap(global = true, long, short = 'c')]
3432
pub chip: Vec<String>,
3533

3634
/// Filter by manufacturer, case sensitive, may be combined with other filters
3735
#[clap(
36+
global = true,
3837
short = 'm',
3938
long = "manufacturer",
4039
ignore_case = true,
@@ -44,6 +43,7 @@ pub struct Diffing {
4443

4544
/// Filter by architecture, case sensitive, may be combined with other filters
4645
#[clap(
46+
global = true,
4747
short = 'a',
4848
long = "architecture",
4949
ignore_case = true,
@@ -54,20 +54,24 @@ pub struct Diffing {
5454
#[clap(global = true, long)]
5555
pub diff_folder: Option<PathBuf>,
5656

57-
#[clap(hide = true, env = "GITHUB_PR")]
57+
/// The pr number to use for `@pr`. If not set will try to get the current pr with the command `gh pr`
58+
#[clap(env = "GITHUB_PR", global = true, long)]
5859
pub pr: Option<usize>,
5960

60-
#[clap(env = "GIT_PAGER", long)]
61+
#[clap(env = "GIT_PAGER", global = true, long)]
6162
pub pager: Option<String>,
6263

6364
/// if set, will use pager directly instead of `git -c core.pager`
64-
#[clap(long, short = 'P')]
65+
#[clap(global = true, long, short = 'P')]
6566
pub use_pager_directly: bool,
6667

6768
/// URL for SVD to download
6869
#[clap(global = true, long)]
6970
pub url: Option<String>,
7071

72+
#[clap(subcommand)]
73+
pub sub: Option<DiffingMode>,
74+
7175
#[clap(last = true)]
7276
pub last_args: Option<String>,
7377
}

ci/svd2rust-regress/src/main.rs

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn get_cargo_workspace() -> &'static std::path::Path {
5050
}
5151

5252
#[derive(clap::Parser, Debug)]
53-
pub struct TestOpts {
53+
pub struct TestAll {
5454
/// Run a long test (it's very long)
5555
#[clap(short = 'l', long)]
5656
pub long_test: bool,
@@ -59,7 +59,7 @@ pub struct TestOpts {
5959
#[clap(short = 'c', long)]
6060
pub chip: Vec<String>,
6161

62-
/// Filter by manufacturer, case sensitive, may be combined with other filters
62+
/// Filter by manufacturer, may be combined with other filters
6363
#[clap(
6464
short = 'm',
6565
long = "manufacturer",
@@ -68,7 +68,7 @@ pub struct TestOpts {
6868
)]
6969
pub mfgr: Option<String>,
7070

71-
/// Filter by architecture, case sensitive, may be combined with other filters
71+
/// Filter by architecture, may be combined with other filters
7272
#[clap(
7373
short = 'a',
7474
long = "architecture",
@@ -104,7 +104,97 @@ pub struct TestOpts {
104104
// TODO: Compile svd2rust?
105105
}
106106

107-
impl TestOpts {
107+
#[derive(clap::Parser, Debug)]
108+
// TODO: Replace with https://github.com/clap-rs/clap/issues/2621 when available
109+
#[group(id = "svd_source", required = true)]
110+
pub struct Test {
111+
/// Enable formatting with `rustfmt`
112+
#[arg(short = 'f', long)]
113+
pub format: bool,
114+
115+
#[arg(long)]
116+
/// Enable splitting `lib.rs` with `form`
117+
pub form_lib: bool,
118+
119+
#[arg(
120+
short = 'm',
121+
long = "manufacturer",
122+
ignore_case = true,
123+
value_parser = manufacturers(),
124+
)]
125+
/// Manufacturer
126+
pub mfgr: Option<String>,
127+
#[arg(
128+
short = 'a',
129+
long = "architecture",
130+
ignore_case = true,
131+
value_parser = architectures(),
132+
)]
133+
/// Architecture
134+
pub arch: Option<String>,
135+
#[arg(long, group = "svd_source", conflicts_with_all = ["svd_file"], requires = "arch")]
136+
/// URL to SVD file to test
137+
pub url: Option<String>,
138+
#[arg(long = "svd", group = "svd_source")]
139+
/// Path to SVD file to test
140+
pub svd_file: Option<PathBuf>,
141+
#[arg(long, group = "svd_source")]
142+
/// Chip to use, use `--url` or `--svd-file` for another way to specify svd
143+
pub chip: Option<String>,
144+
145+
/// Path to an `svd2rust` binary, relative or absolute.
146+
/// Defaults to `target/release/svd2rust[.exe]` of this repository
147+
/// (which must be already built)
148+
#[clap(short = 'p', long = "svd2rust-path", default_value = default_svd2rust())]
149+
pub current_bin_path: PathBuf,
150+
#[clap(last = true)]
151+
pub command: Option<String>,
152+
}
153+
154+
impl Test {
155+
fn run(&self, opts: &Opts) -> Result<(), anyhow::Error> {
156+
match self {
157+
Self { url: Some(url), .. } => {}
158+
Self {
159+
svd_file: Some(svd_file),
160+
..
161+
} => {}
162+
Self {
163+
chip: Some(chip), ..
164+
} => {}
165+
_ => unreachable!("clap should not allow this"),
166+
}
167+
let test = if let (Some(url), Some(arch)) = (&self.url, &self.arch) {
168+
tests::TestCase {
169+
arch: svd2rust::Target::parse(&arch)?,
170+
mfgr: tests::Manufacturer::Unknown,
171+
chip: self
172+
.chip
173+
.as_deref()
174+
.or_else(|| url.rsplit('/').next().and_then(|s| s.strip_suffix(".svd")))
175+
.ok_or_else(|| {
176+
anyhow::anyhow!(
177+
"could not figure out chip name, specify with `--chip <name>`",
178+
)
179+
})?
180+
.to_owned(),
181+
svd_url: Some(url.clone()),
182+
should_pass: true,
183+
run_when: tests::RunWhen::default(),
184+
}
185+
} else {
186+
tests::tests(Some(&opts.test_cases))?
187+
.iter()
188+
.find(|t| self.chip.iter().any(|c| WildMatch::new(c).matches(&t.chip)))
189+
.ok_or_else(|| anyhow::anyhow!("no test found for chip"))?
190+
.to_owned()
191+
};
192+
test.test(opts, &self.current_bin_path, self.command.as_deref())?;
193+
Ok(())
194+
}
195+
}
196+
197+
impl TestAll {
108198
fn run(&self, opt: &Opts) -> Result<(), anyhow::Error> {
109199
let tests = tests::tests(Some(&opt.test_cases))?
110200
.iter()
@@ -152,7 +242,7 @@ impl TestOpts {
152242
tests.par_iter().for_each(|t| {
153243
let start = Instant::now();
154244

155-
match t.test(opt, self) {
245+
match t.test(opt, &self.current_bin_path, self.command.as_deref()) {
156246
Ok(s) => {
157247
if let Some(stderrs) = s {
158248
let mut buf = String::new();
@@ -217,7 +307,8 @@ impl TestOpts {
217307
#[derive(clap::Subcommand, Debug)]
218308
pub enum Subcommand {
219309
Diff(Diffing),
220-
Tests(TestOpts),
310+
Tests(TestAll),
311+
Test(Test),
221312
Ci(Ci),
222313
}
223314

@@ -256,15 +347,17 @@ pub struct Opts {
256347
impl Opts {
257348
const fn use_rustfmt(&self) -> bool {
258349
match self.subcommand {
259-
Subcommand::Tests(TestOpts { format, .. })
350+
Subcommand::Tests(TestAll { format, .. })
351+
| Subcommand::Test(Test { format, .. })
260352
| Subcommand::Diff(Diffing { format, .. })
261353
| Subcommand::Ci(Ci { format, .. }) => format,
262354
}
263355
}
264356

265357
const fn use_form(&self) -> bool {
266358
match self.subcommand {
267-
Subcommand::Tests(TestOpts { form_lib, .. })
359+
Subcommand::Tests(TestAll { form_lib, .. })
360+
| Subcommand::Test(Test { form_lib, .. })
268361
| Subcommand::Diff(Diffing {
269362
form_split: form_lib,
270363
..
@@ -278,13 +371,10 @@ impl Opts {
278371
fn default_test_cases() -> std::ffi::OsString {
279372
std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
280373
|| std::ffi::OsString::from("tests.yml".to_owned()),
281-
|mut e| {
282-
e.extend([std::ffi::OsStr::new("/tests.yml")]);
283-
std::path::PathBuf::from(e)
284-
.strip_prefix(std::env::current_dir().unwrap())
285-
.unwrap()
286-
.to_owned()
287-
.into_os_string()
374+
|path| {
375+
let path = std::path::PathBuf::from(path);
376+
let path = path.join("tests.yml");
377+
path.to_owned().into_os_string()
288378
},
289379
)
290380
}
@@ -414,6 +504,13 @@ fn main() -> Result<(), anyhow::Error> {
414504
}
415505
Subcommand::Diff(diff) => diff.run(&opt).with_context(|| "failed to run diff"),
416506
Subcommand::Ci(ci) => ci.run(&opt).with_context(|| "failed to run ci"),
507+
Subcommand::Test(test) => {
508+
anyhow::ensure!(
509+
test.current_bin_path.exists(),
510+
"svd2rust binary does not exist"
511+
);
512+
test.run(&opt).with_context(|| "failed to run test")
513+
}
417514
}
418515
}
419516

0 commit comments

Comments
 (0)