Skip to content

Commit 18c5ea4

Browse files
committed
Auto merge of #6413 - phansch:bless, r=flip1995
Rewrite update-all-references bash scripts in Rust This replaces the `update-all-references` scripts with a single cargo dev bless command. It should behave mostly the same as the bash scripts. The major difference is, that it can be called from the project root and will always update the files in all of the test suites. cc #5394 changelog: none
2 parents baf5f2d + b8501e1 commit 18c5ea4

11 files changed

+87
-208
lines changed

clippy_dev/src/bless.rs

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//! `bless` updates the reference files in the repo with changed output files
2+
//! from the last test run.
3+
4+
use std::env;
5+
use std::ffi::OsStr;
6+
use std::fs;
7+
use std::lazy::SyncLazy;
8+
use std::path::PathBuf;
9+
use walkdir::WalkDir;
10+
11+
use crate::clippy_project_root;
12+
13+
// NOTE: this is duplicated with tests/cargo/mod.rs What to do?
14+
pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
15+
Some(v) => v.into(),
16+
None => env::current_dir().unwrap().join("target"),
17+
});
18+
19+
pub fn bless() {
20+
let test_dirs = [
21+
clippy_project_root().join("tests").join("ui"),
22+
clippy_project_root().join("tests").join("ui-toml"),
23+
clippy_project_root().join("tests").join("ui-cargo"),
24+
];
25+
for test_dir in &test_dirs {
26+
WalkDir::new(test_dir)
27+
.into_iter()
28+
.filter_map(Result::ok)
29+
.filter(|f| f.path().extension() == Some(OsStr::new("rs")))
30+
.for_each(|f| {
31+
update_reference_file(f.path().with_extension("stdout"));
32+
update_reference_file(f.path().with_extension("stderr"));
33+
update_reference_file(f.path().with_extension("fixed"));
34+
});
35+
}
36+
}
37+
38+
fn update_reference_file(reference_file_path: PathBuf) {
39+
let test_output_path = build_dir().join(PathBuf::from(reference_file_path.file_name().unwrap()));
40+
let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
41+
42+
// If compiletest did not write any changes during the test run,
43+
// we don't have to update anything
44+
if !test_output_path.exists() {
45+
return;
46+
}
47+
48+
let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
49+
let reference_file = fs::read(&reference_file_path).expect("Unable to read reference file");
50+
51+
if test_output_file != reference_file {
52+
// If a test run caused an output file to change, update the reference file
53+
println!("updating {}", &relative_reference_file_path.display());
54+
fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
55+
56+
if reference_file.is_empty() {
57+
// If we copied over an empty output file, we remove the now empty reference file
58+
println!("removing {}", &relative_reference_file_path.display());
59+
fs::remove_file(reference_file_path).expect("Could not remove reference file");
60+
}
61+
}
62+
}
63+
64+
fn build_dir() -> PathBuf {
65+
let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
66+
let mut path = PathBuf::new();
67+
path.push(CARGO_TARGET_DIR.clone());
68+
path.push(profile);
69+
path.push("test_build_base");
70+
path
71+
}

clippy_dev/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::lazy::SyncLazy;
1010
use std::path::{Path, PathBuf};
1111
use walkdir::WalkDir;
1212

13+
pub mod bless;
1314
pub mod fmt;
1415
pub mod new_lint;
1516
pub mod ra_setup;

clippy_dev/src/main.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
22

