aboutsummaryrefslogtreecommitdiff
path: root/src/dots.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dots.rs')
-rw-r--r--src/dots.rs46
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)
);
}