use std::collections::{HashSet, HashMap};
use std::env;
use std::fs::{self, OpenOptions, File};
-use std::io::{self, Seek, SeekFrom, Write, Read};
+use std::io::{Seek, SeekFrom, Write, Read};
use std::path::{PathBuf, Path};
use std::process::{self, Command};
use std::slice;
if !src.exists() {
panic!("Error: File \"{}\" not found!", src.display());
}
- let mut s = t!(fs::File::open(&src));
- let mut d = t!(fs::File::create(&dst));
- io::copy(&mut s, &mut d).expect("failed to copy");
+ let metadata = t!(src.symlink_metadata());
+ if let Err(e) = fs::copy(&src, &dst) {
+ panic!("failed to copy `{}` to `{}`: {}", src.display(),
+ dst.display(), e)
+ }
+ t!(fs::set_permissions(&dst, metadata.permissions()));
+ let atime = FileTime::from_last_access_time(&metadata);
+ let mtime = FileTime::from_last_modification_time(&metadata);
+ t!(filetime::set_file_times(&dst, atime, mtime));
}
chmod(&dst, perms);
}
output_base_dir(config, testpaths, revision).join("stamp")
}
-/// Return an iterator over timestamps of files in the directory at `path`.
-fn collect_timestamps(path: &PathBuf) -> impl Iterator<Item=FileTime> {
- WalkDir::new(path)
- .into_iter()
- .map(|entry| entry.unwrap())
- .filter(|entry| entry.file_type().is_file())
- .map(|entry| mtime(entry.path()))
-}
-
fn up_to_date(
config: &Config,
testpaths: &TestPaths,
let rust_src_dir = config
.find_rust_src_root()
.expect("Could not find Rust source root");
- let stamp = mtime(&stamp_name);
- let mut inputs = vec![mtime(&testpaths.file), mtime(&config.rustc_path)];
+ let stamp = Stamp::from_path(&stamp_name);
+ let mut inputs = vec![Stamp::from_path(&testpaths.file), Stamp::from_path(&config.rustc_path)];
inputs.extend(
props
.aux
.iter()
- .map(|aux| mtime(&testpaths.file.parent().unwrap().join("auxiliary").join(aux))),
+ .map(|aux| {
+ Stamp::from_path(&testpaths.file.parent().unwrap().join("auxiliary").join(aux))
+ }),
);
// Relevant pretty printer files
let pretty_printer_files = [
"src/etc/lldb_rust_formatters.py",
];
inputs.extend(pretty_printer_files.iter().map(|pretty_printer_file| {
- mtime(&rust_src_dir.join(pretty_printer_file))
+ Stamp::from_path(&rust_src_dir.join(pretty_printer_file))
}));
- inputs.extend(collect_timestamps(&config.run_lib_path));
+ inputs.extend(Stamp::from_dir(&config.run_lib_path));
if let Some(ref rustdoc_path) = config.rustdoc_path {
- inputs.push(mtime(&rustdoc_path));
- inputs.push(mtime(&rust_src_dir.join("src/etc/htmldocck.py")));
+ inputs.push(Stamp::from_path(&rustdoc_path));
+ inputs.push(Stamp::from_path(&rust_src_dir.join("src/etc/htmldocck.py")));
}
// UI test files.
inputs.extend(UI_EXTENSIONS.iter().map(|extension| {
let path = &expected_output_path(testpaths, revision, &config.compare_mode, extension);
- mtime(path)
+ Stamp::from_path(path)
}));
// Compiletest itself.
- inputs.extend(collect_timestamps(&rust_src_dir.join("src/tools/compiletest/")));
+ inputs.extend(Stamp::from_dir(&rust_src_dir.join("src/tools/compiletest/")));
- inputs.iter().any(|input| *input > stamp)
+ inputs.iter().any(|input| input > &stamp)
+}
+
+#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)]
+struct Stamp {
+ time: FileTime,
+ file: PathBuf,
+}
+
+impl Stamp {
+ fn from_path(p: &Path) -> Self {
+ Stamp {
+ time: mtime(&p),
+ file: p.into(),
+ }
+ }
+
+ fn from_dir(path: &Path) -> impl Iterator<Item=Stamp> {
+ WalkDir::new(path)
+ .into_iter()
+ .map(|entry| entry.unwrap())
+ .filter(|entry| entry.file_type().is_file())
+ .map(|entry| Stamp::from_path(entry.path()))
+ }
}
fn mtime(path: &Path) -> FileTime {