about summary refs log tree commit diff
path: root/clippy_dev
diff options
context:
space:
mode:
authorflip1995 <hello@philkrones.com>2020-12-20 17:19:49 +0100
committerflip1995 <hello@philkrones.com>2020-12-20 17:19:49 +0100
commitf03edfd7a1a02c696a600a1776aa847edd98c378 (patch)
tree28336431eb95b625711017cd53a86b1af48dd192 /clippy_dev
parentf00b6ac24e0decaa182b717172f2caf97c6b08bf (diff)
downloadrust-f03edfd7a1a02c696a600a1776aa847edd98c378.tar.gz
rust-f03edfd7a1a02c696a600a1776aa847edd98c378.zip
Merge commit '4911ab124c481430672a3833b37075e6435ec34d' into clippyup
Diffstat (limited to 'clippy_dev')
-rw-r--r--clippy_dev/src/bless.rs74
-rw-r--r--clippy_dev/src/fmt.rs21
-rw-r--r--clippy_dev/src/lib.rs1
-rw-r--r--clippy_dev/src/main.rs102
-rw-r--r--clippy_dev/src/ra_setup.rs2
5 files changed, 151 insertions, 49 deletions
diff --git a/clippy_dev/src/bless.rs b/clippy_dev/src/bless.rs
new file mode 100644
index 00000000000..645098e4cfc
--- /dev/null
+++ b/clippy_dev/src/bless.rs
@@ -0,0 +1,74 @@
+//! `bless` updates the reference files in the repo with changed output files
+//! from the last test run.
+
+use std::env;
+use std::ffi::OsStr;
+use std::fs;
+use std::lazy::SyncLazy;
+use std::path::PathBuf;
+use walkdir::WalkDir;
+
+use crate::clippy_project_root;
+
+// NOTE: this is duplicated with tests/cargo/mod.rs What to do?
+pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
+    Some(v) => v.into(),
+    None => env::current_dir().unwrap().join("target"),
+});
+
+pub fn bless() {
+    let test_dirs = [
+        clippy_project_root().join("tests").join("ui"),
+        clippy_project_root().join("tests").join("ui-toml"),
+        clippy_project_root().join("tests").join("ui-cargo"),
+    ];
+    for test_dir in &test_dirs {
+        WalkDir::new(test_dir)
+            .into_iter()
+            .filter_map(Result::ok)
+            .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+            .for_each(|f| {
+                update_reference_file(f.path().with_extension("stdout"));
+                update_reference_file(f.path().with_extension("stderr"));
+                update_reference_file(f.path().with_extension("fixed"));
+            });
+    }
+}
+
+fn update_reference_file(reference_file_path: PathBuf) {
+    let test_output_path = build_dir().join(PathBuf::from(reference_file_path.file_name().unwrap()));
+    let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
+
+    // If compiletest did not write any changes during the test run,
+    // we don't have to update anything
+    if !test_output_path.exists() {
+        return;
+    }
+
+    let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
+    let reference_file = fs::read(&reference_file_path).unwrap_or_default();
+
+    if test_output_file != reference_file {
+        // If a test run caused an output file to change, update the reference file
+        println!("updating {}", &relative_reference_file_path.display());
+        fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
+
+        // We need to re-read the file now because it was potentially updated from copying
+        let reference_file = fs::read(&reference_file_path).unwrap_or_default();
+
+        if reference_file.is_empty() {
+            // If we copied over an empty output file, we remove the now empty reference file
+            println!("removing {}", &relative_reference_file_path.display());
+            fs::remove_file(reference_file_path).expect("Could not remove reference file");
+        }
+    }
+}
+
+fn build_dir() -> PathBuf {
+    let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
+    let mut path = PathBuf::new();
+    path.push(CARGO_TARGET_DIR.clone());
+    path.push(profile);
+    path.push("test_build_base");
+    path
+}
diff --git a/clippy_dev/src/fmt.rs b/clippy_dev/src/fmt.rs
index 6ae3f58c1f2..6b528d219df 100644
--- a/clippy_dev/src/fmt.rs
+++ b/clippy_dev/src/fmt.rs
@@ -1,9 +1,9 @@
 use crate::clippy_project_root;
 use shell_escape::escape;
 use std::ffi::OsStr;
