cargo_zng/res/built_in/
copy.rs1use super::*;
2
3const COPY_HELP: &str = "
4Copy the file or dir
5
6The request file:
7 source/foo.txt.zr-copy
8 | # comment
9 | path/bar.txt
10
11Copies `path/bar.txt` to:
12 target/foo.txt
13
14Paths are relative to the Cargo workspace root
15";
16pub(super) fn copy() {
17 help(COPY_HELP);
18
19 let source = read_path(&path(ZR_REQUEST)).unwrap_or_else(|e| fatal!("{e}"));
21 let mut target = path(ZR_TARGET);
23 if target.ends_with(".zr-copy") {
25 target = target.with_file_name(source.file_name().unwrap());
26 }
27
28 if source.is_dir() {
29 println!("{}", display_path(&target));
30 fs::create_dir(&target).unwrap_or_else(|e| {
31 if e.kind() != io::ErrorKind::AlreadyExists {
32 fatal!("{e}")
33 }
34 });
35 copy_dir_all(&source, &target, true);
36 } else if source.is_file() {
37 println!("{}", display_path(&target));
38 fs::copy(source, &target).unwrap_or_else(|e| fatal!("{e}"));
39 } else if source.is_symlink() {
40 symlink_warn(&source);
41 } else {
42 warn!("cannot copy '{}', not found", source.display());
43 }
44}
45
46fn copy_dir_all(from: &Path, to: &Path, trace: bool) {
47 for entry in walkdir::WalkDir::new(from).min_depth(1).max_depth(1).sort_by_file_name() {
48 let entry = entry.unwrap_or_else(|e| fatal!("cannot walkdir entry `{}`, {e}", from.display()));
49 let from = entry.path();
50 let to = to.join(entry.file_name());
51 if entry.file_type().is_dir() {
52 fs::create_dir(&to).unwrap_or_else(|e| {
53 if e.kind() != io::ErrorKind::AlreadyExists {
54 fatal!("cannot create_dir `{}`, {e}", to.display())
55 }
56 });
57 if trace {
58 println!("{}", display_path(&to));
59 }
60 copy_dir_all(from, &to, trace);
61 } else if entry.file_type().is_file() {
62 fs::copy(from, &to).unwrap_or_else(|e| fatal!("cannot copy `{}` to `{}`, {e}", from.display(), to.display()));
63 if trace {
64 println!("{}", display_path(&to));
65 }
66 } else if entry.file_type().is_symlink() {
67 symlink_warn(entry.path())
68 }
69 }
70}