]> git.lizzy.rs Git - rust.git/blob - clippy_dev/src/crater.rs
cargo dev crater: work on downloading and extracting crate sources
[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(version: &str, name: &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         print!("Downloading {}, {}", self.name, self.version);
37
38         let krate_name = format!("{}-{}.crate", &self.name, &self.version);
39         let mut krate_dest = std::fs::File::create(krate_download_dir.join(krate_name)).unwrap();
40         let mut krate_req = ureq::get(&url).call().unwrap().into_reader();
41         std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
42
43         // extract
44         let krate = krate_dest;
45         let tar = flate2::read::GzDecoder::new(krate);
46         let mut archiv = tar::Archive::new(tar);
47         let extracted_path = extract_dir.join(format!("{}-{}/", self.name, self.version));
48         archiv.unpack(&extracted_path).expect("Failed to extract!");
49
50         Krate {
51             version: self.version.clone(),
52             name: self.name.clone(),
53             path: extracted_path,
54         }
55     }
56 }
57
58 impl Krate {
59     fn run_clippy_lints(&self) -> String {
60         todo!();
61     }
62 }
63
64 fn build_clippy() {
65     Command::new("cargo")
66         .arg("build")
67         .output()
68         .expect("Failed to build clippy!");
69 }
70
71 // the main fn
72 pub(crate) fn run() {
73     let cargo_clippy_path: PathBuf = PathBuf::from("target/debug/cargo-clippy");
74     let clippy_driver_path: PathBuf = PathBuf::from("target/debug/cargo-driver");
75
76     // crates we want to check:
77     let krates: Vec<KrateSource> = vec![KrateSource::new("cargo", "0.49.0"), KrateSource::new("regex", "1.4.2")];
78
79     build_clippy();
80     // assert that clippy is found
81     assert!(
82         cargo_clippy_path.is_file(),
83         "target/debug/cargo-clippy binary not found!"
84     );
85     assert!(
86         clippy_driver_path.is_file(),
87         "target/debug/clippy-driver binary not found!"
88     );
89
90     // download and extract the crates, then run clippy on them and collect clippys warnings
91     let clippy_lint_results: Vec<String> = krates
92         .into_iter()
93         .map(|krate| krate.download_and_extract())
94         .map(|krate| krate.run_clippy_lints())
95         .collect::<Vec<String>>();
96 }