]> git.lizzy.rs Git - rust.git/blob - src/tools/cargotest/main.rs
use top level `fs` functions where appropriate
[rust.git] / src / tools / cargotest / main.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::env;
12 use std::process::Command;
13 use std::path::{Path, PathBuf};
14 use std::fs;
15
16 struct Test {
17     repo: &'static str,
18     name: &'static str,
19     sha: &'static str,
20     lock: Option<&'static str>,
21     packages: &'static [&'static str],
22 }
23
24 const TEST_REPOS: &'static [Test] = &[
25     Test {
26         name: "iron",
27         repo: "https://github.com/iron/iron",
28         sha: "21c7dae29c3c214c08533c2a55ac649b418f2fe3",
29         lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
30         packages: &[],
31     },
32     Test {
33         name: "ripgrep",
34         repo: "https://github.com/BurntSushi/ripgrep",
35         sha: "ad9befbc1d3b5c695e7f6b6734ee1b8e683edd41",
36         lock: None,
37         packages: &[],
38     },
39     Test {
40         name: "tokei",
41         repo: "https://github.com/Aaronepower/tokei",
42         sha: "5e11c4852fe4aa086b0e4fe5885822fbe57ba928",
43         lock: None,
44         packages: &[],
45     },
46     Test {
47         name: "treeify",
48         repo: "https://github.com/dzamlo/treeify",
49         sha: "999001b223152441198f117a68fb81f57bc086dd",
50         lock: None,
51         packages: &[],
52     },
53     Test {
54         name: "xsv",
55         repo: "https://github.com/BurntSushi/xsv",
56         sha: "66956b6bfd62d6ac767a6b6499c982eae20a2c9f",
57         lock: None,
58         packages: &[],
59     },
60     Test {
61         name: "servo",
62         repo: "https://github.com/servo/servo",
63         sha: "987e376ca7a4245dbc3e0c06e963278ee1ac92d1",
64         lock: None,
65         // Only test Stylo a.k.a. Quantum CSS, the parts of Servo going into Firefox.
66         // This takes much less time to build than all of Servo and supports stable Rust.
67         packages: &["selectors"],
68     },
69     Test {
70         name: "webrender",
71         repo: "https://github.com/servo/webrender",
72         sha: "57250b2b8fa63934f80e5376a29f7dcb3f759ad6",
73         lock: None,
74         packages: &[],
75     },
76 ];
77
78 fn main() {
79     let args = env::args().collect::<Vec<_>>();
80     let ref cargo = args[1];
81     let out_dir = Path::new(&args[2]);
82     let ref cargo = Path::new(cargo);
83
84     for test in TEST_REPOS.iter().rev() {
85         test_repo(cargo, out_dir, test);
86     }
87 }
88
89 fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
90     println!("testing {}", test.repo);
91     let dir = clone_repo(test, out_dir);
92     if let Some(lockfile) = test.lock {
93         fs::write(&dir.join("Cargo.lock"), lockfile).unwrap();
94     }
95     if !run_cargo_test(cargo, &dir, test.packages) {
96         panic!("tests failed for {}", test.repo);
97     }
98 }
99
100 fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
101     let out_dir = out_dir.join(test.name);
102
103     if !out_dir.join(".git").is_dir() {
104         let status = Command::new("git")
105                          .arg("init")
106                          .arg(&out_dir)
107                          .status()
108                          .expect("");
109         assert!(status.success());
110     }
111
112     // Try progressively deeper fetch depths to find the commit
113     let mut found = false;
114     for depth in &[0, 1, 10, 100, 1000, 100000] {
115         if *depth > 0 {
116             let status = Command::new("git")
117                              .arg("fetch")
118                              .arg(test.repo)
119                              .arg("master")
120                              .arg(&format!("--depth={}", depth))
121                              .current_dir(&out_dir)
122                              .status()
123                              .expect("");
124             assert!(status.success());
125         }
126
127         let status = Command::new("git")
128                          .arg("reset")
129                          .arg(test.sha)
130                          .arg("--hard")
131                          .current_dir(&out_dir)
132                          .status()
133                          .expect("");
134
135         if status.success() {
136             found = true;
137             break;
138         }
139     }
140
141     if !found {
142         panic!("unable to find commit {}", test.sha)
143     }
144     let status = Command::new("git")
145                      .arg("clean")
146                      .arg("-fdx")
147                      .current_dir(&out_dir)
148                      .status()
149                      .unwrap();
150     assert!(status.success());
151
152     out_dir
153 }
154
155 fn run_cargo_test(cargo_path: &Path, crate_path: &Path, packages: &[&str]) -> bool {
156     let mut command = Command::new(cargo_path);
157     command.arg("test");
158     for name in packages {
159         command.arg("-p").arg(name);
160     }
161     let status = command
162         // Disable rust-lang/cargo's cross-compile tests
163         .env("CFG_DISABLE_CROSS_TESTS", "1")
164         // Relax #![deny(warnings)] in some crates
165         .env("RUSTFLAGS", "--cap-lints warn")
166         .current_dir(crate_path)
167         .status()
168         .expect("");
169
170     status.success()
171 }