feat, fix: make -n flag busybox-compatible, add dereferncing of symlinks in cross::fs
This commit is contained in:
parent
95a5c3f565
commit
900f84f7ec
2 changed files with 47 additions and 18 deletions
|
|
@ -1,7 +1,6 @@
|
|||
use boxutils::args::ArgParser;
|
||||
use boxutils::commands::Command;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
pub struct Ln;
|
||||
|
||||
|
|
@ -17,6 +16,7 @@ impl Command for Ln {
|
|||
.add_option("-S")
|
||||
.parse_args("ln");
|
||||
|
||||
let mut dereference = true;
|
||||
let help = args.get_normal_args().len() != 2 || args.get_flag("--help");
|
||||
if help {
|
||||
println!("Usage: ln [-sfnbtv] [-S SUF] TARGET LINK");
|
||||
|
|
@ -31,7 +31,7 @@ impl Command for Ln {
|
|||
}
|
||||
|
||||
if args.get_flag("-f") {
|
||||
if fs::metadata(&destination).is_ok() {
|
||||
if fs::exists(&destination).unwrap() {
|
||||
if fs::metadata(&destination).unwrap().is_dir() {
|
||||
fs::remove_dir_all(&destination).unwrap();
|
||||
} else {
|
||||
|
|
@ -41,10 +41,7 @@ impl Command for Ln {
|
|||
}
|
||||
|
||||
if args.get_flag("-n") {
|
||||
if Path::new(&destination).exists() {
|
||||
println!("ln: {} exists, stopping...", destination);
|
||||
return;
|
||||
}
|
||||
dereference = false;
|
||||
}
|
||||
|
||||
if args.get_flag("-b") {
|
||||
|
|
@ -54,13 +51,13 @@ impl Command for Ln {
|
|||
}
|
||||
|
||||
if args.get_flag("-s") {
|
||||
let symlink_result = boxutils::cross::fs::symlink(to_be_linked, destination);
|
||||
let symlink_result = boxutils::cross::fs::symlink(to_be_linked, destination, dereference);
|
||||
|
||||
if let Err(e) = symlink_result {
|
||||
eprintln!("ln: failed to create symlink: {}", e);
|
||||
}
|
||||
} else {
|
||||
if let Err(e) = boxutils::cross::fs::hard_link(to_be_linked, destination) {
|
||||
if let Err(e) = boxutils::cross::fs::hard_link(to_be_linked, destination, dereference) {
|
||||
eprintln!("ln: failed to create hard link: {}", e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,56 @@ use std::os::unix::fs::symlink as unix_symlink;
|
|||
#[cfg(windows)]
|
||||
use std::os::windows::fs::{symlink_dir, symlink_file};
|
||||
|
||||
fn deref(to_be_dereferenced: String) -> String {
|
||||
let mut metadata = fs::metadata(&to_be_dereferenced).unwrap();
|
||||
let file = &to_be_dereferenced;
|
||||
let mut new_file = file.clone();
|
||||
while metadata.is_symlink() {
|
||||
new_file = String::from(fs::read_link(new_file.to_string()).unwrap().into_os_string().into_string().unwrap());
|
||||
metadata = fs::metadata(&new_file).unwrap()
|
||||
}
|
||||
|
||||
new_file
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn symlink(to_be_linked: String, destination: String) -> std::io::Result<()> {
|
||||
pub fn symlink(to_be_linked: String, destination: String, dereference: bool) -> std::io::Result<()> {
|
||||
if !dereference {
|
||||
let target_metadata = fs::metadata(&to_be_linked)?;
|
||||
if target_metadata.is_dir() {
|
||||
symlink_dir(&to_be_linked, &destination)
|
||||
} else {
|
||||
symlink_file(&to_be_linked, &destination)
|
||||
}?;
|
||||
} else {
|
||||
let dereferenced = deref(to_be_linked.clone());
|
||||
let deref_metadata = fs::metadata(&dereferenced)?;
|
||||
if deref_metadata.is_dir() {
|
||||
symlink_dir(&dereferenced, &destination)
|
||||
} else {
|
||||
symlink_file(&dereferenced, &destination)
|
||||
}?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn symlink(to_be_linked: String, destination: String) -> std::io::Result<()> {
|
||||
pub fn symlink(to_be_linked: String, destination: String, dereference: bool) -> std::io::Result<()> {
|
||||
if !dereference {
|
||||
unix_symlink(to_be_linked, destination)?;
|
||||
} else {
|
||||
let dereferenced = deref(to_be_linked);
|
||||
unix_symlink(dereferenced, destination)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn hard_link(to_be_linked: String, destination: String) -> std::io::Result<()> {
|
||||
pub fn hard_link(to_be_linked: String, destination: String, dereference: bool) -> std::io::Result<()> {
|
||||
if !dereference {
|
||||
fs::hard_link(to_be_linked, destination)?;
|
||||
} else {
|
||||
let dereferenced = deref(to_be_linked);
|
||||
fs::hard_link(dereferenced, destination)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue