diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 00000000..85fe6401 --- /dev/null +++ b/src/git.rs @@ -0,0 +1,50 @@ +use super::error::*; +use std::path::{Path, PathBuf}; +use std::process::Command; +use which::which; + +pub struct Git { + git: Option, +} + +impl Git { + pub fn new() -> Self { + Self { + git: which("git").ok(), + } + } + + pub fn get_repo_root>(&self, path: P) -> Option { + if !path.as_ref().exists() { + return None; + } + + if let Some(git) = &self.git { + let output = Command::new(&git) + .arg("rev-parse") + .arg("--show-toplevel") + .current_dir(path) + .output(); + + if let Ok(output) = output { + if !output.status.success() { + return None; + } + + return Some(String::from_utf8_lossy(&output.stdout).trim().to_string()); + } + } + + None + } + + pub fn pull>(&self, path: P) -> Result<()> { + if let Some(git) = &self.git { + if let Ok(mut command) = Command::new(&git).arg("pull").current_dir(path).spawn() { + command.wait()?; + } + } + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 808d5805..86813e1f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ extern crate which; #[macro_use] extern crate error_chain; -mod errors { +mod error { error_chain!{ foreign_links { Io(::std::io::Error); @@ -11,7 +11,11 @@ mod errors { } } -use errors::*; +mod git; + +use error::*; +use git::Git; +use std::collections::HashSet; use std::env::home_dir; use std::path::PathBuf; use std::process::{Command, ExitStatus}; @@ -39,11 +43,10 @@ impl Chain for ExitStatus { } } -#[cfg(unix)] -fn zplug_exists() -> bool { +fn home_path(p: &str) -> PathBuf { let mut path = home_dir().unwrap(); - path.push(".zplug"); - path.exists() + path.push(p); + path } #[cfg(unix)] @@ -58,9 +61,27 @@ fn tpm() -> Option { } fn run() -> Result<()> { + let git = Git::new(); + let mut git_repos: HashSet = HashSet::new(); + + { + let mut collect_repo = |path| { + if let Some(repo) = git.get_repo_root(path) { + git_repos.insert(repo); + } + }; + + collect_repo(home_path(".emacs.d")); + + if cfg!(unix) { + collect_repo(home_path(".zshrc")); + collect_repo(home_path(".tmux")); + } + } + if cfg!(unix) { if let Ok(zsh) = which("zsh") { - if zplug_exists() { + if home_path(".zplug").exists() { Command::new(&zsh) .arg("-ic") .arg("zplug update") @@ -70,12 +91,14 @@ fn run() -> Result<()> { } if let Some(tpm) = tpm() { - if zplug_exists() { - Command::new(&tpm).arg("all").spawn()?.wait()?; - } + Command::new(&tpm).arg("all").spawn()?.wait()?; } } + for repo in git_repos { + git.pull(repo)?; + } + if cfg!(target_os = "macos") { if let Ok(brew) = which("brew") { Command::new(&brew)