Auto merge of #125628 - matthiaskrgr:rollup-3zk9v3w, r=matthiaskrgr · rust-lang/rust@84b40fc
@@ -12,6 +12,8 @@ pub mod rustc;
1212pub mod rustdoc;
13131414use std::env;
15+use std::fs;
16+use std::io;
1517use std::path::{Path, PathBuf};
1618use std::process::{Command, Output};
1719@@ -201,6 +203,71 @@ pub fn set_host_rpath(cmd: &mut Command) {
201203});
202204}
203205206+/// Copy a directory into another.
207+pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
208+fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
209+let dst = dst.as_ref();
210+if !dst.is_dir() {
211+ fs::create_dir_all(&dst)?;
212+}
213+for entry in fs::read_dir(src)? {
214+let entry = entry?;
215+let ty = entry.file_type()?;
216+if ty.is_dir() {
217+copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
218+} else {
219+ fs::copy(entry.path(), dst.join(entry.file_name()))?;
220+}
221+}
222+Ok(())
223+}
224+225+if let Err(e) = copy_dir_all_inner(&src, &dst) {
226+// Trying to give more context about what exactly caused the failure
227+panic!(
228+"failed to copy `{}` to `{}`: {:?}",
229+ src.as_ref().display(),
230+ dst.as_ref().display(),
231+ e
232+);
233+}
234+}
235+236+/// Check that all files in `dir1` exist and have the same content in `dir2`. Panic otherwise.
237+pub fn recursive_diff(dir1: impl AsRef<Path>, dir2: impl AsRef<Path>) {
238+fn read_file(path: &Path) -> Vec<u8> {
239+match fs::read(path) {
240+Ok(c) => c,
241+Err(e) => panic!("Failed to read `{}`: {:?}", path.display(), e),
242+}
243+}
244+245+let dir2 = dir2.as_ref();
246+for entry in fs::read_dir(dir1).unwrap() {
247+let entry = entry.unwrap();
248+let entry_name = entry.file_name();
249+let path = entry.path();
250+251+if path.is_dir() {
252+recursive_diff(&path, &dir2.join(entry_name));
253+} else {
254+let path2 = dir2.join(entry_name);
255+let file1 = read_file(&path);
256+let file2 = read_file(&path2);
257+258+// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
259+// Why not using String? Because there might be minified files or even potentially
260+// binary ones, so that would display useless output.
261+assert!(
262+ file1 == file2,
263+"`{}` and `{}` have different content",
264+ path.display(),
265+ path2.display(),
266+);
267+}
268+}
269+}
270+204271/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
205272/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
206273///