use super::*;
use std::fs::create_dir_all;
use std::fs::File;
use std::io::read_to_string;
#[cfg(unix)]
use std::os::unix::fs::{symlink, PermissionsExt};
#[test]
fn copy_basic() {
std::env::set_var("RUST_LOG", "DEBUG");
let _ = env_logger::builder().try_init();
let src = "basic_src";
let dst = "basic_dest";
create_dir_all(format!("{src}/level1/level2/level3")).unwrap();
File::create(format!("{src}/test")).unwrap();
File::create(format!("{src}/level1/other_file")).unwrap();
#[cfg(unix)]
{
File::create(format!("{src}/exec_file")).unwrap();
std::fs::set_permissions(
format!("{src}/exec_file"),
std::fs::Permissions::from_mode(0o755),
)
.unwrap();
symlink("exec_file", format!("{src}/symlink")).unwrap();
symlink("does_not_exist", format!("{src}/dangling_symlink")).unwrap();
}
CopyBuilder::new(src, dst)
.overwrite(true)
.overwrite_if_newer(true)
.run()
.unwrap();
#[cfg(unix)]
{
let f = File::open(format!("{dst}/exec_file")).unwrap();
let metadata = f.metadata().unwrap();
let permissions = metadata.permissions();
println!("permissions: {:o}", permissions.mode());
assert_eq!(permissions.mode(), 33261);
assert_eq!(
Path::new("exec_file"),
read_link(format!("{dst}/symlink")).unwrap().as_path()
);
assert_eq!(
Path::new("does_not_exist"),
read_link(format!("{dst}/dangling_symlink"))
.unwrap()
.as_path()
);
}
std::fs::remove_dir_all(src).unwrap();
std::fs::remove_dir_all(dst).unwrap();
}
#[test]
fn copy_subdir() {
std::env::set_var("RUST_LOG", "debug");
let _ = env_logger::try_init();
create_dir_all("source/subdir").unwrap();
create_dir_all("source/this_should_copy").unwrap();
File::create("source/this_should_copy/file.doc").unwrap();
File::create("source/a.jpg").unwrap();
File::create("source/b.jpg").unwrap();
File::create("source/d.txt").unwrap();
CopyBuilder::new("source", "source/subdir").run().unwrap();
std::fs::remove_dir_all("source").unwrap();
}
#[cfg(feature = "jwalk")]
#[test]
fn copy_subdir_jwalk() {
use std::fs::File;
use std::io::Write;
let source_dir = "overwrite_sourcej";
let dest_dir = "overwrite_destj";
std::env::set_var("RUST_LOG", "debug");
let _ = env_logger::try_init();
create_dir_all(source_dir).unwrap();
create_dir_all(dest_dir).unwrap();
File::create(format!("{source_dir}/a.txt")).unwrap();
let mut file_b = File::create(format!("{source_dir}/b.txt")).unwrap();
let contents = "Contents changed";
CopyBuilder::new(source_dir, dest_dir).run().unwrap();
write!(file_b, "{contents}").unwrap();
CopyBuilder::new(source_dir, dest_dir)
.overwrite(true)
.run()
.unwrap();
let s = read_to_string(File::open(format!("{dest_dir}/b.txt")).unwrap()).unwrap();
assert!(s == contents, "Destination was not overwritten");
std::fs::remove_dir_all(source_dir).unwrap();
std::fs::remove_dir_all(dest_dir).unwrap();
}
#[test]
fn copy_overwrite() {
use std::fs::File;
use std::io::Write;
let source_dir = "overwrite_source";
let dest_dir = "overwrite_dest";
std::env::set_var("RUST_LOG", "debug");
let _ = env_logger::try_init();
create_dir_all(source_dir).unwrap();
create_dir_all(dest_dir).unwrap();
File::create(format!("{source_dir}/a.txt")).unwrap();
let mut file_b = File::create(format!("{source_dir}/b.txt")).unwrap();
let contents = "Contents changed";
CopyBuilder::new(source_dir, dest_dir).run().unwrap();
write!(file_b, "{contents}").unwrap();
CopyBuilder::new(source_dir, dest_dir)
.overwrite(true)
.run()
.unwrap();
let s = read_to_string(File::open(format!("{dest_dir}/b.txt")).unwrap()).unwrap();
assert!(s == contents, "Destination was not overwritten");
std::fs::remove_dir_all(source_dir).unwrap();
std::fs::remove_dir_all(dest_dir).unwrap();
}
#[test]
fn copy_exclude() {
std::env::set_var("RUST_LOG", "DEBUG");
let _ = env_logger::builder().try_init();
let src = "ex_src";
let dst = "ex_dest";
create_dir_all(src).unwrap();
File::create(format!("{src}/foo")).unwrap();
File::create(format!("{src}/bar")).unwrap();
CopyBuilder::new(src, dst)
.overwrite(true)
.overwrite_if_newer(true)
.with_exclude_filter("foo")
.run()
.unwrap();
assert!(!Path::new(&format!("{}/foo", dst)).is_file());
std::fs::remove_dir_all(src).unwrap();
std::fs::remove_dir_all(dst).unwrap();
}
#[test]
fn copy_include() {
std::env::set_var("RUST_LOG", "DEBUG");
let _ = env_logger::builder().try_init();
let src = "in_src";
let dst = "in_dest";
create_dir_all(src).unwrap();
File::create(format!("{src}/foo")).unwrap();
File::create(format!("{src}/bar")).unwrap();
File::create(format!("{src}/baz")).unwrap();
CopyBuilder::new(src, dst)
.overwrite(true)
.overwrite_if_newer(true)
.with_include_filter("foo")
.with_include_filter("baz")
.run()
.unwrap();
assert!(Path::new(&format!("{dst}/foo")).is_file());
assert!(!Path::new(&format!("{dst}/bar")).exists());
assert!(Path::new(&format!("{dst}/baz")).exists());
std::fs::remove_dir_all(src).unwrap();
std::fs::remove_dir_all(dst).unwrap();
}
#[test]
fn copy_empty_include() {
std::env::set_var("RUST_LOG", "DEBUG");
let _ = env_logger::builder().try_init();
let src = "in_src_inc";
let dst = "in_dest_inc";
create_dir_all(src).unwrap();
File::create(format!("{src}/foo")).unwrap();
File::create(format!("{src}/bar")).unwrap();
File::create(format!("{src}/baz")).unwrap();
CopyBuilder::new(src, dst)
.overwrite(true)
.overwrite_if_newer(true)
.run()
.unwrap();
assert!(Path::new(&format!("{dst}/foo")).is_file());
assert!(Path::new(&format!("{dst}/bar")).exists());
assert!(Path::new(&format!("{dst}/baz")).exists());
std::fs::remove_dir_all(src).unwrap();
std::fs::remove_dir_all(dst).unwrap();
}
#[test]
fn copy_cargo() {
std::env::set_var("RUST_LOG", "DEBUG");
let _ = env_logger::builder().try_init();
let url = "https://github.com/rust-lang/cargo/archive/master.zip";
let sample_dir = "cargo";
let output_dir = format!("{sample_dir}_output");
let archive = format!("{sample_dir}.zip");
info!("Expanding {archive}");
let mut resp = reqwest::blocking::get(url).unwrap();
let mut out = File::create(&archive).expect("failed to create file");
std::io::copy(&mut resp, &mut out).expect("failed to copy content");
let reader = std::fs::File::open(&archive).unwrap();
unzip::Unzipper::new(reader, sample_dir)
.unzip()
.expect("Could not expand cargo sources");
let num_input_files = WalkDir::new(&sample_dir)
.into_iter()
.filter_map(|e| e.ok())
.count();
CopyBuilder::new(
&Path::new(sample_dir).canonicalize().unwrap(),
&PathBuf::from(&output_dir),
)
.run()
.unwrap();
let num_output_files = WalkDir::new(&output_dir)
.into_iter()
.filter_map(|e| e.ok())
.count();
assert_eq!(num_output_files, num_input_files);
std::fs::remove_dir_all(sample_dir).unwrap();
std::fs::remove_dir_all(output_dir).unwrap();
std::fs::remove_file(archive).unwrap();
}
#[test]
fn copy_cargo_progress() {
std::env::set_var("RUST_LOG", "INFO");
let _ = env_logger::builder().try_init();
let url = "https://github.com/rust-lang/cargo/archive/master.zip";
let sample_dir = "cargo_progress";
let output_dir = format!("{sample_dir}_output");
let archive = format!("{sample_dir}.zip");
info!("Expanding {archive}");
let mut resp = reqwest::blocking::get(url).unwrap();
let mut out = File::create(&archive).expect("failed to create file");
std::io::copy(&mut resp, &mut out).expect("failed to copy content");
let reader = std::fs::File::open(&archive).unwrap();
unzip::Unzipper::new(reader, &sample_dir)
.unzip()
.expect("Could not expand cargo sources");
let num_input_files = WalkDir::new(&sample_dir)
.into_iter()
.filter_map(|e| e.ok())
.count();
CopyBuilder::new(
&Path::new(&sample_dir).canonicalize().unwrap(),
&PathBuf::from(&output_dir),
)
.with_progress(|all, done| {
info!("copied {done}/{all}");
})
.run()
.unwrap();
let num_output_files = WalkDir::new(&output_dir)
.into_iter()
.filter_map(|e| e.ok())
.count();
assert_eq!(num_output_files, num_input_files);
std::fs::remove_dir_all(sample_dir).unwrap();
std::fs::remove_dir_all(output_dir).unwrap();
std::fs::remove_file(archive).unwrap();
}