Skip to content

Commit fb54754

Browse files
authored
Merge pull request #199 from Emilgardis/improve-ci
Improve ci
2 parents df3d37e + 8aef365 commit fb54754

File tree

7 files changed

+133
-45
lines changed

7 files changed

+133
-45
lines changed

.gitlab-ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ regress:nightly:
1212
image: rustlang/rust:nightly
1313
script:
1414
- cargo build --release
15+
- rustup component add rustfmt-preview
1516
- cd ci/svd2rust-regress
1617
- rm -rf ./output
17-
- cargo run --release -- --long-test
18+
- cargo run --release -- --long-test --format --verbose

ci/svd2rust-regress/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "svd2rust-regress"
33
version = "0.1.0"
4-
authors = ["James Munns <[email protected]>"]
4+
authors = ["James Munns <[email protected]>", "The svd2rust developers"]
55

66
[dependencies]
77
reqwest = "0.8"
88
rayon = "1.0"
99
structopt = "0.2"
1010
error-chain = "0.11"
11-
inflections = "1.1.0"
11+
inflections = "1.1.0"

ci/svd2rust-regress/README.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
### Preconditions
1717

18-
By default, `svd2rust-regress` assumes you have already built `svd2rust` in the root of this repository in `--release` mode. If this is not possible, it is possible to specify the path to an `svd2rust` binary (see **Options** below).
18+
By default, `svd2rust-regress` assumes you have already built `svd2rust` in the root of this repository in `--release` mode.
19+
If this is not possible, it is possible to specify the path to an `svd2rust` binary (see **Options** below).
20+
21+
You'll also need to have `rustfmt` version > v0.4.0 to use the `--format` flag, you can install `rustfmt` with `rustup component add rustfmt-preview`.
1922

2023
### Output
2124

@@ -30,7 +33,7 @@ Passed: spansion_mb9af12x_k - 23 seconds
3033
Fail results look like this:
3134

3235
```text
33-
Failed: si_five_e310x - 0 seconds - Error(Msg("Process Failed! - cargo check"), State { next_error: None, backtrace: None })
36+
Failed: si_five_e310x - 0 seconds. Error: Process Failed - cargo check
3437
```
3538

3639
If all test cases passed, the return code will be `0`. If any test cases failed, the return code will be `1`.
@@ -42,24 +45,32 @@ Here are the options for running `svd2rust-regress`:
4245

4346
```text
4447
svd2rust-regress 0.1.0
45-
James Munns <[email protected]>
48+
James Munns <[email protected]>:The svd2rust developers
4649
4750
USAGE:
4851
svd2rust-regress [FLAGS] [OPTIONS]
4952
5053
FLAGS:
5154
-b, --bad-tests Include tests expected to fail (will cause a non-zero return code)
55+
-f, --format Enable formatting with `rustfmt`
5256
-h, --help Prints help information
5357
-l, --long-test Run a long test (it's very long)
5458
-V, --version Prints version information
59+
-v, --verbose Use verbose output
5560
5661
OPTIONS:
57-
-a, --architecture <arch> Filter by architecture, case sensitive, may be combined with other filters Options
58-
are: "CortexM", "RiscV", and "Msp430"
59-
-p, --svd2rust-path <bin_path> Path to an `svd2rust` binary, relative or absolute. Defaults to
60-
`target/release/svd2rust[.exe]` of this repository (which must be already built)
61-
-c, --chip <chip> Filter by chip name, case sensitive, may be combined with other filters
62-
-m, --manufacturer <mfgr> Filter by manufacturer, case sensitive, may be combined with other filters
62+
-a, --architecture <arch>
63+
Filter by architecture, case sensitive, may be combined with other filters Options are: "CortexM", "RiscV",
64+
and "Msp430"
65+
-p, --svd2rust-path <bin_path>
66+
Path to an `svd2rust` binary, relative or absolute. Defaults to `target/release/svd2rust[.exe]` of this
67+
repository (which must be already built)
68+
-c, --chip <chip> Filter by chip name, case sensitive, may be combined with other filters
69+
-m, --manufacturer <mfgr>
70+
Filter by manufacturer, case sensitive, may be combined with other filters
71+
72+
--rustfmt_bin_path <rustfmt_bin_path>
73+
Path to an `rustfmt` binary, relative or absolute. Defaults to `$(rustup which rustfmt)`
6374
```
6475

6576
### Filters
@@ -92,4 +103,6 @@ cargo run --release -- --long-test -c MB9AF12xK -m Fujitsu
92103
Finished release [optimized] target(s) in 0.0 secs
93104
Running `target/release/svd2rust-regress --long-test -c MB9AF12xK -m Fujitsu`
94105
Passed: fujitsu_mb9af12x_k - 19 seconds
95-
```
106+
```
107+
108+
Note that you may have to pass `--long-test` to enable some chips as they are known to take a long time to compile.