33
use clap::{App, Arg, SubCommand};
4-
use clippy_dev::{fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
4+
use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
55

66
fn main() {
77
let matches = App::new("Clippy developer tooling")
8+
.subcommand(SubCommand::with_name("bless").about("bless the test output changes"))
89
.subcommand(
910
SubCommand::with_name("fmt")
1011
.about("Run rustfmt on all projects and tests")
@@ -116,6 +117,9 @@ fn main() {
116117
.get_matches();
117118

118119
match matches.subcommand() {
120+
("bless", Some(_)) => {
121+
bless::bless();
122+
},
119123
("fmt", Some(matches)) => {
120124
fmt::run(matches.is_present("check"), matches.is_present("verbose"));
121125
},

doc/adding_lints.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,12 @@ While we are working on implementing our lint, we can keep running the UI
9898
test. That allows us to check if the output is turning into what we want.
9999

100100
Once we are satisfied with the output, we need to run
101-
`tests/ui/update-all-references.sh` to update the `.stderr` file for our lint.
101+
`cargo dev bless` to update the `.stderr` file for our lint.
102102
Please note that, we should run `TESTNAME=foo_functions cargo uitest`
103-
every time before running `tests/ui/update-all-references.sh`.
103+
every time before running `cargo dev bless`.
104104
Running `TESTNAME=foo_functions cargo uitest` should pass then. When we commit
105105
our lint, we need to commit the generated `.stderr` files, too. In general, you
106-
should only commit files changed by `tests/ui/update-all-references.sh` for the
106+
should only commit files changed by `cargo dev bless` for the
107107
specific lint you are creating/editing. Note that if the generated files are
108108
empty, they should be removed.
109109

@@ -122,8 +122,7 @@ we will find by default two new crates, each with its manifest file:
122122
If you need more cases, you can copy one of those crates (under `foo_categories`) and rename it.
123123

124124
The process of generating the `.stderr` file is the same, and prepending the `TESTNAME`
125-
variable to `cargo uitest` works too, but the script to update the references
126-
is in another path: `tests/ui-cargo/update-all-references.sh`.
125+
variable to `cargo uitest` works too.
127126

128127
## Rustfix tests
129128

@@ -133,7 +132,7 @@ additionally run [rustfix] for that test. Rustfix will apply the suggestions
133132
from the lint to the code of the test file and compare that to the contents of
134133
a `.fixed` file.
135134

136-
Use `tests/ui/update-all-references.sh` to automatically generate the
135+
Use `cargo dev bless` to automatically generate the
137136
`.fixed` file after running the tests.
138137

139138
[rustfix]: https://github.com/rust-lang/rustfix
@@ -368,7 +367,7 @@ fn is_foo_fn(fn_kind: FnKind<'_>) -> bool {
368367

369368
Now we should also run the full test suite with `cargo test`. At this point
370369
running `cargo test` should produce the expected output. Remember to run
371-
`tests/ui/update-all-references.sh` to update the `.stderr` file.
370+
`cargo dev bless` to update the `.stderr` file.
372371

373372
`cargo test` (as opposed to `cargo uitest`) will also ensure that our lint
374373
implementation is not violating any Clippy lints itself.

doc/basics.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ If the output of a [UI test] differs from the expected output, you can update th
6161
reference file with:
6262

6363
```bash
64-
sh tests/ui/update-all-references.sh
64+
cargo dev bless
6565
```
6666

6767
For example, this is necessary, if you fix a typo in an error message of a lint
+1-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
11
#!/bin/bash
2-
#
3-
# A script to update the references for all tests. The idea is that
4-
# you do a run, which will generate files in the build directory
5-
# containing the (normalized) actual output of the compiler. You then
6-
# run this script, which will copy those files over. If you find
7-
# yourself manually editing a foo.stderr file, you're doing it wrong.
8-
#
9-
# See all `update-references.sh`, if you just want to update a single test.
102

11-
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
12-
echo "usage: $0"
13-
fi
14-
15-
BUILD_DIR=$PWD/target/debug/test_build_base
16-
MY_DIR=$(dirname "$0")
17-
cd "$MY_DIR" || exit
18-
find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
3+
echo "Please use 'cargo dev bless' instead."

tests/ui-cargo/update-references.sh

-46
This file was deleted.
+1-16
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
11
#!/bin/bash
2-
#
3-
# A script to update the references for all tests. The idea is that
4-
# you do a run, which will generate files in the build directory
5-
# containing the (normalized) actual output of the compiler. You then
6-
# run this script, which will copy those files over. If you find
7-
# yourself manually editing a foo.stderr file, you're doing it wrong.
8-
#
9-
# See all `update-references.sh`, if you just want to update a single test.
102

11-
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
12-
echo "usage: $0"
13-
fi
14-
15-
BUILD_DIR=$PWD/target/debug/test_build_base
16-
MY_DIR=$(dirname "$0")
17-
cd "$MY_DIR" || exit
18-
find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
3+
echo "Please use 'cargo dev bless' instead."

tests/ui-toml/update-references.sh

-46
This file was deleted.

tests/ui/update-all-references.sh

+1-19
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
11
#!/bin/bash
22

3-
# A script to update the references for all tests. The idea is that
4-
# you do a run, which will generate files in the build directory
5-
# containing the (normalized) actual output of the compiler. You then
6-
# run this script, which will copy those files over. If you find
7-
# yourself manually editing a foo.stderr file, you're doing it wrong.
8-
#
9-
# See all `update-references.sh`, if you just want to update a single test.
10-
11-
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
12-
echo "usage: $0"
13-
fi
14-
15-
CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-$PWD/target}
16-
PROFILE=${PROFILE:-debug}
17-
BUILD_DIR=${CARGO_TARGET_DIR}/${PROFILE}/test_build_base
18-
19-
MY_DIR=$(dirname "$0")
20-
cd "$MY_DIR" || exit
21-
find . -name '*.rs' -exec ./update-references.sh "$BUILD_DIR" {} +
3+
echo "Please use 'cargo dev bless' instead."

tests/ui/update-references.sh

-56
This file was deleted.

0 commit comments

Comments
 (0)