]> git.lizzy.rs Git - rust.git/blob - src/tools/cargotest/main.rs
update tokei and ripgrep in cargotest
[rust.git] / src / tools / cargotest / main.rs
1 use std::env;
2 use std::fs;
3 use std::path::{Path, PathBuf};
4 use std::process::Command;
5
6 struct Test {
7     repo: &'static str,
8     name: &'static str,
9     sha: &'static str,
10     lock: Option<&'static str>,
11     packages: &'static [&'static str],
12 }
13
14 const TEST_REPOS: &[Test] = &[
15     Test {
16         name: "iron",
17         repo: "https://github.com/iron/iron",
18         sha: "cf056ea5e8052c1feea6141e40ab0306715a2c33",
19         lock: None,
20         packages: &[],
21     },
22     Test {
23         name: "ripgrep",
24         repo: "https://github.com/BurntSushi/ripgrep",
25         sha: "3de31f752729525d85a3d1575ac1978733b3f7e7",
26         lock: None,
27         packages: &[],
28     },
29     Test {
30         name: "tokei",
31         repo: "https://github.com/XAMPPRocky/tokei",
32         sha: "fdf3f8cb279a7aeac0696c87e5d8b0cd946e4f9e",
33         lock: None,
34         packages: &[],
35     },
36     Test {
37         name: "xsv",
38         repo: "https://github.com/BurntSushi/xsv",
39         sha: "66956b6bfd62d6ac767a6b6499c982eae20a2c9f",
40         lock: None,
41         packages: &[],
42     },
43     Test {
44         name: "servo",
45         repo: "https://github.com/servo/servo",
46         sha: "caac107ae8145ef2fd20365e2b8fadaf09c2eb3b",
47         lock: None,
48         // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox.
49         // This takes much less time to build than all of Servo and supports stable Rust.
50         packages: &["selectors"],
51     },
52 ];
53
54 fn main() {
55     let args = env::args().collect::<Vec<_>>();
56     let cargo = &args[1];
57     let out_dir = Path::new(&args[2]);
58     let cargo = &Path::new(cargo);
59
60     for test in TEST_REPOS.iter().rev() {
61         test_repo(cargo, out_dir, test);
62     }
63 }
64
65 fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
66     println!("testing {}", test.repo);
67     let dir = clone_repo(test, out_dir);
68     if let Some(lockfile) = test.lock {
69         fs::write(&dir.join("Cargo.lock"), lockfile).unwrap();
70     }
71     if !run_cargo_test(cargo, &dir, test.packages) {
72         panic!("tests failed for {}", test.repo);
73     }
74 }
75
76 fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
77     let out_dir = out_dir.join(test.name);
78
79     if !out_dir.join(".git").is_dir() {
80         let status = Command::new("git").arg("init").arg(&out_dir).status().unwrap();
81         assert!(status.success());
82     }
83
84     // Try progressively deeper fetch depths to find the commit
85     let mut found = false;
86     for depth in &[0, 1, 10, 100, 1000, 100000] {
87         if *depth > 0 {
88             let status = Command::new("git")
89                 .arg("fetch")
90                 .arg(test.repo)
91                 .arg("master")
92                 .arg(&format!("--depth={}", depth))
93                 .current_dir(&out_dir)
94                 .status()
95                 .unwrap();
96             assert!(status.success());
97         }
98
99         let status = Command::new("git")
100             .arg("reset")
101             .arg(test.sha)
102             .arg("--hard")
103             .current_dir(&out_dir)
104             .status()
105             .unwrap();
106
107         if status.success() {
108             found = true;
109             break;
110         }
111     }
112
113     if !found {
114         panic!("unable to find commit {}", test.sha)
115     }
116     let status =
117         Command::new("git").arg("clean").arg("-fdx").current_dir(&out_dir).status().unwrap();
118     assert!(status.success());
119
120     out_dir
121 }
122
123 fn run_cargo_test(cargo_path: &Path, crate_path: &Path, packages: &[&str]) -> bool {
124     let mut command = Command::new(cargo_path);
125     command.arg("test");
126     for name in packages {
127         command.arg("-p").arg(name);
128     }
129     let status = command
130         // Disable rust-lang/cargo's cross-compile tests
131         .env("CFG_DISABLE_CROSS_TESTS", "1")
132         // Relax #![deny(warnings)] in some crates
133         .env("RUSTFLAGS", "--cap-lints warn")
134         .current_dir(crate_path)
135         .status()
136         .unwrap();
137
138     status.success()
139 }