add work_dir option

This commit is contained in:
Bryson Steck 2025-03-02 14:39:12 -07:00
parent 7998e49958
commit 03aef02abc
5 changed files with 76 additions and 36 deletions

View file

@ -1,8 +1,9 @@
FROM rust:latest FROM rust:slim
WORKDIR /usr/src/refractr WORKDIR /usr/src/refractr
COPY . . COPY . .
RUN cargo install --path . RUN cargo build --release
RUN cargo install --locked --path .
CMD ["refractr"] CMD ["refractr"]

View file

@ -1,6 +1,8 @@
pub struct Refractr { 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) { pub fn verbose(level: u8, msg_lvl: u8, msg: String) {

View file

@ -3,6 +3,7 @@ use core::fmt;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
use std::fs; use std::fs;
use std::env;
use std::fs::{File, Metadata}; use std::fs::{File, Metadata};
use toml; use toml;
use serde_derive::Deserialize; use serde_derive::Deserialize;
@ -39,19 +40,21 @@ impl fmt::Display for ConfigFile {
}; };
to_list.push(']'); to_list.push(']');
write!(f, "Config file: \"{}\"\n \ let work_dir_path = match &self.config.work_dir {
Is a file: {}\n \ None => {
Read only: {}\n \ if cfg!(windows) {
Configuration:\n \ format!("Using default \"{}\\refractr\"", match env::var("TEMP") {
Git repo to clone: {}\n \ Ok(val) => val,
Git repos to push clone to: {}\n \ Err(_) => format!("This shouldn't happen!")
Branches of clone to push: {}\n \ })
SSH key for pushing clone: {}\n \ } else {
Schedule enabled: {}\n\ format!("Using default: /tmp/refractr")
{}" }
, 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 Some(path) => format!("{}", path)
, match self.config.schedule.interval { };
let schedule_interval = match self.config.schedule.interval {
None => { None => {
if !self.config.schedule.enabled { if !self.config.schedule.enabled {
String::from("") String::from("")
@ -59,16 +62,32 @@ impl fmt::Display for ConfigFile {
String::from("This shouldn't happen!\n") String::from("This shouldn't happen!\n")
} }
}, },
Some(int) => format!(" Scheduled interval in seconds: {}\n", int.to_string()) 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, work_dir_path, self.config.git.ssh_identity_file, self.config.schedule.enabled
, schedule_interval)
} }
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct Config { pub struct Config {
from: String, from: String,
to: Vec<String>, to: Vec<String>,
branches: Option<Vec<String>>, branches: Option<Vec<String>>,
work_dir: Option<String>,
git: Git, git: Git,
schedule: Schedule schedule: Schedule
} }
@ -87,9 +106,7 @@ struct Schedule {
pub fn read_config(paths: Vec<PathBuf>, refractr: &common::Refractr) -> Vec<ConfigFile> { pub fn read_config(paths: Vec<PathBuf>, refractr: &common::Refractr) -> Vec<ConfigFile> {
let mut config_files: Vec<ConfigFile> = vec![]; let mut config_files: Vec<ConfigFile> = vec![];
for path in paths { 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 data = String::new();
let mut file = match File::open(path.as_path()) { let mut file = match File::open(path.as_path()) {
Err(e) => panic!("refractr: unable to open {}: {}", path.as_path().display(), e), Err(e) => panic!("refractr: unable to open {}: {}", path.as_path().display(), e),
@ -103,11 +120,12 @@ pub fn read_config(paths: Vec<PathBuf>, refractr: &common::Refractr) -> Vec<Conf
let config_file = ConfigFile { let config_file = ConfigFile {
path: String::from(path.to_string_lossy()), path: String::from(path.to_string_lossy()),
file: match fs::metadata(&path) { file: match fs::metadata(&path) {
Err(e) => panic!("refractr: cannot obtain metadata: {}", path.as_path().display()), Err(_) => panic!("refractr: cannot obtain metadata: {}", path.as_path().display()),
Ok(metadata) => metadata Ok(metadata) => metadata
}, },
config: verify_config(toml::from_str(&data).unwrap()) config: verify_config(toml::from_str(&data).unwrap())
}; };
config_files.push(config_file); config_files.push(config_file);
} }
@ -119,5 +137,19 @@ fn verify_config(config: Config) -> Config {
assert_ne!(config.schedule.interval, None); 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; return config;
} }

View file

@ -18,6 +18,11 @@
# This field is OPTIONAL, will default to ["master"] if omitted # This field is OPTIONAL, will default to ["master"] if omitted
#branches = ["master"] #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] [git]
# The "ssh_identity_file" is your private SSH key that you will use to push updates # The "ssh_identity_file" is your private SSH key that you will use to push updates
# from the original repository. # from the original repository.

View file

@ -3,6 +3,7 @@ mod config;
use clap::Parser; use clap::Parser;
use std::path::PathBuf; use std::path::PathBuf;
use std::process;
#[derive(Parser)] #[derive(Parser)]
#[command(name = "refractor")] #[command(name = "refractor")]
@ -23,27 +24,26 @@ struct Args {
fn main() { fn main() {
let args = Args::parse(); let args = Args::parse();
let refractr = common::Refractr { 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")); common::verbose(refractr.verbose, 2, format!("Checking for create flag"));
if args.create { 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"); let example = include_str!("example/config.toml");
println!("{}", example); println!("{}", example);
} else { } else {
let cfgs = config::read_config(args.config, &refractr); let cfgs = config::read_config(args.config, &refractr);
if refractr.verbose >= 2 { if refractr.verbose >= 2 {
// no need to loop over configs if verbose is not at the correct level
for i in cfgs { for i in cfgs {
common::verbose(refractr.verbose, 2, format!("{}", i)); 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"));
} }
}
} }