1 mod progress;
2 
3 use self::progress::Progress;
4 use anyhow::Result;
5 use flate2::read::GzDecoder;
6 use std::fs;
7 use std::path::Path;
8 use tar::Archive;
9 use walkdir::DirEntry;
10 
11 const REVISION: &str = "81e754c359c471f91263813c46c67955071716a7";
12 
13 #[rustfmt::skip]
14 static EXCLUDE: &[&str] = &[
15     // Deprecated anonymous parameter syntax in traits
16     "test/ui/issues/issue-13105.rs",
17     "test/ui/issues/issue-13775.rs",
18     "test/ui/issues/issue-34074.rs",
19     "test/ui/proc-macro/trait-fn-args-2015.rs",
20 
21     // not actually test cases
22     "test/rustdoc-ui/test-compile-fail2.rs",
23     "test/rustdoc-ui/test-compile-fail3.rs",
24     "test/ui/include-single-expr-helper.rs",
25     "test/ui/include-single-expr-helper-1.rs",
26     "test/ui/issues/auxiliary/issue-21146-inc.rs",
27     "test/ui/json-bom-plus-crlf-multifile-aux.rs",
28     "test/ui/lint/expansion-time-include.rs",
29     "test/ui/macros/auxiliary/macro-comma-support.rs",
30     "test/ui/macros/auxiliary/macro-include-items-expr.rs",
31 ];
32 
base_dir_filter(entry: &DirEntry) -> bool33 pub fn base_dir_filter(entry: &DirEntry) -> bool {
34     let path = entry.path();
35     if path.is_dir() {
36         return true; // otherwise walkdir does not visit the files
37     }
38     if path.extension().map(|e| e != "rs").unwrap_or(true) {
39         return false;
40     }
41 
42     let mut path_string = path.to_string_lossy();
43     if cfg!(windows) {
44         path_string = path_string.replace('\\', "/").into();
45     }
46     let path = if let Some(path) = path_string.strip_prefix("tests/rust/src/") {
47         path
48     } else if let Some(path) = path_string.strip_prefix("tests/rust/library/") {
49         path
50     } else {
51         panic!("unexpected path in Rust dist: {}", path_string);
52     };
53 
54     // TODO assert that parsing fails on the parse-fail cases
55     if path.starts_with("test/parse-fail")
56         || path.starts_with("test/compile-fail")
57         || path.starts_with("test/rustfix")
58     {
59         return false;
60     }
61 
62     if path.starts_with("test/ui") {
63         let stderr_path = entry.path().with_extension("stderr");
64         if stderr_path.exists() {
65             // Expected to fail in some way
66             return false;
67         }
68     }
69 
70     !EXCLUDE.contains(&path)
71 }
72 
73 #[allow(dead_code)]
edition(path: &Path) -> &'static str74 pub fn edition(path: &Path) -> &'static str {
75     if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
76         "2015"
77     } else {
78         "2018"
79     }
80 }
81 
clone_rust()82 pub fn clone_rust() {
83     let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
84         Err(_) => true,
85         Ok(contents) => contents.trim() != REVISION,
86     };
87     if needs_clone {
88         download_and_unpack().unwrap();
89     }
90     let mut missing = String::new();
91     let test_src = Path::new("tests/rust/src");
92     for exclude in EXCLUDE {
93         if !test_src.join(exclude).exists() {
94             missing += "\ntests/rust/src/";
95             missing += exclude;
96         }
97     }
98     if !missing.is_empty() {
99         panic!("excluded test file does not exist:{}\n", missing);
100     }
101 }
102 
download_and_unpack() -> Result<()>103 fn download_and_unpack() -> Result<()> {
104     let url = format!(
105         "https://github.com/rust-lang/rust/archive/{}.tar.gz",
106         REVISION
107     );
108     let response = reqwest::blocking::get(&url)?.error_for_status()?;
109     let progress = Progress::new(response);
110     let decoder = GzDecoder::new(progress);
111     let mut archive = Archive::new(decoder);
112     let prefix = format!("rust-{}", REVISION);
113 
114     let tests_rust = Path::new("tests/rust");
115     if tests_rust.exists() {
116         fs::remove_dir_all(tests_rust)?;
117     }
118 
119     for entry in archive.entries()? {
120         let mut entry = entry?;
121         let path = entry.path()?;
122         if path == Path::new("pax_global_header") {
123             continue;
124         }
125         let relative = path.strip_prefix(&prefix)?;
126         let out = tests_rust.join(relative);
127         entry.unpack(&out)?;
128     }
129 
130     fs::write("tests/rust/COMMIT", REVISION)?;
131     Ok(())
132 }
133