Skip to content

Commit a89a90d

Browse files
authored
Merge pull request #907 from robamu/ci-update-clippy-and-docs
update CI to run clippy and docs
2 parents af3fa4a + 90196b0 commit a89a90d

File tree

5 files changed

+163
-34
lines changed

5 files changed

+163
-34
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
ci:
1111
name: CI
1212
runs-on: ubuntu-latest
13-
needs: [check, ci-linux, ci-clippy, ci-serde]
13+
needs: [check, ci-linux, ci-docs-clippy, ci-serde]
1414
if: always()
1515
steps:
1616
- name: Done
@@ -127,15 +127,33 @@ jobs:
127127
# stable.
128128
run: cargo +stable regress tests --toolchain 1.76.0 -m Nordic -- --strict --atomics
129129

130-
ci-clippy:
130+
ci-docs-clippy:
131131
runs-on: ubuntu-latest
132132
needs: [check]
133+
strategy:
134+
fail-fast: false
135+
matrix:
136+
include:
137+
# STMicro
138+
- { chip: STM32F030 }
139+
- { chip: STM32F410 }
140+
- { chip: STM32L1xx }
141+
# Espressif
142+
- { chip: esp32c3 }
143+
# Freescale
144+
- { chip: MKW22D5 }
145+
- { chip: MK02F12810 }
146+
# Silicon Labs
147+
# TODO: fix doc rendering bug when math `>` is present in description
148+
#- { chip: SIM3L1x8_SVD }
149+
# Nordic chips
150+
- { chip: nrf51, options: "-- -f register_mod::s:_mod" }
151+
- { chip: nrf52, options: "-- -f register_mod::s:_mod" }
133152
steps:
134153
- uses: actions/checkout@v4
135154

136-
- uses: dtolnay/rust-toolchain@master
137-
with:
138-
toolchain: stable
155+
- uses: dtolnay/rust-toolchain@nightly
156+
- uses: dtolnay/rust-toolchain@stable
139157

140158
- name: Cache
141159
uses: Swatinem/rust-cache@v2
@@ -144,12 +162,8 @@ jobs:
144162
run: |
145163
cargo install svd2rust --path .
146164
147-
- name: Run CI script
148-
env:
149-
VENDOR: RISC-V
150-
OPTIONS: ""
151-
COMMAND: clippy
152-
run: bash ci/script.sh
165+
- name: Check docs and clippy on generated PACs
166+
run: cargo regress test -c ${{ matrix.chip }} --docs-stable --docs-nightly --clippy ${{ matrix.options }}
153167

154168
ci-serde:
155169
runs-on: ubuntu-latest

ci/svd2rust-regress/src/command.rs

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

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

1213
#[track_caller]
1314
fn get_output_string(&mut self) -> Result<String, anyhow::Error>;
@@ -33,7 +34,10 @@ impl CommandExt for Command {
3334
}
3435