-use std::io;
 use std::path::Path;
 use std::process::{self, Command};
+use std::{fs, io};
 use walkdir::WalkDir;
 
 #[derive(Debug)]
@@ -12,6 +12,7 @@ pub enum CliError {
     IoError(io::Error),
     RustfmtNotInstalled,
     WalkDirError(walkdir::Error),
+    RaSetupActive,
 }
 
 impl From<io::Error> for CliError {
@@ -31,12 +32,23 @@ struct FmtContext {
     verbose: bool,
 }
 
+// the "main" function of cargo dev fmt
 pub fn run(check: bool, verbose: bool) {
     fn try_run(context: &FmtContext) -> Result<bool, CliError> {
         let mut success = true;
 
         let project_root = clippy_project_root();
 
+        // if we added a local rustc repo as path dependency to clippy for rust analyzer, we do NOT want to
+        // format because rustfmt would also format the entire rustc repo as it is a local
+        // dependency
+        if fs::read_to_string(project_root.join("Cargo.toml"))
+            .expect("Failed to read clippy Cargo.toml")
+            .contains(&"[target.'cfg(NOT_A_PLATFORM)'.dependencies]")
+        {
+            return Err(CliError::RaSetupActive);
+        }
+
         rustfmt_test(context)?;
 
         success &= cargo_fmt(context, project_root.as_path())?;
@@ -75,6 +87,13 @@ pub fn run(check: bool, verbose: bool) {
             CliError::WalkDirError(err) => {
                 eprintln!("error: {}", err);
             },
+            CliError::RaSetupActive => {
+                eprintln!(
+                    "error: a local rustc repo is enabled as path dependency via `cargo dev ra_setup`.
+Not formatting because that would format the local repo as well!
+Please revert the changes to Cargo.tomls first."
+                );
+            },
         }
     }
 
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index f51c45e9eb5..17cc08ee10f 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -10,6 +10,7 @@ use std::lazy::SyncLazy;
 use std::path::{Path, PathBuf};
 use walkdir::WalkDir;
 
+pub mod bless;
 pub mod fmt;
 pub mod new_lint;
 pub mod ra_setup;
diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
index 7a8cbd5251d..4fdae38e3ab 100644
--- a/clippy_dev/src/main.rs
+++ b/clippy_dev/src/main.rs
@@ -1,10 +1,53 @@
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
 
-use clap::{App, Arg, SubCommand};
-use clippy_dev::{fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
+use clap::{App, Arg, ArgMatches, SubCommand};
+use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
 
 fn main() {
-    let matches = App::new("Clippy developer tooling")
+    let matches = get_clap_config();
+
+    match matches.subcommand() {
+        ("bless", Some(_)) => {
+            bless::bless();
+        },
+        ("fmt", Some(matches)) => {
+            fmt::run(matches.is_present("check"), matches.is_present("verbose"));
+        },
+        ("update_lints", Some(matches)) => {
+            if matches.is_present("print-only") {
+                update_lints::print_lints();
+            } else if matches.is_present("check") {
+                update_lints::run(update_lints::UpdateMode::Check);
+            } else {
+                update_lints::run(update_lints::UpdateMode::Change);
+            }
+        },
+        ("new_lint", Some(matches)) => {
+            match new_lint::create(
+                matches.value_of("pass"),
+                matches.value_of("name"),
+                matches.value_of("category"),
+            ) {
+                Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
+                Err(e) => eprintln!("Unable to create lint: {}", e),
+            }
+        },
+        ("limit_stderr_length", _) => {
+            stderr_length_check::check();
+        },
+        ("ra_setup", Some(matches)) => ra_setup::run(matches.value_of("rustc-repo-path")),
+        ("serve", Some(matches)) => {
+            let port = matches.value_of("port").unwrap().parse().unwrap();
+            let lint = matches.value_of("lint");
+            serve::run(port, lint);
+        },
+        _ => {},
+    }
+}
+
+fn get_clap_config<'a>() -> ArgMatches<'a> {
+    App::new("Clippy developer tooling")
+        .subcommand(SubCommand::with_name("bless").about("bless the test output changes"))
         .subcommand(
             SubCommand::with_name("fmt")
                 .about("Run rustfmt on all projects and tests")
@@ -25,16 +68,16 @@ fn main() {
                 .about("Updates lint registration and information from the source code")
                 .long_about(
                     "Makes sure that:\n \
-                     * the lint count in README.md is correct\n \
-                     * the changelog contains markdown link references at the bottom\n \
-                     * all lint groups include the correct lints\n \
-                     * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
-                     * all lints are registered in the lint store",
+                 * the lint count in README.md is correct\n \
+                 * the changelog contains markdown link references at the bottom\n \
+                 * all lint groups include the correct lints\n \
+                 * lint modules in `clippy_lints/*` are visible in `src/lifb.rs` via `pub mod`\n \
+                 * all lints are registered in the lint store",
                 )
                 .arg(Arg::with_name("print-only").long("print-only").help(
                     "Print a table of lints to STDOUT. \
-                     This does not include deprecated and internal lints. \
-                     (Does not modify any files)",
+                 This does not include deprecated and internal lints. \
+                 (Does not modify any files)",
                 ))
                 .arg(
                     Arg::with_name("check")
@@ -88,7 +131,7 @@ fn main() {
                 .about("Ensures that stderr files do not grow longer than a certain amount of lines."),
         )
         .subcommand(
-            SubCommand::with_name("ra-setup")
+            SubCommand::with_name("ra_setup")
                 .about("Alter dependencies so rust-analyzer can find rustc internals")
                 .arg(
                     Arg::with_name("rustc-repo-path")
@@ -113,40 +156,5 @@ fn main() {
                 )
                 .arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
         )
-        .get_matches();
-
-    match matches.subcommand() {
-        ("fmt", Some(matches)) => {
-            fmt::run(matches.is_present("check"), matches.is_present("verbose"));
-        },
-        ("update_lints", Some(matches)) => {
-            if matches.is_present("print-only") {
-                update_lints::print_lints();
-            } else if matches.is_present("check") {
-                update_lints::run(update_lints::UpdateMode::Check);
-            } else {
-                update_lints::run(update_lints::UpdateMode::Change);
-            }
-        },
-        ("new_lint", Some(matches)) => {
-            match new_lint::create(
-                matches.value_of("pass"),
-                matches.value_of("name"),
-                matches.value_of("category"),
-            ) {
-                Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
-                Err(e) => eprintln!("Unable to create lint: {}", e),
-            }
-        },
-        ("limit_stderr_length", _) => {
-            stderr_length_check::check();
-        },
-        ("ra-setup", Some(matches)) => ra_setup::run(matches.value_of("rustc-repo-path")),
-        ("serve", Some(matches)) => {
-            let port = matches.value_of("port").unwrap().parse().unwrap();
-            let lint = matches.value_of("lint");
-            serve::run(port, lint);
-        },
-        _ => {},
-    }
+        .get_matches()
 }
diff --git a/clippy_dev/src/ra_setup.rs b/clippy_dev/src/ra_setup.rs
index 9d9e836cc08..40bf4a9505a 100644
--- a/clippy_dev/src/ra_setup.rs
+++ b/clippy_dev/src/ra_setup.rs
@@ -52,7 +52,7 @@ fn inject_deps_into_manifest(
     // do not inject deps if we have aleady done so
     if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
         eprintln!(
-            "cargo dev ra-setup: warning: deps already found inside {}, doing nothing.",
+            "cargo dev ra_setup: warning: deps already found inside {}, doing nothing.",
             manifest_path
         );
         return Ok(());