diff --git a/Dockerfile b/Dockerfile index 1a7d453..f9ffc26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,9 @@ -FROM rust:latest +FROM rust:slim WORKDIR /usr/src/refractr COPY . . -RUN cargo install --path . +RUN cargo build --release +RUN cargo install --locked --path . CMD ["refractr"] \ No newline at end of file diff --git a/src/common.rs b/src/common.rs index 4d30d65..490651f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,6 +1,8 @@ pub struct Refractr { - pub verbose: u8 + pub verbose: u8, + pub pid: u32, + pub unix: bool } pub fn verbose(level: u8, msg_lvl: u8, msg: String) { diff --git a/src/config.rs b/src/config.rs index 2a5f995..108126d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,6 +3,7 @@ use core::fmt; use std::io::Read; use std::path::PathBuf; use std::fs; +use std::env; use std::fs::{File, Metadata}; use toml; use serde_derive::Deserialize; @@ -39,36 +40,54 @@ impl fmt::Display for ConfigFile { }; to_list.push(']'); - write!(f, "Config file: \"{}\"\n \ - Is a file: {}\n \ - Read only: {}\n \ - Configuration:\n \ - Git repo to clone: {}\n \ - Git repos to push clone to: {}\n \ - Branches of clone to push: {}\n \ - SSH key for pushing clone: {}\n \ - Schedule enabled: {}\n\ + let work_dir_path = match &self.config.work_dir { + None => { + if cfg!(windows) { + format!("Using default \"{}\\refractr\"", match env::var("TEMP") { + Ok(val) => val, + Err(_) => format!("This shouldn't happen!") + }) + } else { + format!("Using default: /tmp/refractr") + } + }, + Some(path) => format!("{}", path) + }; + + let schedule_interval = match self.config.schedule.interval { + None => { + if !self.config.schedule.enabled { + String::from("") + } else { + String::from("This shouldn't happen!\n") + } + }, + Some(int) => format!("\n Scheduled interval in seconds: {}", int.to_string()) + }; + + write!(f, "Config file: \"{}\"\n \ + Is a file: {}\n \ + Read only: {}\n \ + Configuration:\n \ + Git repo to clone: {}\n \ + Git repos to push clone to: {}\n \ + Branches of clone to push: {}\n \ + Working directory: {}\n \ + SSH key for pushing clone: {}\n \ + Schedule enabled: {}\ {}" , self.path, self.file.is_file(), self.file.permissions().readonly(), self.config.from - , to_list, branches_list, self.config.git.ssh_identity_file, self.config.schedule.enabled - , match self.config.schedule.interval { - None => { - if !self.config.schedule.enabled { - String::from("") - } else { - String::from("This shouldn't happen!\n") - } - }, - Some(int) => format!(" Scheduled interval in seconds: {}\n", int.to_string()) - }) + , to_list, branches_list, work_dir_path, self.config.git.ssh_identity_file, self.config.schedule.enabled + , schedule_interval) } } #[derive(Deserialize)] -struct Config { +pub struct Config { from: String, to: Vec, branches: Option>, + work_dir: Option, git: Git, schedule: Schedule } @@ -87,9 +106,7 @@ struct Schedule { pub fn read_config(paths: Vec, refractr: &common::Refractr) -> Vec { let mut config_files: Vec = vec![]; for path in paths { - if refractr.verbose >= 1 { - common::verbose(refractr.verbose, 1, format!("Reading config file: \"{}\"", String::from(path.to_string_lossy()))); - } + common::verbose(refractr.verbose, 1, format!("Reading config file: \"{}\"", String::from(path.to_string_lossy()))); let mut data = String::new(); let mut file = match File::open(path.as_path()) { Err(e) => panic!("refractr: unable to open {}: {}", path.as_path().display(), e), @@ -103,11 +120,12 @@ pub fn read_config(paths: Vec, refractr: &common::Refractr) -> Vec panic!("refractr: cannot obtain metadata: {}", path.as_path().display()), + Err(_) => panic!("refractr: cannot obtain metadata: {}", path.as_path().display()), Ok(metadata) => metadata }, config: verify_config(toml::from_str(&data).unwrap()) }; + config_files.push(config_file); } @@ -119,5 +137,19 @@ fn verify_config(config: Config) -> Config { assert_ne!(config.schedule.interval, None); } + assert_ne!("", match &config.work_dir { + Some(path) => format!("{}", path), + None => { + if cfg!(windows) { + match env::var("TEMP") { + Ok(val) => val, + Err(_) => format!("") + } + } else { + format!("/tmp/refractr") + } + }, + }); + return config; } diff --git a/src/example/config.toml b/src/example/config.toml index 6a908af..0c7fcc8 100644 --- a/src/example/config.toml +++ b/src/example/config.toml @@ -18,6 +18,11 @@ # This field is OPTIONAL, will default to ["master"] if omitted #branches = ["master"] +# The "work_dir" field is where refractr will write the clone to +# This field is OPTIONAL, will default to /tmp/refractr on *NIX and +# $env:TEMP\refractr on Windows +#work_dir = /tmp/refractr + [git] # The "ssh_identity_file" is your private SSH key that you will use to push updates # from the original repository. diff --git a/src/main.rs b/src/main.rs index 929ae3c..98050f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ mod config; use clap::Parser; use std::path::PathBuf; +use std::process; #[derive(Parser)] #[command(name = "refractor")] @@ -23,27 +24,26 @@ struct Args { fn main() { let args = Args::parse(); let refractr = common::Refractr { - verbose: args.verbose + verbose: args.verbose, + pid: process::id(), + unix: cfg!(unix) }; - if refractr.verbose >= 1 { - common::verbose(refractr.verbose, 1, format!("Level {} verbosity enabled", refractr.verbose.to_string())); - } + common::verbose(refractr.verbose, 1, format!("Level {} verbosity enabled", refractr.verbose.to_string())); common::verbose(refractr.verbose, 2, format!("Checking for create flag")); if args.create { - common::verbose(refractr.verbose, 2, format!("Printing sample config")); + common::verbose(refractr.verbose, 3, format!("Printing sample config")); let example = include_str!("example/config.toml"); println!("{}", example); } else { let cfgs = config::read_config(args.config, &refractr); if refractr.verbose >= 2 { + // no need to loop over configs if verbose is not at the correct level for i in cfgs { common::verbose(refractr.verbose, 2, format!("{}", i)); } } - if refractr.verbose >= 1 { - common::verbose(refractr.verbose, 1, format!("Config file(s) read successfully")); - } + common::verbose(refractr.verbose, 1, format!("Config file(s) read successfully")); } }