3536
#[track_caller]
36-
fn get_output(&mut self, can_fail: bool) -> Result<std::process::Output, anyhow::Error> {
37+
fn run_and_get_output(
38+
&mut self,
39+
can_fail: bool,
40+
) -> Result<std::process::Output, anyhow::Error> {
3741
let output = self
3842
.output()
3943
.with_context(|| format!("command `{}` couldn't be run", self.display()))?;
@@ -51,7 +55,7 @@ impl CommandExt for Command {
5155

5256
#[track_caller]
5357
fn get_output_string(&mut self) -> Result<String, anyhow::Error> {
54-
String::from_utf8(self.get_output(true)?.stdout).map_err(Into::into)
58+
String::from_utf8(self.run_and_get_output(true)?.stdout).map_err(Into::into)
5559
}
5660

5761
fn display(&self) -> String {

ci/svd2rust-regress/src/github.rs

Lines changed: 1 addition & 1 deletion
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(false)?;
151+
.run_and_get_output(false)?;
152152
}
153153
}
154154
_ => {

ci/svd2rust-regress/src/main.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ pub struct TestAll {
9090
/// Enable splitting `lib.rs` with `form`
9191
pub form_lib: bool,
9292

93+
/// Check generated crates with clippy.
94+
#[clap(long)]
95+
pub clippy: bool,
96+
97+
/// Check documentation build with stable.
98+
#[clap(long)]
99+
pub docs_stable: bool,
100+
101+
/// Check documentation build with nightly settings (docs.rs equivalent).
102+
#[clap(long)]
103+
pub docs_nightly: bool,
104+
93105
/// Print all available test using the specified filters
94106
#[clap(long)]
95107
pub list: bool,
@@ -143,6 +155,18 @@ pub struct Test {
143155
/// Chip to use, use `--url` or `--svd-file` for another way to specify svd
144156
pub chip: Option<String>,
145157

158+
/// Check generated crate with clippy.
159+
#[arg(long)]
160+
pub clippy: bool,
161+
162+
/// Check documentation build with stable.
163+
#[clap(long)]
164+
pub docs_stable: bool,
165+
166+
/// Check documentation build with nightly settings (docs.rs equivalent).
167+
#[clap(long)]
168+
pub docs_nightly: bool,
169+
146170
/// Path to an `svd2rust` binary, relative or absolute.
147171
/// Defaults to `target/release/svd2rust[.exe]` of this repository
148172
/// (which must be already built)
@@ -191,7 +215,14 @@ impl Test {
191215
.ok_or_else(|| anyhow::anyhow!("no test found for chip"))?
192216
.to_owned()
193217
};
194-
test.test(opts, &self.current_bin_path, &self.passthrough_opts)?;
218+
test.test(
219+
opts,
220+
&self.current_bin_path,
221+
self.clippy,
222+
self.docs_stable,
223+
self.docs_nightly,
224+
&self.passthrough_opts,
225+
)?;
195226
Ok(())
196227
}
197228
}
@@ -247,7 +278,14 @@ impl TestAll {
247278
tests.par_iter().for_each(|t| {
248279
let start = Instant::now();
249280

250-
match t.test(opt, &self.current_bin_path, &self.passthrough_opts) {
281+
match t.test(
282+
opt,
283+
&self.current_bin_path,
284+
self.clippy,
285+
self.docs_stable,
286+
self.docs_nightly,
287+
&self.passthrough_opts,
288+
) {
251289
Ok(s) => {
252290
if let Some(stderrs) = s {
253291
let mut buf = String::new();

ci/svd2rust-regress/src/svd_test.rs

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,27 +71,43 @@ impl std::fmt::Debug for ProcessFailed {
7171
}
7272

7373
trait CommandHelper {
74-
fn capture_outputs(
74+
fn run_and_capture_outputs(
7575
&mut self,
7676
cant_fail: bool,
7777
name: &str,
7878
stdout: Option<&PathBuf>,
7979
stderr: Option<&PathBuf>,
8080
previous_processes_stderr: &[PathBuf],
8181
) -> Result<(), TestError>;
82+
83+
fn run_and_capture_stderr(
84+
&mut self,
85+
cant_fail: bool,
86+
name: &str,
87+
stderr: &PathBuf,
88+
previous_processes_stderr: &[PathBuf],
89+
) -> Result<(), TestError> {
90+
self.run_and_capture_outputs(
91+
cant_fail,
92+
name,
93+
None,
94+
Some(stderr),
95+
previous_processes_stderr,
96+
)
97+
}
8298
}
8399

84100
impl CommandHelper for Command {
85101
#[tracing::instrument(skip_all, fields(stdout = tracing::field::Empty, stderr = tracing::field::Empty))]
86-
fn capture_outputs(
102+
fn run_and_capture_outputs(
87103
&mut self,
88104
cant_fail: bool,
89105
name: &str,
90106
stdout: Option<&PathBuf>,
91107
stderr: Option<&PathBuf>,
92108
previous_processes_stderr: &[PathBuf],
93109
) -> Result<(), TestError> {
94-
let output = self.get_output(true)?;
110+
let output = self.run_and_get_output(true)?;
95111
let out_payload = String::from_utf8_lossy(&output.stdout);
96112
if let Some(out) = stdout {
97113
file_helper(&out_payload, out)?;
@@ -142,41 +158,98 @@ impl TestCase {
142158
&self,
143159
opts: &Opts,
144160
bin_path: &Path,
145-
cli_opts: &Option<Vec<String>>,
161+
run_clippy: bool,
162+
run_docs_stable: bool,
163+
run_docs_nightly: bool,
164+
cli_passthrough_opts: &Option<Vec<String>>,
146165
) -> Result<Option<Vec<PathBuf>>, TestError> {
147166
let (chip_dir, mut process_stderr_paths) = self
148-
.setup_case(&opts.output_dir, bin_path, cli_opts)
167+
.setup_case(&opts.output_dir, bin_path, cli_passthrough_opts)
149168
.with_context(|| anyhow!("when setting up case for {}", self.name()))?;
150169
// Run `cargo check`, capturing stderr to a log file
151170
if !self.skip_check {
152171
let cargo_check_err_file = path_helper_base(&chip_dir, &["cargo-check.err.log"]);
153172
Command::new("cargo")
154173
.arg("check")
155174
.current_dir(&chip_dir)
156-
.capture_outputs(
175+
.run_and_capture_stderr(
157176
true,
158177
"cargo check",
159-
None,
160-
Some(&cargo_check_err_file),
178+
&cargo_check_err_file,
161179
&process_stderr_paths,
162180
)
163-
.with_context(|| "failed to check")?;
181+
.with_context(|| "failed to check with cargo check")?;
164182
process_stderr_paths.push(cargo_check_err_file);
165183
}
184+
if run_docs_nightly {
185+
tracing::info!("Checking docs build with nightly");
186+
let cargo_docs_err_file = path_helper_base(&chip_dir, &["cargo-docs-nightly.err.log"]);
187+
// Docs are built like docs.rs would build them. Additionally, build with all features.
188+
189+
// Set the RUSTDOCFLAGS environment variable
190+
let rustdocflags = "--cfg docsrs --generate-link-to-definition -Z unstable-options";
191+
Command::new("cargo")
192+
.arg("+nightly")
193+
.arg("doc")
194+
.arg("--all-features")
195+
.env("RUSTDOCFLAGS", rustdocflags) // Set the environment variable
196+
.current_dir(&chip_dir)
197+
.run_and_capture_stderr(
198+
true,
199+
"cargo docs nightly",
200+
&cargo_docs_err_file,
201+
&process_stderr_paths,
202+
)
203+
.with_context(|| "failed to generate docs with cargo docs")?;
204+
}
205+
if run_docs_stable {
206+
tracing::info!("Checking docs build with stable");
207+
let cargo_docs_err_file = path_helper_base(&chip_dir, &["cargo-docs-stable.err.log"]);
208+
// Docs are built like docs.rs would build them. Additionally, build with all features.
209+
Command::new("cargo")
210+
.arg("+stable")
211+
.arg("doc")
212+
.arg("--all-features")
213+
.current_dir(&chip_dir)
214+
.run_and_capture_stderr(
215+
true,
216+
"cargo docs stable",
217+
&cargo_docs_err_file,
218+
&process_stderr_paths,
219+
)
220+
.with_context(|| "failed to generate docs with cargo docs")?;
221+
}
222+
if run_clippy {
223+
tracing::info!("Checking with clippy");
224+
let cargo_clippy_err_file = path_helper_base(&chip_dir, &["cargo-clippy.err.log"]);
225+
Command::new("cargo")
226+
.arg("clippy")
227+
.arg("--")
228+
.arg("-D")
229+
.arg("warnings")
230+
.current_dir(&chip_dir)
231+
.run_and_capture_stderr(
232+
true,
233+
"cargo clippy",
234+
&cargo_clippy_err_file,
235+
&process_stderr_paths,
236+
)
237+
.with_context(|| "failed to check with cargo clippy")?;
238+
}
166239
Ok(if opts.verbose > 1 {
167240
Some(process_stderr_paths)
168241
} else {
169242
None
170243
})
171244
}
172245

173-
#[tracing::instrument(skip(self, output_dir, command), fields(name = %self.name(), chip_dir = tracing::field::Empty))]
246+
#[tracing::instrument(skip(self, output_dir, passthrough_opts), fields(name = %self.name(), chip_dir = tracing::field::Empty))]
174247

175248
pub fn setup_case(
176249
&self,
177250
output_dir: &Path,
178251
svd2rust_bin_path: &Path,
179-
command: &Option<Vec<String>>,
252+
passthrough_opts: &Option<Vec<String>>,
180253
) -> Result<(PathBuf, Vec<PathBuf>), TestError> {
181254
let user = match std::env::var("USER") {
182255
Ok(val) => val,
@@ -210,10 +283,10 @@ impl TestCase {
210283
.arg("none")
211284
.arg("--lib")
212285
.arg(&chip_dir)
213-
.capture_outputs(true, "cargo init", None, None, &[])
286+
.run_and_capture_outputs(true, "cargo init", None, None, &[])
214287
.with_context(|| "Failed to cargo init")?;
215288

216-
self.prepare_chip_test_toml(&chip_dir, command)?;
289+
self.prepare_chip_test_toml(&chip_dir, passthrough_opts)?;
217290
let chip_svd = self.prepare_svd_file(&chip_dir)?;
218291
self.prepare_rust_toolchain_file(&chip_dir)?;
219292

@@ -226,7 +299,7 @@ impl TestCase {
226299
&chip_dir,
227300
&lib_rs_file,
228301
&svd2rust_err_file,
229-
command,
302+
passthrough_opts,
230303
)?;
231304
process_stderr_paths.push(svd2rust_err_file);
232305
match self.arch {
@@ -262,7 +335,7 @@ impl TestCase {
262335
.arg(&new_lib_rs_file)
263336
.arg("--outdir")
264337
.arg(&src_dir)
265-
.capture_outputs(
338+
.run_and_capture_outputs(
266339
true,
267340
"form",
268341
None,
@@ -291,7 +364,7 @@ impl TestCase {
291364
Command::new(rustfmt_bin_path)
292365
.arg(entry)
293366
.args(["--edition", "2021"])
294-
.capture_outputs(
367+
.run_and_capture_outputs(
295368
false,
296369
"rustfmt",
297370
None,
@@ -417,7 +490,7 @@ impl TestCase {
417490
if let Some(opts) = self.opts.as_ref() {
418491
base_cmd.args(opts);
419492
}
420-
base_cmd.current_dir(chip_dir).capture_outputs(
493+
base_cmd.current_dir(chip_dir).run_and_capture_outputs(
421494
true,
422495
"svd2rust",
423496
Some(lib_rs_file).filter(|_| {

0 commit comments

Comments
 (0)