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)              );          } | 
