cargo fmt

This commit is contained in:
southerntofu 2020-11-25 23:59:39 +01:00
parent 6ed76928db
commit 104302ede2
6 changed files with 141 additions and 104 deletions

View File

@ -1,11 +1,13 @@
use structopt::StructOpt;
use std::path::PathBuf;
use std::env; use std::env;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Debug, 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 { pub struct Cli {
#[structopt(short = "f", long = "force")] #[structopt(short = "f", long = "force")]
pub force: bool, pub force: bool,
@ -19,7 +21,9 @@ pub struct Cli {
impl Cli { impl Cli {
pub fn basedir(&self) -> PathBuf { pub fn basedir(&self) -> PathBuf {
if let Some(basedir) = &self.basedir { 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 { } else {
let mut home_path = PathBuf::from(env::var("HOME").expect("No $HOME in env")); let mut home_path = PathBuf::from(env::var("HOME").expect("No $HOME in env"));
home_path.push(".forgebuild"); home_path.push(".forgebuild");

View File

@ -1,11 +1,11 @@
use std::path::{PathBuf,Path}; use std::ffi::OsString;
use std::fs; use std::fs;
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
use std::ffi::OsString; use std::path::{Path, PathBuf};
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
EntryNotFound(String) EntryNotFound(String),
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -41,10 +41,12 @@ pub fn entry(basedir: &str, filter: impl Fn(&Path) -> bool, name: &str) -> Optio
} }
Some(Entry::new( Some(Entry::new(
path.clone(), path.clone(),
path.file_name().expect("Failed to read file name").to_os_string(), path.file_name()
basepath .expect("Failed to read file name")
)) .to_os_string(),
basepath,
))
} }
/// Loads entire database from folder /// Loads entire database from folder
@ -63,13 +65,14 @@ pub fn from(path_name: &str, filter: impl Fn(&Path) -> bool) -> Result<Vec<Entry
} }
let entry = file?.path(); let entry = file?.path();
if filter(&entry) { if filter(&entry) {
entries.push( entries.push(Entry::new(
Entry::new( entry.clone(),
entry.clone(), entry
entry.file_name().expect("Failed to read file name").to_os_string(), .file_name()
path.clone() .expect("Failed to read file name")
) .to_os_string(),
); path.clone(),
));
} }
} }
@ -86,7 +89,7 @@ pub fn read_or_none(path: &Path) -> Option<String> {
Ok(content) => { Ok(content) => {
// Remove trailing space/newlines // Remove trailing space/newlines
Some(content.trim().to_string()) Some(content.trim().to_string())
}, }
Err(e) => { Err(e) => {
eprintln!("IO ERROR: {}", e); eprintln!("IO ERROR: {}", e);
None None
@ -110,7 +113,7 @@ pub fn is_executable(path: &Path) -> bool {
} else { } else {
false false
} }
}, }
Err(e) => { Err(e) => {
eprintln!("IO Error: {}", e); eprintln!("IO Error: {}", e);
false false
@ -126,9 +129,15 @@ mod tests {
fn can_load_db() { fn can_load_db() {
let base_dir = "tests/success"; let base_dir = "tests/success";
let entries = from(base_dir, is_executable).expect("Could not load db"); let entries = from(base_dir, is_executable).expect("Could not load db");
let entries_names: Vec<String> = entries.iter().map(|x| x.name.clone().into_string().unwrap()).collect(); let entries_names: Vec<String> = entries
.iter()
.map(|x| x.name.clone().into_string().unwrap())
.collect();
let expected: Vec<String> = vec!("task", "symlink", "no_source").iter().map(|x| x.to_string()).collect(); let expected: Vec<String> = vec!["task", "symlink", "no_source"]
.iter()
.map(|x| x.to_string())
.collect();
assert_eq!(expected.len(), entries_names.len()); assert_eq!(expected.len(), entries_names.len());

View File

@ -1,5 +1,5 @@
use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use std::path::{Path,PathBuf};
#[derive(Debug)] #[derive(Debug)]
pub enum Backend { pub enum Backend {
@ -14,12 +14,11 @@ impl Backend {
setting.map_or(Backend::Git, |name| match name.as_ref() { setting.map_or(Backend::Git, |name| match name.as_ref() {
"git" => Backend::Git, "git" => Backend::Git,
"mercurial" => Backend::Mercurial, "mercurial" => Backend::Mercurial,
_ => Backend::Unknown(name.to_string()) _ => Backend::Unknown(name.to_string()),
}) })
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Repo { pub struct Repo {
pub backend: Backend, pub backend: Backend,
@ -34,7 +33,7 @@ impl Repo {
backend, backend,
source: source.to_string(), source: source.to_string(),
dest: dest.to_path_buf(), dest: dest.to_path_buf(),
subupdates subupdates,
} }
} }
@ -45,18 +44,19 @@ impl Repo {
.arg("rev-parse") .arg("rev-parse")
.arg("--abbrev-ref") .arg("--abbrev-ref")
.arg("HEAD") .arg("HEAD")
.output().expect("WTF"); .output()
.expect("WTF");
if !output.status.success() { if !output.status.success() {
panic!("Corrupted git repository???"); panic!("Corrupted git repository???");
} }
String::from_utf8(output.stdout).unwrap().trim().to_string() String::from_utf8(output.stdout).unwrap().trim().to_string()
}, }
Backend::Mercurial => { Backend::Mercurial => {
unreachable!("UNIMPLEMENTED!"); unreachable!("UNIMPLEMENTED!");
}, }
Backend::Unknown(name) => { Backend::Unknown(name) => {
panic!("Uknown backend: {}. Cannot find ranch", name); panic!("Uknown backend: {}. Cannot find ranch", name);
}, }
} }
} }
@ -68,12 +68,13 @@ impl Repo {
.arg("--recursive") .arg("--recursive")
.arg(&self.source) .arg(&self.source)
.arg(&self.dest) .arg(&self.dest)
.status().expect("PROCESS ERROR!"); .status()
.expect("PROCESS ERROR!");
status.success() status.success()
}, }
Backend::Mercurial => { Backend::Mercurial => {
unreachable!("Unimplemented"); unreachable!("Unimplemented");
}, }
Backend::Unknown(name) => { Backend::Unknown(name) => {
eprintln!("Unknown DVCS: {}", name); eprintln!("Unknown DVCS: {}", name);
false false
@ -88,12 +89,13 @@ impl Repo {
let status = Command::new("git") let status = Command::new("git")
.arg("checkout") .arg("checkout")
.arg(target) .arg(target)
.status().expect("PROCESS ERROR!"); .status()
.expect("PROCESS ERROR!");
status.success() status.success()
}, }
Backend::Mercurial => { Backend::Mercurial => {
unreachable!("UNIMPLEMENTED"); unreachable!("UNIMPLEMENTED");
}, }
Backend::Unknown(name) => { Backend::Unknown(name) => {
eprintln!("Unknown DVCS: {}", name); eprintln!("Unknown DVCS: {}", name);
false false
@ -109,7 +111,10 @@ impl Repo {
.arg("fetch") .arg("fetch")
.arg("--quiet") .arg("--quiet")
.arg("origin") .arg("origin")
.status().expect("WTF").success() { .status()
.expect("WTF")
.success()
{
// FAILED, no internet?? // FAILED, no internet??
eprintln!("Fetching updates failed"); eprintln!("Fetching updates failed");
return false; return false;
@ -119,16 +124,19 @@ impl Repo {
.arg("diff") .arg("diff")
.arg("--quiet") .arg("--quiet")
.arg(format!("remotes/origin/{}", &branch)) .arg(format!("remotes/origin/{}", &branch))
.status().expect("WTF").success() { .status()
.expect("WTF")
.success()
{
// Command succeeeded, no updates // Command succeeeded, no updates
return false; return false;
} }
// Updates // Updates
return true; return true;
}, }
Backend::Mercurial => { Backend::Mercurial => {
unreachable!("unimplemented"); unreachable!("unimplemented");
}, }
Backend::Unknown(name) => { Backend::Unknown(name) => {
eprintln!("Unknown DVCS:{}!", name); eprintln!("Unknown DVCS:{}!", name);
false false
@ -141,7 +149,7 @@ impl Repo {
pub fn update(&self, dest: &str) -> bool { pub fn update(&self, dest: &str) -> bool {
match self { match self {
Backend::Git => { Backend::Git => {
}, },
Backend::Mercurial => { Backend::Mercurial => {

View File

@ -1,11 +1,11 @@
use std::env;
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::env;
use std::fs; use std::fs;
use std::path::PathBuf;
use lazy_static::lazy_static; use lazy_static::lazy_static;
lazy_static!{ lazy_static! {
static ref LOGLEVEL: LogLevel = LogLevel::from_env(); static ref LOGLEVEL: LogLevel = LogLevel::from_env();
static ref LANG: String = lang_from_env(); static ref LANG: String = lang_from_env();
static ref TRANSLATIONS: HashMap<String, String> = load_translations(); static ref TRANSLATIONS: HashMap<String, String> = load_translations();
@ -52,9 +52,9 @@ fn load_translations() -> HashMap<String, String> {
//return trans //return trans
match serde_json::from_str(&content) { match serde_json::from_str(&content) {
Ok(trans) => trans, Ok(trans) => trans,
Err(e) => panic!("JSON ERROR: {}", e) Err(e) => panic!("JSON ERROR: {}", e),
} }
}, }
Err(e) => { Err(e) => {
panic!("IO ERROR: {}", e); panic!("IO ERROR: {}", e);
} }
@ -71,15 +71,15 @@ fn trans(key: &str) -> String {
} }
fn lang_from_env() -> 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() lang[0..2].to_string()
} }
struct LogLevel { struct LogLevel {
info: bool, info: bool,
debug: bool, debug: bool,
error: bool error: bool,
} }
impl LogLevel { impl LogLevel {
@ -91,31 +91,34 @@ impl LogLevel {
let env_log = env::var("LOG").unwrap_or("info".to_string()); let env_log = env::var("LOG").unwrap_or("info".to_string());
match env_log.to_lowercase().as_str() { match env_log.to_lowercase().as_str() {
"info" => {}, "info" => {}
"debug" => { debug = true; }, "debug" => {
"error" => { info = false; } debug = true;
}
"error" => {
info = false;
}
_ => { _ => {
// This happens before loglevel initialization // This happens before loglevel initialization
// so we can't use warn function // 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 { return LogLevel { info, debug, error };
info,
debug,
error
}
} }
} }
fn expand(msg: &str, vars: Option<Context>) -> String { fn expand(msg: &str, vars: Option<Context>) -> String {
//let mut s = msg; //let mut s = msg;
if vars.is_some() { if vars.is_some() {
return vars.unwrap().iter().fold(msg.to_string(), |prev, (key, val)| { return vars
prev.replace(key, val) .unwrap()
}) .iter()
.fold(msg.to_string(), |prev, (key, val)| prev.replace(key, val));
} }
return msg.to_string(); return msg.to_string();
} }

View File

@ -1,12 +1,12 @@
use std::env::{set_current_dir as cd, set_var};
use std::collections::HashMap; use std::collections::HashMap;
use std::env::{set_current_dir as cd, set_var};
use structopt::StructOpt; use structopt::StructOpt;
// For UNIX extended metadata // For UNIX extended metadata
mod log; mod cli;
mod db; mod db;
mod dvcs; mod dvcs;
mod cli; mod log;
mod task; mod task;
fn main() -> Result<(), std::io::Error> { 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)); let (config_folder, ignored_tasks) = task::config(&std::path::Path::new(&base_dir));
set_var("GITBUILDCONF", &config_folder); set_var("GITBUILDCONF", &config_folder);
// Reorder tasks alphanumerically // Reorder tasks alphanumerically
tasks.sort_unstable_by_key(|t| t.name.clone()); tasks.sort_unstable_by_key(|t| t.name.clone());
// Remove duplicates, in case a task was called along // 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); context.insert("$i18n_source", &repo.source);
log::error("clone_failed", Some(&context)); log::error("clone_failed", Some(&context));
// Skip further processing // Skip further processing
continue continue;
} }
// New repo just cloned // New repo just cloned
// TODO: submodule and submodule updates // 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"); cd(&source_dir).expect("Failed to change working dir");
// Checkout specific branch? // Checkout specific branch?
task.checkout(); task.checkout();
task.run(); task.run();
} else { } else {
// So the cloned repo is already here maybe update? // So the cloned repo is already here maybe update?
// Let's say there was an update and run // 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"); cd(&source_dir).expect("Failed to change working dir");
task.checkout(); task.checkout();
task.update_and_run(&cmd.force); task.update_and_run(&cmd.force);
//task.run(); //task.run();
} }
} else { } else {
// No source, chaneg working dir to basedir // No source, chaneg working dir to basedir

View File

@ -1,10 +1,10 @@
use std::path::{Path, PathBuf};
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use crate::dvcs::{Backend, Repo};
use crate::db; use crate::db;
use crate::db::{Entry,is_executable}; use crate::db::{is_executable, Entry};
use crate::dvcs::{Backend, Repo};
use crate::log; use crate::log;
#[derive(Debug)] #[derive(Debug)]
@ -23,19 +23,24 @@ pub struct Task {
/// config returns an option of (settings directory, ignored tasks) as /// config returns an option of (settings directory, ignored tasks) as
/// (PathBuf, Vec<String>) /// (PathBuf, Vec<String>)
pub fn config(basedir: &Path) -> (PathBuf, Vec<String>) { pub fn config(basedir: &Path) -> (PathBuf, Vec<String>) {
let hostname = std::env::var("HOST").unwrap_or_else( let hostname =
|_| hostname::get().unwrap().into_string().unwrap() std::env::var("HOST").unwrap_or_else(|_| hostname::get().unwrap().into_string().unwrap());
);
let path = basedir.join(hostname); let path = basedir.join(hostname);
if path.is_dir() { if path.is_dir() {
let ignored = path.read_dir().unwrap().filter_map(|x| { let ignored = path
if x.is_err() { return None; } .read_dir()
let name = x.unwrap().file_name().into_string().unwrap(); .unwrap()
if name.ends_with(".ignore") { .filter_map(|x| {
return Some(name.trim_end_matches(".ignore").to_string()); if x.is_err() {
} return None;
return None; }
}).collect(); 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) (path, ignored)
} else { } else {
// TODO: load .ignore in default config? // TODO: load .ignore in default config?
@ -46,26 +51,32 @@ pub fn config(basedir: &Path) -> (PathBuf, Vec<String>) {
impl Task { impl Task {
pub fn from_entry(entry: &Entry) -> Task { pub fn from_entry(entry: &Entry) -> Task {
let source = entry.read_setting("source"); let source = entry.read_setting("source");
let dest = entry.base_dir.join(&format!(".{}", entry.name.to_str().expect("WTF"))); let dest = entry
let cloned = source.clone().map_or(false, |_| { .base_dir
dest.is_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(); let subupdates = entry.read_setting("subupdates").is_some();
Task { Task {
name: entry.name.to_str().unwrap().to_string(), name: entry.name.to_str().unwrap().to_string(),
bin: entry.path.clone(), bin: entry.path.clone(),
// None source = None repo // None source = None repo
repo: source.as_ref().map(|s| repo: source.as_ref().map(|s| {
Repo::new(Backend::from_setting(entry.read_setting("dvcs")), s, &dest, subupdates) Repo::new(
), Backend::from_setting(entry.read_setting("dvcs")),
s,
&dest,
subupdates,
)
}),
source, source,
config: HashMap::new(), config: HashMap::new(),
branch: entry.read_setting("checkout"), 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, cloned,
subupdates: entry.read_setting("subupdates").is_some(), 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) // $HOSTNAME env is a bashism, we need to call libc (through hostname crate)
// to find out the actual hostname // to find out the actual hostname
let hostname = std::env::var("HOST").unwrap_or_else( let hostname = std::env::var("HOST")
|_| hostname::get().unwrap().into_string().unwrap() .unwrap_or_else(|_| hostname::get().unwrap().into_string().unwrap());
);
println!("HOSTNAME: {}", hostname); println!("HOSTNAME: {}", hostname);
if self.hosts.contains(&hostname) { if self.hosts.contains(&hostname) {
return true; return true;
@ -117,7 +127,9 @@ impl Task {
} }
pub fn run(&self) { 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? let cmd_out = Command::new("bash") // TODO: no need to call bash?
.arg(&self.bin) .arg(&self.bin)
@ -126,11 +138,14 @@ impl Task {
.expect(&format!("Failed to run {:?}", &self.bin)); .expect(&format!("Failed to run {:?}", &self.bin));
let mut log_path = self.bin.clone(); let mut log_path = self.bin.clone();
log_path.set_extension("log"); 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) { pub fn run_once(&self) {
if !self.run_on_host() { return; } if !self.run_on_host() {
return;
}
let mut done_path = self.bin.clone(); let mut done_path = self.bin.clone();
done_path.set_extension("done"); done_path.set_extension("done");
if !done_path.exists() { if !done_path.exists() {
@ -149,9 +164,7 @@ pub fn from_entries(db: Vec<Entry>) -> Vec<Task> {
/// Returns a list of tasks, or std::io::Error /// Returns a list of tasks, or std::io::Error
/// Reads all entries in a directory /// Reads all entries in a directory
pub fn from_dir(base_dir: &str) -> Result<Vec<Task>, std::io::Error> { pub fn from_dir(base_dir: &str) -> Result<Vec<Task>, std::io::Error> {
Ok(from_entries( Ok(from_entries(db::from(base_dir, is_executable)?))
db::from(base_dir, is_executable)?
))
} }
/// Returns a list of tasks, or std::io::Error /// Returns a list of tasks, or std::io::Error