|
1 | 1 | #![feature(test)] // compiletest_rs requires this attribute
|
2 | 2 | #![feature(once_cell)]
|
| 3 | +#![feature(try_blocks)] |
3 | 4 |
|
4 | 5 | use compiletest_rs as compiletest;
|
5 | 6 | use compiletest_rs::common::Mode as TestMode;
|
@@ -45,48 +46,49 @@ fn third_party_crates() -> String {
|
45 | 46 | "syn",
|
46 | 47 | ];
|
47 | 48 | let dep_dir = cargo::TARGET_LIB.join("deps");
|
48 |
| - let mut crates: HashMap<&str, PathBuf> = HashMap::with_capacity(CRATES.len()); |
49 |
| - for entry in fs::read_dir(dep_dir).unwrap() { |
50 |
| - let path = match entry { |
51 |
| - Ok(entry) => entry.path(), |
52 |
| - Err(_) => continue, |
53 |
| - }; |
54 |
| - if let Some(name) = path.file_name().and_then(OsStr::to_str) { |
55 |
| - for dep in CRATES { |
56 |
| - if name.starts_with(&format!("lib{}-", dep)) |
57 |
| - && name.rsplit('.').next().map(|ext| ext.eq_ignore_ascii_case("rlib")) == Some(true) |
58 |
| - { |
59 |
| - if let Some(old) = crates.insert(dep, path.clone()) { |
60 |
| - // Check which action should be done in order to remove compiled deps. |
61 |
| - // If pre-installed version of compiler is used, `cargo clean` will do. |
62 |
| - // Otherwise (for bootstrapped compiler), the dependencies directory |
63 |
| - // must be removed manually. |
64 |
| - let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { |
65 |
| - "remove the stageN-tools directory" |
66 |
| - } else { |
67 |
| - "run `cargo clean`" |
68 |
| - }; |
69 |
| - |
70 |
| - panic!( |
71 |
| - "\n---------------------------------------------------\n\n \ |
72 |
| - Found multiple rlibs for crate `{}`: `{:?}` and `{:?}`.\n \ |
73 |
| - Probably, you need to {} before running tests again.\n \ |
74 |
| - \nFor details on that error see https://github.com/rust-lang/rust-clippy/issues/7343 \ |
75 |
| - \n---------------------------------------------------\n", |
76 |
| - dep, old, path, suggested_action |
77 |
| - ); |
78 |
| - } |
79 |
| - break; |
80 |
| - } |
81 |
| - } |
| 49 | + let mut crates: HashMap<&str, Vec<PathBuf>> = HashMap::with_capacity(CRATES.len()); |
| 50 | + let mut flags = String::new(); |
| 51 | + for entry in fs::read_dir(dep_dir).unwrap().flatten() { |
| 52 | + let path = entry.path(); |
| 53 | + if let Some(name) = try { |
| 54 | + let name = path.file_name()?.to_str()?; |
| 55 | + let (name, _) = name.strip_suffix(".rlib")?.strip_prefix("lib")?.split_once('-')?; |
| 56 | + CRATES.iter().copied().find(|&c| c == name)? |
| 57 | + } { |
| 58 | + flags += &format!(" --extern {}={}", name, path.display()); |
| 59 | + crates.entry(name).or_default().push(path.clone()); |
82 | 60 | }
|
83 | 61 | }
|
| 62 | + crates.retain(|_, paths| paths.len() > 1); |
| 63 | + if !crates.is_empty() { |
| 64 | + let crate_names = crates.keys().map(|s| format!("`{}`", s)).collect::<Vec<_>>().join(", "); |
| 65 | + // add backslashes for an easy copy-paste `rm` command |
| 66 | + let paths = crates |
| 67 | + .into_values() |
| 68 | + .flatten() |
| 69 | + .map(|p| strip_current_dir(&p).display().to_string()) |
| 70 | + .collect::<Vec<_>>() |
| 71 | + .join(" \\\n"); |
| 72 | + // Check which action should be done in order to remove compiled deps. |
| 73 | + // If pre-installed version of compiler is used, `cargo clean` will do. |
| 74 | + // Otherwise (for bootstrapped compiler), the dependencies directory |
| 75 | + // must be removed manually. |
| 76 | + let suggested_action = if std::env::var_os("RUSTC_BOOTSTRAP").is_some() { |
| 77 | + "removing the stageN-tools directory" |
| 78 | + } else { |
| 79 | + "running `cargo clean`" |
| 80 | + }; |
84 | 81 |
|
85 |
| - let v: Vec<_> = crates |
86 |
| - .into_iter() |
87 |
| - .map(|(dep, path)| format!("--extern {}={}", dep, path.display())) |
88 |
| - .collect(); |
89 |
| - v.join(" ") |
| 82 | + panic!( |
| 83 | + "\n----------------------------------------------------------------------\n\ |
| 84 | + ERROR: Found multiple rlibs for crates: {}\n\ |
| 85 | + Try {} or remove the following files:\n\n{}\n\n\ |
| 86 | + For details on this error see https://github.com/rust-lang/rust-clippy/issues/7343\n\ |
| 87 | + ----------------------------------------------------------------------\n", |
| 88 | + crate_names, suggested_action, paths |
| 89 | + ); |
| 90 | + } |
| 91 | + flags |
90 | 92 | }
|
91 | 93 |
|
92 | 94 | fn default_config() -> compiletest::Config {
|
@@ -313,3 +315,12 @@ impl Drop for VarGuard {
|
313 | 315 | }
|
314 | 316 | }
|
315 | 317 | }
|
| 318 | + |
| 319 | +fn strip_current_dir(path: &Path) -> &Path { |
| 320 | + if let Ok(curr) = env::current_dir() { |
| 321 | + if let Ok(stripped) = path.strip_prefix(curr) { |
| 322 | + return stripped; |
| 323 | + } |
| 324 | + } |
| 325 | + path |
| 326 | +} |
0 commit comments