summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_dev/src/lint.rs
blob: 71005449b4ddf871d46f1ec86a8cc07b89ed3a8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use crate::cargo_clippy_path;
use std::process::{self, Command, ExitStatus};
use std::{fs, io};

fn exit_if_err(status: io::Result<ExitStatus>) {
    match status.expect("failed to run command").code() {
        Some(0) => {},
        Some(n) => process::exit(n),
        None => {
            eprintln!("Killed by signal");
            process::exit(1);
        },
    }
}

pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
    let is_file = match fs::metadata(path) {
        Ok(metadata) => metadata.is_file(),
        Err(e) => {
            eprintln!("Failed to read {path}: {e:?}");
            process::exit(1);
        },
    };

    if is_file {
        exit_if_err(
            Command::new("cargo")
                .args(["run", "--bin", "clippy-driver", "--"])
                .args(["-L", "./target/debug"])
                .args(["-Z", "no-codegen"])
                .args(["--edition", "2021"])
                .arg(path)
                .args(args)
                .status(),
        );
    } else {
        exit_if_err(Command::new("cargo").arg("build").status());

        // Run in a tempdir as changes to clippy do not retrigger linting
        let target = tempfile::Builder::new()
            .prefix("clippy")
            .tempdir()
            .expect("failed to create tempdir");

        let status = Command::new(cargo_clippy_path())
            .arg("clippy")
            .args(args)
            .current_dir(path)
            .env("CARGO_TARGET_DIR", target.as_ref())
            .status();

        target.close().expect("failed to remove tempdir");
        exit_if_err(status);
    }
}