diff --git a/src/cli.rs b/src/cli.rs index 0cff35a..406152d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,11 +1,13 @@ -use structopt::StructOpt; -use std::path::PathBuf; use std::env; +use std::path::PathBuf; +use structopt::StructOpt; #[derive(Debug, StructOpt)] -#[structopt(name = "git-build", about = "Update your repositories and trigger tasks")] +#[structopt( + name = "git-build", + about = "Update your repositories and trigger tasks" +)] pub struct Cli { - #[structopt(short = "f", long = "force")] pub force: bool, @@ -19,7 +21,9 @@ pub struct Cli { impl Cli { pub fn basedir(&self) -> PathBuf { if let Some(basedir) = &self.basedir { - PathBuf::from(basedir).canonicalize().expect("failed to expand relative path") + PathBuf::from(basedir) + .canonicalize() + .expect("failed to expand relative path") } else { let mut home_path = PathBuf::from(env::var("HOME").expect("No $HOME in env")); home_path.push(".forgebuild"); diff --git a/src/db.rs b/src/db.rs index 9c0ed9b..aa4f2f0 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,11 +1,11 @@ -use std::path::{PathBuf,Path}; +use std::ffi::OsString; use std::fs; use std::os::unix::fs::MetadataExt; -use std::ffi::OsString; +use std::path::{Path, PathBuf}; #[derive(Debug)] pub enum Error { - EntryNotFound(String) + EntryNotFound(String), } #[derive(Debug, Clone)] @@ -41,10 +41,12 @@ pub fn entry(basedir: &str, filter: impl Fn(&Path) -> bool, name: &str) -> Optio } Some(Entry::new( - path.clone(), - path.file_name().expect("Failed to read file name").to_os_string(), - basepath - )) + path.clone(), + path.file_name() + .expect("Failed to read file name") + .to_os_string(), + basepath, + )) } /// Loads entire database from folder @@ -63,13 +65,14 @@ pub fn from(path_name: &str, filter: impl Fn(&Path) -> bool) -> Result Option { Ok(content) => { // Remove trailing space/newlines Some(content.trim().to_string()) - }, + } Err(e) => { eprintln!("IO ERROR: {}", e); None @@ -110,7 +113,7 @@ pub fn is_executable(path: &Path) -> bool { } else { false } - }, + } Err(e) => { eprintln!("IO Error: {}", e); false @@ -126,9 +129,15 @@ mod tests { fn can_load_db() { let base_dir = "tests/success"; let entries = from(base_dir, is_executable).expect("Could not load db"); - let entries_names: Vec = entries.iter().map(|x| x.name.clone().into_string().unwrap()).collect(); + let entries_names: Vec = entries + .iter() + .map(|x| x.name.clone().into_string().unwrap()) + .collect(); - let expected: Vec = vec!("task", "symlink", "no_source").iter().map(|x| x.to_string()).collect(); + let expected: Vec = vec!["task", "symlink", "no_source"] + .iter() + .map(|x| x.to_string()) + .collect(); assert_eq!(expected.len(), entries_names.len()); diff --git a/src/dvcs.rs b/src/dvcs.rs index 36776f9..807a5c9 100644 --- a/src/dvcs.rs +++ b/src/dvcs.rs @@ -1,5 +1,5 @@ +use std::path::{Path, PathBuf}; use std::process::Command; -use std::path::{Path,PathBuf}; #[derive(Debug)] pub enum Backend { @@ -14,12 +14,11 @@ impl Backend { setting.map_or(Backend::Git, |name| match name.as_ref() { "git" => Backend::Git, "mercurial" => Backend::Mercurial, - _ => Backend::Unknown(name.to_string()) + _ => Backend::Unknown(name.to_string()), }) } } - #[derive(Debug)] pub struct Repo { pub backend: Backend, @@ -34,7 +33,7 @@ impl Repo { backend, source: source.to_string(), dest: dest.to_path_buf(), - subupdates + subupdates, } } @@ -45,18 +44,19 @@ impl Repo { .arg("rev-parse") .arg("--abbrev-ref") .arg("HEAD") - .output().expect("WTF"); + .output() + .expect("WTF"); if !output.status.success() { panic!("Corrupted git repository???"); } String::from_utf8(output.stdout).unwrap().trim().to_string() - }, + } Backend::Mercurial => { unreachable!("UNIMPLEMENTED!"); - }, + } Backend::Unknown(name) => { panic!("Uknown backend: {}. Cannot find ranch", name); - }, + } } } @@ -68,12 +68,13 @@ impl Repo { .arg("--recursive") .arg(&self.source) .arg(&self.dest) - .status().expect("PROCESS ERROR!"); + .status() + .expect("PROCESS ERROR!"); status.success() - }, + } Backend::Mercurial => { unreachable!("Unimplemented"); - }, + } Backend::Unknown(name) => { eprintln!("Unknown DVCS: {}", name); false @@ -88,12 +89,13 @@ impl Repo { let status = Command::new("git") .arg("checkout") .arg(target) - .status().expect("PROCESS ERROR!"); + .status() + .expect("PROCESS ERROR!"); status.success() - }, + } Backend::Mercurial => { unreachable!("UNIMPLEMENTED"); - }, + } Backend::Unknown(name) => { eprintln!("Unknown DVCS: {}", name); false @@ -109,7 +111,10 @@ impl Repo { .arg("fetch") .arg("--quiet") .arg("origin") - .status().expect("WTF").success() { + .status() + .expect("WTF") + .success() + { // FAILED, no internet?? eprintln!("Fetching updates failed"); return false; @@ -119,16 +124,19 @@ impl Repo { .arg("diff") .arg("--quiet") .arg(format!("remotes/origin/{}", &branch)) - .status().expect("WTF").success() { + .status() + .expect("WTF") + .success() + { // Command succeeeded, no updates return false; } // Updates return true; - }, + } Backend::Mercurial => { unreachable!("unimplemented"); - }, + } Backend::Unknown(name) => { eprintln!("Unknown DVCS:{}!", name); false @@ -141,7 +149,7 @@ impl Repo { pub fn update(&self, dest: &str) -> bool { match self { Backend::Git => { - + }, Backend::Mercurial => { diff --git a/src/log.rs b/src/log.rs index 06e88b0..f2423a4 100644 --- a/src/log.rs +++ b/src/log.rs @@ -1,11 +1,11 @@ -use std::env; use std::collections::HashMap; -use std::path::PathBuf; +use std::env; use std::fs; +use std::path::PathBuf; use lazy_static::lazy_static; -lazy_static!{ +lazy_static! { static ref LOGLEVEL: LogLevel = LogLevel::from_env(); static ref LANG: String = lang_from_env(); static ref TRANSLATIONS: HashMap = load_translations(); @@ -52,9 +52,9 @@ fn load_translations() -> HashMap { //return trans match serde_json::from_str(&content) { Ok(trans) => trans, - Err(e) => panic!("JSON ERROR: {}", e) + Err(e) => panic!("JSON ERROR: {}", e), } - }, + } Err(e) => { panic!("IO ERROR: {}", e); } @@ -71,15 +71,15 @@ fn trans(key: &str) -> String { } fn lang_from_env() -> String { - let lang = env::var("LANG").expect("$LANG not set in environment. Your machine is misconfigured!"); + let lang = + env::var("LANG").expect("$LANG not set in environment. Your machine is misconfigured!"); lang[0..2].to_string() } - struct LogLevel { info: bool, debug: bool, - error: bool + error: bool, } impl LogLevel { @@ -91,31 +91,34 @@ impl LogLevel { let env_log = env::var("LOG").unwrap_or("info".to_string()); match env_log.to_lowercase().as_str() { - "info" => {}, - "debug" => { debug = true; }, - "error" => { info = false; } + "info" => {} + "debug" => { + debug = true; + } + "error" => { + info = false; + } _ => { // This happens before loglevel initialization // so we can't use warn function - eprintln!("$LOG level is incorrect: {} (can be: debug, info, error", env_log); + eprintln!( + "$LOG level is incorrect: {} (can be: debug, info, error", + env_log + ); } } - return LogLevel { - info, - debug, - error - } + return LogLevel { info, debug, error }; } } - fn expand(msg: &str, vars: Option) -> String { //let mut s = msg; if vars.is_some() { - return vars.unwrap().iter().fold(msg.to_string(), |prev, (key, val)| { - prev.replace(key, val) - }) + return vars + .unwrap() + .iter() + .fold(msg.to_string(), |prev, (key, val)| prev.replace(key, val)); } return msg.to_string(); } diff --git a/src/main.rs b/src/main.rs index 22f2c4f..9129721 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,12 @@ -use std::env::{set_current_dir as cd, set_var}; use std::collections::HashMap; +use std::env::{set_current_dir as cd, set_var}; use structopt::StructOpt; // For UNIX extended metadata -mod log; +mod cli; mod db; mod dvcs; -mod cli; +mod log; mod task; fn main() -> Result<(), std::io::Error> { @@ -24,7 +24,7 @@ fn main() -> Result<(), std::io::Error> { let (config_folder, ignored_tasks) = task::config(&std::path::Path::new(&base_dir)); set_var("GITBUILDCONF", &config_folder); - + // Reorder tasks alphanumerically tasks.sort_unstable_by_key(|t| t.name.clone()); // Remove duplicates, in case a task was called along @@ -50,16 +50,16 @@ fn main() -> Result<(), std::io::Error> { context.insert("$i18n_source", &repo.source); log::error("clone_failed", Some(&context)); // Skip further processing - continue + continue; } // New repo just cloned // TODO: submodule and submodule updates - println!("Downloaded source for {}", task.name); + println!("Downloaded source for {}", task.name); cd(&source_dir).expect("Failed to change working dir"); // Checkout specific branch? - task.checkout(); - task.run(); + task.checkout(); + task.run(); } else { // So the cloned repo is already here maybe update? // Let's say there was an update and run @@ -67,7 +67,7 @@ fn main() -> Result<(), std::io::Error> { cd(&source_dir).expect("Failed to change working dir"); task.checkout(); task.update_and_run(&cmd.force); - //task.run(); + //task.run(); } } else { // No source, chaneg working dir to basedir diff --git a/src/task.rs b/src/task.rs index 62ec2ac..c30f7c1 100644 --- a/src/task.rs +++ b/src/task.rs @@ -1,10 +1,10 @@ -use std::path::{Path, PathBuf}; use std::collections::HashMap; +use std::path::{Path, PathBuf}; use std::process::Command; -use crate::dvcs::{Backend, Repo}; use crate::db; -use crate::db::{Entry,is_executable}; +use crate::db::{is_executable, Entry}; +use crate::dvcs::{Backend, Repo}; use crate::log; #[derive(Debug)] @@ -23,19 +23,24 @@ pub struct Task { /// config returns an option of (settings directory, ignored tasks) as /// (PathBuf, Vec) pub fn config(basedir: &Path) -> (PathBuf, Vec) { - let hostname = std::env::var("HOST").unwrap_or_else( - |_| hostname::get().unwrap().into_string().unwrap() - ); + let hostname = + std::env::var("HOST").unwrap_or_else(|_| hostname::get().unwrap().into_string().unwrap()); let path = basedir.join(hostname); if path.is_dir() { - let ignored = path.read_dir().unwrap().filter_map(|x| { - if x.is_err() { return None; } - let name = x.unwrap().file_name().into_string().unwrap(); - if name.ends_with(".ignore") { - return Some(name.trim_end_matches(".ignore").to_string()); - } - return None; - }).collect(); + let ignored = path + .read_dir() + .unwrap() + .filter_map(|x| { + if x.is_err() { + return None; + } + let name = x.unwrap().file_name().into_string().unwrap(); + if name.ends_with(".ignore") { + return Some(name.trim_end_matches(".ignore").to_string()); + } + return None; + }) + .collect(); (path, ignored) } else { // TODO: load .ignore in default config? @@ -46,26 +51,32 @@ pub fn config(basedir: &Path) -> (PathBuf, Vec) { impl Task { pub fn from_entry(entry: &Entry) -> Task { let source = entry.read_setting("source"); - let dest = entry.base_dir.join(&format!(".{}", entry.name.to_str().expect("WTF"))); - let cloned = source.clone().map_or(false, |_| { - dest.is_dir() - }); + let dest = entry + .base_dir + .join(&format!(".{}", entry.name.to_str().expect("WTF"))); + let cloned = source.clone().map_or(false, |_| dest.is_dir()); let subupdates = entry.read_setting("subupdates").is_some(); Task { name: entry.name.to_str().unwrap().to_string(), bin: entry.path.clone(), // None source = None repo - repo: source.as_ref().map(|s| - Repo::new(Backend::from_setting(entry.read_setting("dvcs")), s, &dest, subupdates) - ), + repo: source.as_ref().map(|s| { + Repo::new( + Backend::from_setting(entry.read_setting("dvcs")), + s, + &dest, + subupdates, + ) + }), source, config: HashMap::new(), branch: entry.read_setting("checkout"), - hosts: entry.read_setting("hosts").map_or(Vec::new(), |c| c.split("\n").map(|line| line.to_string()).collect()), + hosts: entry.read_setting("hosts").map_or(Vec::new(), |c| { + c.split("\n").map(|line| line.to_string()).collect() + }), cloned, subupdates: entry.read_setting("subupdates").is_some(), - } } @@ -88,9 +99,8 @@ impl Task { } // $HOSTNAME env is a bashism, we need to call libc (through hostname crate) // to find out the actual hostname - let hostname = std::env::var("HOST").unwrap_or_else( - |_| hostname::get().unwrap().into_string().unwrap() - ); + let hostname = std::env::var("HOST") + .unwrap_or_else(|_| hostname::get().unwrap().into_string().unwrap()); println!("HOSTNAME: {}", hostname); if self.hosts.contains(&hostname) { return true; @@ -117,7 +127,9 @@ impl Task { } pub fn run(&self) { - if !self.run_on_host() { return; } + if !self.run_on_host() { + return; + } let cmd_out = Command::new("bash") // TODO: no need to call bash? .arg(&self.bin) @@ -126,11 +138,14 @@ impl Task { .expect(&format!("Failed to run {:?}", &self.bin)); let mut log_path = self.bin.clone(); log_path.set_extension("log"); - std::fs::write(&log_path, cmd_out.stderr).expect(&format!("Failed to write log to {:?}", &log_path)); + std::fs::write(&log_path, cmd_out.stderr) + .expect(&format!("Failed to write log to {:?}", &log_path)); } pub fn run_once(&self) { - if !self.run_on_host() { return; } + if !self.run_on_host() { + return; + } let mut done_path = self.bin.clone(); done_path.set_extension("done"); if !done_path.exists() { @@ -149,9 +164,7 @@ pub fn from_entries(db: Vec) -> Vec { /// Returns a list of tasks, or std::io::Error /// Reads all entries in a directory pub fn from_dir(base_dir: &str) -> Result, std::io::Error> { - Ok(from_entries( - db::from(base_dir, is_executable)? - )) + Ok(from_entries(db::from(base_dir, is_executable)?)) } /// Returns a list of tasks, or std::io::Error