ci/svd2rust-regress/src/errors.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
error_chain!{}
1+
use std::path::PathBuf;
2+
error_chain!{
3+
errors {
4+
ProcessFailed(command: String, stderr: Option<PathBuf>, stdout: Option<PathBuf>) {
5+
description("Process Failed")
6+
display("Process Failed - {}", command)
7+
}
8+
}
9+
}

ci/svd2rust-regress/src/main.rs

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@ extern crate reqwest;
66
#[macro_use]
77
extern crate structopt;
88

9-
mod tests;
109
mod errors;
1110
mod svd_test;
11+
mod tests;
1212

13-
use std::path::PathBuf;
14-
use structopt::StructOpt;
13+
use error_chain::ChainedError;
1514
use rayon::prelude::*;
15+
use std::fs::File;
16+
use std::io::Read;
17+
use std::path::PathBuf;
18+
use std::process::{exit, Command};
1619
use std::sync::atomic::{AtomicBool, Ordering};
17-
use std::process::exit;
1820
use std::time::Instant;
21+
use structopt::StructOpt;
1922

2023
#[derive(StructOpt, Debug)]
2124
#[structopt(name = "svd2rust-regress")]
@@ -47,6 +50,18 @@ struct Opt {
4750
#[structopt(short = "b", long = "bad-tests")]
4851
bad_tests: bool,
4952

53+
/// Enable formatting with `rustfmt`
54+
#[structopt(short = "f", long = "format")]
55+
format: bool,
56+
57+
/// Path to an `rustfmt` binary, relative or absolute.
58+
/// Defaults to `$(rustup which rustfmt)`
59+
#[structopt(long = "rustfmt_bin_path", parse(from_os_str))]
60+
rustfmt_bin_path: Option<PathBuf>,
61+
62+
/// Use verbose output
63+
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
64+
verbose: u8,
5065
// TODO: Specify smaller subset of tests? Maybe with tags?
5166
// TODO: Early fail
5267
// TODO: Compile svd2rust?
@@ -93,6 +108,36 @@ fn main() {
93108
None => &default_svd2rust,
94109
};
95110

111+
let default_rustfmt: Option<PathBuf> = if let Some((v, true)) = Command::new("rustup")
112+
.args(&["which", "rustfmt"])
113+
.output()
114+
.ok()
115+
.map(|o| (o.stdout, o.status.success()))
116+
{
117+
Some(String::from_utf8_lossy(&v).into_owned().trim().into())
118+
} else {
119+
if opt.format && opt.rustfmt_bin_path.is_none() {
120+
panic!("rustfmt binary not found, is rustup and rustfmt-preview installed?");
121+
}
122+
None
123+
};
124+
125+
let rustfmt_bin_path = match (&opt.rustfmt_bin_path, opt.format) {
126+
(_, false) => None,
127+
(&Some(ref path), true) => Some(path),
128+
(&None, true) => {
129+
// FIXME: Use Option::filter instead when stable, rust-lang/rust#45860
130+
if default_rustfmt
131+
.iter()
132+
.filter(|p| p.is_file())
133+
.next()
134+
.is_none()
135+
{
136+
panic!("No rustfmt found");
137+
}
138+
default_rustfmt.as_ref()
139+
}
140+
};
96141
// collect enabled tests
97142
let tests = tests::TESTS
98143
.iter()
@@ -133,8 +178,9 @@ fn main() {
133178
tests.par_iter().for_each(|t| {
134179
let start = Instant::now();
135180

136-
match svd_test::test(t, &bin_path) {
181+
match svd_test::test(t, &bin_path, rustfmt_bin_path) {
137182
Ok(()) => {
183+
// TODO: If verbosity is > 1, print every logged stderr
138184
eprintln!(
139185
"Passed: {} - {} seconds",
140186
t.name(),
@@ -143,11 +189,31 @@ fn main() {
143189
}
144190
Err(e) => {
145191
any_fails.store(true, Ordering::Release);
192+
let additional_info = if opt.verbose > 0 {
193+
match e.kind() {
194+
&errors::ErrorKind::ProcessFailed(ref command, _, Some(ref stderr))
195+
if command == "cargo check" =>
196+
{
197+
let mut buf = String::new();
198+
// Unwrap is safe
199+
File::open(stderr)
200+
.expect("Couldn't open file")
201+
.read_to_string(&mut buf)
202+
.expect("Couldn't read file to string");
203+
buf.insert_str(0, &format!("\n---{:?}---\n", stderr.as_os_str()));
204+
buf
205+
}
206+
_ => "".into(),
207+
}
208+
} else {
209+
"".into()
210+
};
146211
eprintln!(
147-
"Failed: {} - {} seconds - {:?}",
212+
"Failed: {} - {} seconds. {}{}",
148213
t.name(),
149214
start.elapsed().as_secs(),
150-
e
215+
e.display_chain().to_string().trim_right(),
216+
additional_info,
151217
);
152218
}
153219
}

ci/svd2rust-regress/src/svd_test.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use errors::*;
2-
use std::io::prelude::*;
2+
use reqwest;
33
use std::fs::{remove_dir_all, File, OpenOptions};
4+
use std::io::prelude::*;
5+
use std::path::PathBuf;
46
use std::process::{Command, Output};
57
use tests::TestCase;
6-
use reqwest;
7-
use std::path::PathBuf;
88

99
static CRATES_ALL: &[&str] = &["bare-metal = \"0.1.0\"", "vcell = \"0.1.0\""];
1010
static CRATES_MSP430: &[&str] = &["msp430 = \"0.1.0\""];
@@ -50,25 +50,27 @@ impl CommandHelper for Output {
5050
stdout: Option<&PathBuf>,
5151
stderr: Option<&PathBuf>,
5252
) -> Result<()> {
53-
if cant_fail && !self.status.success() {
54-
bail!(format!("Process Failed! - {}", name))
55-
}
56-
5753
if let Some(out) = stdout {
5854
let out_payload = String::from_utf8_lossy(&self.stdout);
5955
file_helper(&out_payload, out)?;
60-
}
56+
};
6157

6258
if let Some(err) = stderr {
6359
let err_payload = String::from_utf8_lossy(&self.stderr);
6460
file_helper(&err_payload, err)?;
61+
};
62+
63+
if cant_fail && !self.status.success() {
64+
return Err(
65+
ErrorKind::ProcessFailed(name.into(), stdout.cloned(), stderr.cloned()).into(),
66+
);
6567
}
6668

6769
Ok(())
6870
}
6971
}
7072

71-
pub fn test(t: &TestCase, bin_path: &PathBuf) -> Result<()> {
73+
pub fn test(t: &TestCase, bin_path: &PathBuf, rustfmt_bin_path: Option<&PathBuf>) -> Result<()> {
7274
let user = match ::std::env::var("USER") {
7375
Ok(val) => val,
7476
Err(_) => "rusttester".into(),
@@ -134,11 +136,10 @@ pub fn test(t: &TestCase, bin_path: &PathBuf) -> Result<()> {
134136
&Msp430 => "msp430",
135137
&RiscV => "riscv",
136138
};
139+
137140
Command::new(bin_path)
138-
.arg("-i")
139-
.arg(&chip_svd)
140-
.arg("--target")
141-
.arg(target)
141+
.args(&["-i", &chip_svd])
142+
.args(&["--target", &target])
142143
.current_dir(&chip_dir)
143144
.output()
144145
.chain_err(|| "failed to execute process")?
@@ -149,16 +150,15 @@ pub fn test(t: &TestCase, bin_path: &PathBuf) -> Result<()> {
149150
Some(&svd2rust_err_file),
150151
)?;
151152

152-
// TODO: rustfmt < 0.4.0 seems to mangle some doc comments. Omit until this is fixed
153-
// Run `cargo fmt`, capturing stderr to a log file
154-
// let cargo_fmt_err_file = path_helper_base(&chip_dir, &["cargo-fmt.err.log"]);
155-
// Command::new("cargo")
156-
// .arg("fmt")
157-
// .current_dir(&chip_dir)
158-
// .output()
159-
// .chain_err(|| "failed to format")?
160-
// .capture_outputs(false, "cargo fmt", None, Some(&cargo_fmt_err_file))?;
161-
153+
if let Some(rustfmt_bin_path) = rustfmt_bin_path {
154+
// Run `cargo fmt`, capturing stderr to a log file
155+
let fmt_err_file = path_helper_base(&chip_dir, &["rustfmt.err.log"]);
156+
Command::new(rustfmt_bin_path)
157+
.arg(lib_rs_file)
158+
.output()
159+
.chain_err(|| "failed to format")?
160+
.capture_outputs(false, "rustfmt", None, Some(&fmt_err_file))?;
161+
}
162162
// Run `cargo check`, capturing stderr to a log file
163163
let cargo_check_err_file = path_helper_base(&chip_dir, &["cargo-check.err.log"]);
164164
Command::new("cargo")

ci/svd2rust-regress/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use self::RunWhen::*;
7676
/// that are not valid in Rust ident
7777
const BLACKLIST_CHARS: &'static [char] = &['(', ')', '[', ']'];
7878

79-
/// Lovingly stolen from `svd2rust`. Probably could be `Cow`, but I'm lazy
79+
/// Lovingly stolen from `svd2rust`. Probably could be `Cow`
8080
pub trait ToSanitizedSnakeCase {
8181
fn to_sanitized_snake_case(&self) -> String;
8282
}

0 commit comments

Comments
 (0)