]> git.lizzy.rs Git - rust.git/blob - src/tools/cargotest/main.rs
Rollup merge of #35558 - lukehinds:master, r=nikomatsakis
[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::File;
15 use std::io::Write;
16
17 struct Test {
18     repo: &'static str,
19     name: &'static str,
20     sha: &'static str,
21     lock: Option<&'static str>,
22 }
23
24 const TEST_REPOS: &'static [Test] = &[Test {
25                                           name: "cargo",
26                                           repo: "https://github.com/rust-lang/cargo",
27                                           sha: "2d85908217f99a30aa5f68e05a8980704bb71fad",
28                                           lock: None,
29                                       },
30                                       Test {
31                                           name: "iron",
32                                           repo: "https://github.com/iron/iron",
33                                           sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
34                                           lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
35                                       }];
36
37
38 fn main() {
39     let args = env::args().collect::<Vec<_>>();
40     let ref cargo = args[1];
41     let out_dir = Path::new(&args[2]);
42     let ref cargo = Path::new(cargo);
43
44     for test in TEST_REPOS.iter().rev() {
45         test_repo(cargo, out_dir, test);
46     }
47 }
48
49 fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
50     println!("testing {}", test.repo);
51     let dir = clone_repo(test, out_dir);
52     if let Some(lockfile) = test.lock {
53         File::create(&dir.join("Cargo.lock"))
54             .expect("")
55             .write_all(lockfile.as_bytes())
56             .expect("");
57     }
58     if !run_cargo_test(cargo, &dir) {
59         panic!("tests failed for {}", test.repo);
60     }
61 }
62
63 fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
64     let out_dir = out_dir.join(test.name);
65
66     if !out_dir.join(".git").is_dir() {
67         let status = Command::new("git")
68                          .arg("init")
69                          .arg(&out_dir)
70                          .status()
71                          .expect("");
72         assert!(status.success());
73     }
74
75     // Try progressively deeper fetch depths to find the commit
76     let mut found = false;
77     for depth in &[0, 1, 10, 100, 1000, 100000] {
78         if *depth > 0 {
79             let status = Command::new("git")
80                              .arg("fetch")
81                              .arg(test.repo)
82                              .arg("master")
83                              .arg(&format!("--depth={}", depth))
84                              .current_dir(&out_dir)
85                              .status()
86                              .expect("");
87             assert!(status.success());
88         }
89
90         let status = Command::new("git")
91                          .arg("reset")
92                          .arg(test.sha)
93                          .arg("--hard")
94                          .current_dir(&out_dir)
95                          .status()
96                          .expect("");
97
98         if status.success() {
99             found = true;
100             break;
101         }
102     }
103
104     if !found {
105         panic!("unable to find commit {}", test.sha)
106     }
107     let status = Command::new("git")
108                      .arg("clean")
109                      .arg("-fdx")
110                      .current_dir(&out_dir)
111                      .status()
112                      .unwrap();
113     assert!(status.success());
114
115     out_dir
116 }
117
118 fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
119     let status = Command::new(cargo_path)
120         .arg("test")
121         // Disable rust-lang/cargo's cross-compile tests
122         .env("CFG_DISABLE_CROSS_TESTS", "1")
123         .current_dir(crate_path)
124         .status()
125         .expect("");
126
127     status.success()
128 }