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