diff --git a/src/db.rs b/src/db.rs index d886480..512c047 100644 --- a/src/db.rs +++ b/src/db.rs @@ -32,7 +32,7 @@ impl Entry { } /// Load single entry from folder -pub fn entry(basedir: &str, filter: impl Fn(&Path) -> bool, name: &str) -> Option { +pub fn entry(basedir: &Path, filter: impl Fn(&Path) -> bool, name: &str) -> Option { let basepath = PathBuf::from(&basedir); let path = basepath.clone().join(name); @@ -48,7 +48,7 @@ pub fn entry(basedir: &str, filter: impl Fn(&Path) -> bool, name: &str) -> Optio } /// Loads entire database from folder -pub fn from(path_name: &str, filter: impl Fn(&Path) -> bool) -> Result, std::io::Error> { +pub fn from(path_name: &Path, filter: impl Fn(&Path) -> bool) -> Result, std::io::Error> { let path = PathBuf::from(&path_name); let mut entries = Vec::new(); diff --git a/src/dvcs.rs b/src/dvcs.rs index ad556fa..c44bd7f 100644 --- a/src/dvcs.rs +++ b/src/dvcs.rs @@ -36,4 +36,23 @@ impl Backend { } } } + + pub fn update(&self) -> bool { + match self { + Backend::Git => { + let status = Command::new("git") + .arg("pull") + .status() + .expect("Failed to pull on git repo."); + status.success() + }, + Backend::Mercurial => { + unreachable!("Unimplemented"); + }, + Backend::Unknown(name) => { + eprintln!("Unknown DVCS: {}", name); + false + } + } + } } diff --git a/src/main.rs b/src/main.rs index c7f0b11..2fff9a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use std::env; use std::collections::HashMap; use structopt::StructOpt; +use std::fs::{DirBuilder}; +use std::path::{Path,PathBuf}; // For UNIX extended metadata mod log; @@ -11,8 +13,36 @@ mod task; fn main() -> Result<(), std::io::Error> { - let home_dir = env::var("HOME").expect("$HOME not defined. WTF?"); - let base_dir = format!("{}/.git-build", home_dir); + let default_folder; + + // Check if we defined a given folder in which to find the tasks + let base_dir = match env::var_os("GITBUILDDIR") { + Some(val) => { + default_folder = false; + PathBuf::from(val) + }, + None => { + default_folder = true; + let home_dir = env::var("HOME").expect("$HOME not defined. WTF?"); + PathBuf::from(&format!("{}/.git-build", home_dir).clone()) + } + }; + + // If we're not using a GITBUILDDIR folder, + // We're gonna check if they already is a .git-build folder, and create one otherwise. + if !base_dir.exists() { + if default_folder == false { + let mut context = HashMap::new(); + context.insert("$i18n_folder", base_dir.to_str().unwrap()); + log::error("no_folder", Some(&context)); + return Err(std::io::Error::new(std::io::ErrorKind::NotFound, "Folder not found.")); + } else { + log::info("create_git_build_folder", Some(&HashMap::new())); + DirBuilder::new() + .recursive(true) + .create(&base_dir).unwrap(); + } + } let cmd = cli::Cli::from_args(); @@ -21,7 +51,11 @@ fn main() -> Result<(), std::io::Error> { } else { task::from_dir_and_list(&base_dir, cmd.tasks).expect("Could not load given tasks") }; - + + // Change directory to the base_dir + // assert!(env::set_current_dir(&base_dir).is_ok()); + // println!("Successfully changed working directory to {}!", base_dir.display()); + for (task_name, task) in tasks.iter() { let mut context = HashMap::new(); //context.insert("$i18n_task", task_name.to_str().expect("WTF")); @@ -31,17 +65,48 @@ fn main() -> Result<(), std::io::Error> { // Maybe the task has a source we should clone? if let Some(source) = &task.source { + // If we're not using the default folder, change it + let curr_dirr = env::current_dir().unwrap(); // TODO: Might fail because of a lack of permission to read current dir. + + env::set_current_dir(&base_dir).unwrap(); + + let mut context = HashMap::new(); + context.insert("$i18n_folder", base_dir.to_str().unwrap()); + log::info("change_folder", Some(&context)); + if !task.dvcs.clone(source) { context.insert("$i18n_source", &source); log::error("clone_failed", Some(&context)); + + // Change back to the parent folder. + // TODO: refactor this. + env::set_current_dir(curr_dirr).unwrap(); + let mut context = HashMap::new(); + context.insert("$i18n_folder", curr_dirr.to_str().unwrap().clone()); + log::info("change_folder", Some(&context)); + // Skip further processing continue } + + // Change back to the parent folder. + // TODO: refactor this. + env::set_current_dir(curr_dirr).unwrap(); + let mut context = HashMap::new(); + context.insert("$i18n_folder", curr_dirr.clone().to_str().unwrap()); + log::info("change_folder", Some(&context)); + + // TODO: in case the clone fails + } // Otherwise, it's a sourceless task continue } - // So the cloned repo is here maybe update? + // The repo has been cloned already, we update it. + task.dvcs.update(); + + + } Ok(()) } diff --git a/src/task.rs b/src/task.rs index c7fa46e..1670c8d 100644 --- a/src/task.rs +++ b/src/task.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{PathBuf, Path}; use std::ffi::OsString; use std::collections::HashMap; @@ -57,7 +57,7 @@ pub fn from_entries(db: Vec) -> HashMap { /// Returns a hashmap of tasks, or std::io::Error /// Reads all entries in a directory -pub fn from_dir(base_dir: &str) -> Result, std::io::Error> { +pub fn from_dir(base_dir: &Path) -> Result, std::io::Error> { Ok(from_entries( db::from(base_dir, is_executable)? )) @@ -66,7 +66,7 @@ pub fn from_dir(base_dir: &str) -> Result, std::io::Error> /// Returns a hashmap of tasks, or std::io::Error /// Reads entries in a given list from a directory, fails if a requested entry doesn't exist /// (does not load the whole folder) -pub fn from_dir_and_list(basedir: &str, list: Vec) -> Result, db::Error> { +pub fn from_dir_and_list(basedir: &Path, list: Vec) -> Result, db::Error> { let mut entries: HashMap = HashMap::new(); for item in list { if let Some(entry) = db::entry(&basedir, is_executable, &item) {