Add a stderr file length check to clippy_dev

This adds a check to `clippy_dev` that enforces a maximum line count for
`stderr` files. CI will fail if the line count is exceeded. It's
currently set to `320` lines.

Ideally this would be implemented in `compiletest-rs` but there are
plans to move Rust's `compiletest` into the `compiletest-rs` repository
and I don't want to do the work in `compiletest` twice. However, I also
don't want to wait until the move is done, so I added the check to
`clippy_dev` until it makes sense to add it to compiletest-rs.

cc #2038
This commit is contained in:
Philipp Hansch 2019-05-16 07:31:56 +02:00
parent 82b2dfb9f6
commit d9a8a8a778
No known key found for this signature in database
GPG key ID: 82AA61CAA11397E6
3 changed files with 66 additions and 2 deletions

View file

@ -23,6 +23,7 @@ export CARGO_TARGET_DIR=`pwd`/target/
# Perform various checks for lint registration
./util/dev update_lints --check
./util/dev --limit-stderr-length
cargo +nightly fmt --all -- --check
# Check running clippy-driver without cargo

View file

@ -2,8 +2,9 @@ extern crate clap;
extern crate clippy_dev;
extern crate regex;
use clap::{App, AppSettings, Arg, SubCommand};
use clap::{App, Arg, SubCommand};
use clippy_dev::*;
mod stderr_length_check;
#[derive(PartialEq)]
enum UpdateMode {
@ -13,7 +14,6 @@ enum UpdateMode {
fn main() {
let matches = App::new("Clippy developer tooling")
.setting(AppSettings::SubcommandRequiredElseHelp)
.subcommand(
SubCommand::with_name("update_lints")
.about("Updates lint registration and information from the source code")
@ -36,8 +36,16 @@ fn main() {
.help("Checks that util/dev update_lints has been run. Used on CI."),
),
)
.arg(
Arg::with_name("limit-stderr-length")
.long("limit-stderr-length")
.help("Ensures that stderr files do not grow longer than a certain amount of lines."),
)
.get_matches();
if matches.is_present("limit-stderr-length") {
stderr_length_check::check();
}
if let Some(matches) = matches.subcommand_matches("update_lints") {
if matches.is_present("print-only") {
print_lints();

View file

@ -0,0 +1,55 @@
use std::ffi::OsStr;
use walkdir::WalkDir;
use std::fs::File;
use std::io::prelude::*;
// The maximum length allowed for stderr files.
//
// We limit this because small files are easier to deal with than bigger files.
const LIMIT: usize = 320;
pub fn check() {
let stderr_files = stderr_files();
let exceeding_files = exceeding_stderr_files(stderr_files);
if !exceeding_files.is_empty() {
println!("Error: stderr files exceeding limit of {} lines:", LIMIT);
for path in exceeding_files {
println!("{}", path);
}
std::process::exit(1);
}
}
fn exceeding_stderr_files(files: impl Iterator<Item = walkdir::DirEntry>) -> Vec<String> {
files
.filter_map(|file| {
let path = file.path().to_str().expect("Could not convert path to str").to_string();
let linecount = count_linenumbers(&path);
if linecount > LIMIT {
Some(path)
} else {
None
}
})
.collect()
}
fn stderr_files() -> impl Iterator<Item = walkdir::DirEntry> {
// We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
WalkDir::new("../tests/ui")
.into_iter()
.filter_map(std::result::Result::ok)
.filter(|f| f.path().extension() == Some(OsStr::new("stderr")))
}
fn count_linenumbers(filepath: &str) -> usize {
if let Ok(mut file) = File::open(filepath) {
let mut content = String::new();
file.read_to_string(&mut content).expect("Failed to read file?");
content.lines().count()
} else {
0
}
}