refact: refactor the ln command, to make it windows compatible

This commit is contained in:
Teesh 2025-03-30 10:04:11 +03:00
parent 9d1b21ca0c
commit f4260b668e

View file

@ -1,17 +1,18 @@
use boxutils::args::ArgParser;
use boxutils::commands::Command;
use std::env;
use std::ops::Not;
use std::process::exit;
use std::fs;
#[cfg(unix)]
use std::os::unix::fs::symlink;
#[cfg(windows)]
use std::os::windows::fs::{symlink_dir, symlink_file};
use std::path::Path;
pub struct Ln;
impl Command for Ln {
fn execute(&self) {
let mut to_be_linked = String::from("");
let mut destination = String::from("");
let family = env::consts::FAMILY;
let args = ArgParser::builder()
.add_flag("--help")
.add_flag("-s")
.add_flag("-f")
.add_flag("-n")
@ -19,96 +20,68 @@ impl Command for Ln {
.add_flag("-v")
.add_option("-S")
.parse_args("ln");
fn help() {
println!("Lorem ipsum dolor sit amet.");
exit(1)
}
if args.get_normal_args().len() != 2 {
help();
} else {
to_be_linked = args.get_normal_args()[0].clone();
destination = args.get_normal_args()[1].clone();
}
if ((family == "unix") || (family == "windows")).not() {
eprintln!("OS family is unknown: {}. Aborting.", family);
exit(1);
let help = args.get_normal_args().len() != 2 || args.get_flag("--help");
if help {
println!("Usage: ln [-sfnbtv] [-S SUF] TARGET LINK");
return;
}
#[cfg(unix)]
fn main(args: ArgParser, to_be_linked: String, destination: String) {
use std::os::unix;
use std::fs;
let to_be_linked = args.get_normal_args()[0].clone();
let destination = args.get_normal_args()[1].clone();
if args.get_flag("-v"){
println!("'{}' -> '{}'", to_be_linked, destination)
if args.get_flag("-v") {
println!("{} -> {}", to_be_linked, destination);
}
if args.get_flag("-f") {
if fs::metadata(String::from(&destination)).is_ok() {
if fs::metadata(String::from(&destination)).unwrap().is_dir() {
fs::remove_dir_all(String::from(&destination)).unwrap()
if fs::metadata(&destination).is_ok() {
if fs::metadata(&destination).unwrap().is_dir() {
fs::remove_dir_all(&destination).unwrap();
} else {
fs::remove_file(String::from(&destination)).unwrap()
fs::remove_file(&destination).unwrap();
}
}
}
if args.get_flag("-n") {
if Path::new(&destination).exists() {
println!("ln: {} exists, stopping...", destination);
return;
}
}
if args.get_flag("-b") {
let suffix = args.get_option("-S").unwrap_or("~");
let new_filename = format!("{}{}", destination, suffix);
let _ = fs::rename(&destination, new_filename);
let _ = fs::rename(&destination, &new_filename);
}
if args.get_flag("-s") {
if args.get_flag("-n") {
let _ = unix::fs::symlink(String::from(&to_be_linked), String::from(&destination)).unwrap();
} else {
let mut metadata = fs::metadata(&to_be_linked).unwrap();
let file = &to_be_linked;
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()
}
let _ = unix::fs::symlink(String::from(new_file), String::from(&destination)).unwrap();
}
exit(0)
} else {
if args.get_flag("-n") {
let _ = fs::hard_link(String::from(&to_be_linked), String::from(&destination)).unwrap();
} else {
let mut metadata = fs::metadata(&to_be_linked).unwrap();
let file = &to_be_linked;
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()
}
let _ = fs::hard_link(String::from(&new_file), String::from(&destination)).unwrap();
}
#[cfg(unix)]
{
if let Err(e) = symlink(&to_be_linked, &destination) {
eprintln!("ln: failed to create symlink: {}", e);
}
}
#[cfg(windows)]
fn main(args: ArgParser, to_be_linked: String, destination: String) {
use std::os::windows;
use std::fs;
// TODO: basic code at line 77
{
let target_metadata = fs::metadata(&to_be_linked).unwrap();
let symlink_result = if target_metadata.is_dir() {
symlink_dir(&to_be_linked, &destination)
} else {
symlink_file(&to_be_linked, &destination)
};
if let Err(e) = symlink_result {
eprintln!("ln: failed to create symlink: {}", e);
}
}
} else {
if let Err(e) = fs::hard_link(&to_be_linked, &destination) {
eprintln!("ln: failed to create hard link: {}", e);
}
}
let _ = main(args, to_be_linked, destination);
// #[cfg(windows)]
// fn windows(to_be_linked: String, destination: String) {
// use std::os::windows;
// use std::fs;
// let attr = fs::metadata(args.get_normal_args()[0].clone()).unwrap();
// if attr.is_dir() {
// let _ = windows::fs::symlink_dir(args.get_normal_args()[0].clone(), args.get_normal_args()[1].clone());
// } else {
// let _ = windows::fs::symlink_file(args.get_normal_args()[0].clone(), args.get_normal_args()[1].clone());
// }
// }
// #[cfg(windows)]
// windows(to_be_linked, destination);
// }
}
}