]> git.lizzy.rs Git - rust.git/blob - clippy_dev/src/crater.rs
cargo clippy dev: fix extraction of downloaded crates
[rust.git] / clippy_dev / src / crater.rs
1 use std::path::PathBuf;
2 use std::process::Command;
3
4 // represents an archive we download from crates.io
5 #[derive(Debug)]
6 struct KrateSource {
7     version: String,
8     name: String,
9 }
10
11 // represents the extracted sourcecode of a crate
12 #[derive(Debug)]
13 struct Krate {
14     version: String,
15     name: String,
16     path: PathBuf,
17 }
18
19 impl KrateSource {
20     fn new(name: &str, version: &str) -> Self {
21         KrateSource {
22             version: version.into(),
23             name: name.into(),
24         }
25     }
26     fn download_and_extract(&self) -> Krate {
27         let extract_dir = PathBuf::from("target/crater/crates");
28
29         // download
30         let krate_download_dir = PathBuf::from("target/crater/downloads");
31
32         let url = format!(
33             "https://crates.io/api/v1/crates/{}/{}/download",
34             self.name, self.version
35         );
36         println!("Downloading {}, {} / {}", self.name, self.version, url);
37         let _ = std::fs::create_dir("target/crater/");
38
39         let _ = std::fs::create_dir(&krate_download_dir);
40         let _ = std::fs::create_dir(&extract_dir);
41
42         let krate_name = format!("{}-{}.crate.tar.gz", &self.name, &self.version);
43         let krate_file_path = krate_download_dir.join(krate_name);
44         let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap();
45         let mut krate_req = ureq::get(&url).call().unwrap().into_reader();
46         std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
47         // unzip the tarball
48         let dl = std::fs::File::open(krate_file_path).unwrap();
49
50         let ungz_tar = flate2::read::GzDecoder::new(dl);
51         // extract the tar archive
52         let mut archiv = tar::Archive::new(ungz_tar);
53         let extract_path = extract_dir.join(format!("{}-{}/", self.name, self.version));
54         archiv.unpack(&extract_path).expect("Failed to extract!");
55         // extracted
56
57         Krate {
58             version: self.version.clone(),
59             name: self.name.clone(),
60             path: extract_path,
61         }
62     }
63 }
64
65 impl Krate {
66     fn run_clippy_lints(&self) -> String {
67         todo!();
68     }
69 }
70
71 fn build_clippy() {
72     Command::new("cargo")
73         .arg("build")
74         .output()
75         .expect("Failed to build clippy!");
76 }
77
78 // the main fn
79 pub fn run() {
80     let cargo_clippy_path: PathBuf = PathBuf::from("target/debug/cargo-clippy");
81     let clippy_driver_path: PathBuf = PathBuf::from("target/debug/clippy-driver");
82
83     // crates we want to check:
84     let krates: Vec<KrateSource> = vec![KrateSource::new("cargo", "0.49.0"), KrateSource::new("regex", "1.4.2")];
85
86     println!("Compiling clippy...");
87     build_clippy();
88     println!("Done compiling");
89
90     // assert that clippy is found
91     assert!(
92         cargo_clippy_path.is_file(),
93         "target/debug/cargo-clippy binary not found! {}",
94         cargo_clippy_path.display()
95     );
96     assert!(
97         clippy_driver_path.is_file(),
98         "target/debug/clippy-driver binary not found! {}",
99         clippy_driver_path.display()
100     );
101
102     // download and extract the crates, then run clippy on them and collect clippys warnings
103     let _clippy_lint_results: Vec<String> = krates
104         .into_iter()
105         .map(|krate| krate.download_and_extract())
106         .map(|krate| krate.run_clippy_lints())
107         .collect::<Vec<String>>();
108 }