diff options
Diffstat (limited to 'src/dots.rs')
| -rw-r--r-- | src/dots.rs | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/src/dots.rs b/src/dots.rs index 0259c0c..29059a1 100644 --- a/src/dots.rs +++ b/src/dots.rs @@ -1,42 +1,52 @@ -use std::fs::{remove_file, symlink_metadata}; -use std::os::unix::fs::symlink; +use std::process::Command; +use std::fs::symlink_metadata; use std::path::PathBuf; use dirs::home_dir; use crate::config::Dot; +use symlink::{symlink_auto, remove_symlink_auto}; -pub fn deploy_dots(dots: Vec<Dot>, dots_dir: PathBuf) { - let prepended_dots = dots.iter().map(|m| + +fn prepare_dots(dots: Vec<Dot>, dots_dir: PathBuf, no_hostname_check: bool) -> Vec<Dot> { + let mut hostname = "*".to_string(); + if !no_hostname_check { + // Deeply saddened there is no better way to do this :( + let hostname_cmd = Command::new("hostname").output().expect("failed to get hostname: command \"hostname\" failed"); + let hostname_stdout = hostname_cmd.stdout; + let mut new_hostname = String::from_utf8(hostname_stdout.clone()).expect("failed to get hostname: unknown hostname encoding"); + new_hostname.pop(); // stdout contains a newline + hostname = new_hostname; + } + + let prepared_dots = dots.iter().filter(|dot| if no_hostname_check { true } else { dot.host == "*" || dot.host == hostname }).map(|m| Dot { source: dots_dir.join(&m.source), - destination: if m.destination.is_absolute() { m.destination.clone() } else { prepend_user_dir(&m.destination) } + destination: if m.destination.is_absolute() { m.destination.clone() } else { prepend_user_dir(&m.destination) }, + host: m.host.clone() } ); - for dot in prepended_dots { + prepared_dots.collect() +} + +pub fn deploy_dots(dots: Vec<Dot>, dots_dir: PathBuf, no_hostname_check: bool) { + for dot in prepare_dots(dots, dots_dir, no_hostname_check) { println!("linking from {} to {}", dot.source.display(), dot.destination.display()); - let _ = symlink(&dot.source, &dot.destination).map_err(|err| + let _ = symlink_auto(&dot.source, &dot.destination).map_err(|err| eprintln!("failed to symlink: {}", err.to_string()) ); } } -pub fn unlink_dots(dots: Vec<Dot>, dots_dir: PathBuf) { - let prepended_dots = dots.iter().map(|m| - Dot { - source: dots_dir.join(&m.source), - destination: prepend_user_dir(&m.destination) - } - ); - - for dot in prepended_dots { - println!("unlinking {}", dot.destination.display()); +pub fn unlink_dots(dots: Vec<Dot>, dots_dir: PathBuf, no_hostname_check: bool) { + for dot in prepare_dots(dots, dots_dir, no_hostname_check) { + println!("unlinking {}", dot.destination.display()); let metadata = symlink_metadata(dot.destination.clone()); if metadata.is_err() { eprintln!("failed to query metadata for {}: {}", dot.destination.display(), metadata.err().unwrap()); continue } if metadata.ok().unwrap().is_symlink() { - let _ = remove_file(dot.destination).map_err(|err| + let _ = remove_symlink_auto(dot.destination).map_err(|err| eprintln!("failed to remove symlink: {}", err) ); } |
