Skip to content

Instantly share code, notes, and snippets.

@sleexyz
Created June 6, 2023 05:10
Show Gist options
  • Save sleexyz/12b2a16267140ed082a8349016fb4acf to your computer and use it in GitHub Desktop.
Save sleexyz/12b2a16267140ed082a8349016fb4acf to your computer and use it in GitHub Desktop.
keeps relative symlinks, derefs absolute symlinks
use std::env;
use std::os::unix::fs::symlink;
use std::fs;
use std::path::Path;
use std::io::{self, Error, ErrorKind};
fn copy_dir_recursive(src: &Path, dest: &Path) -> io::Result<()> {
if !src.is_dir() {
return Err(Error::new(ErrorKind::NotFound, "Source directory does not exist."));
}
if !dest.exists() {
fs::create_dir_all(dest)?;
}
let entries = fs::read_dir(src)?;
for entry in entries {
let entry = entry?;
let entry_path = entry.path();
let entry_name = entry.file_name();
let dest_path = dest.join(&entry_name);
if entry_path.is_dir() {
// println!("Recursing into {:?}", entry_path);
copy_dir_recursive(&entry_path, &dest_path)?;
} else if entry_path.is_symlink() {
let symlink_target = fs::read_link(&entry_path)?;
// println!("Symlink target: {:?}", symlink_target);
if symlink_target.is_absolute() {
// println!("Symlink target is absolute: {:?}", symlink_target);
fs::copy(&symlink_target, &dest_path)?;
} else {
println!("Symlink target is relative: {:?}", symlink_target);
symlink(&symlink_target, &dest_path)?;
}
} else if entry_path.is_file() {
// println!("Copying {:?} to {:?}", entry_path, dest_path);
fs::copy(&entry_path, &dest_path)?;
}
}
Ok(())
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 3 {
println!("Usage: {} <source_directory> <destination_directory>", args[0]);
return;
}
let src_dir = Path::new(&args[1]);
let dest_dir = Path::new(&args[2]);
if let Err(err) = copy_dir_recursive(src_dir, dest_dir) {
eprintln!("Error: {}", err);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment