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