Skip to content

Commit 2597ef3

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

File tree

1 file changed

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

1 file changed

+66
-0
lines changed

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

Lines changed: 66 additions & 0 deletions
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,70 @@ 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: &Path, dir2: &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+
for entry in fs::read_dir(dir1).unwrap() {
246+
let entry = entry.unwrap();
247+
let entry_name = entry.file_name();
248+
let path = entry.path();
249+
250+
if path.is_dir() {
251+
recursive_diff(&path, &dir2.join(entry_name));
252+
} else {
253+
let path2 = dir2.join(entry_name);
254+
let file1 = read_file(&path);
255+
let file2 = read_file(&path2);
256+
257+
// We don't use `assert_eq!` because they are `Vec<u8>`, so not great for display.
258+
// Why not using String? Because there might be minified files or even potentially
259+
// binary ones, so that would display useless output.
260+
assert!(
261+
file1 == file2,
262+
"`{}` and `{}` have different content",
263+
path.display(),
264+
path2.display(),
265+
);
266+
}
267+
}
268+
}
269+
204270
/// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct
205271
/// containing a `cmd: Command` field and a `output` function. The provided helpers are:
206272
///

0 commit comments

Comments
 (0)