Skip to content

Commit 90fec5a

Browse files
Add copy_dir_all and recursive_diff functions to run-make-support
1 parent 21e6de7 commit 90fec5a

File tree

1 file changed

+67
-0
lines changed
  • src/tools/run-make-support/src

1 file changed

+67
-0
lines changed

src/tools/run-make-support/src/lib.rs

+67
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub mod rustc;
1212
pub mod rustdoc;
1313

1414
use std::env;
15+
use std::fs;
16+
use std::io;
1517
use std::path::{Path, PathBuf};
1618
use std::process::{Command, Output};
1719

@@ -201,6 +203,71 @@ pub fn set_host_rpath(cmd: &mut Command) {
201203
});
202204
}
203205

206+
/// 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
///

0 commit comments

Comments
 (0)