made config more robust

This commit is contained in:
Bryson Steck 2025-03-02 11:47:29 -07:00
parent d8097ade47
commit 7998e49958
4 changed files with 111 additions and 20 deletions

View file

@ -1,8 +1,12 @@
pub struct Refractr {
pub verbose: u8
}
pub fn verbose(level: u8, msg_lvl: u8, msg: String) {
if level < msg_lvl { return };
let mut prefix = String::new();
for i in 0..msg_lvl {
for _ in 0..msg_lvl {
prefix += "=";
}

View file

@ -1,14 +1,74 @@
use crate::common;
use core::fmt;
use std::io::Read;
use std::path::PathBuf;
use std::fs::File;
use std::fs;
use std::fs::{File, Metadata};
use toml;
use serde_derive::Deserialize;
pub struct ConfigFile {
pub path: String,
pub file: Metadata,
pub config: Config
}
impl fmt::Display for ConfigFile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let branches_list = match &self.config.branches {
None => String::from("All branches"),
Some(vec) => {
let mut out = String::from("[");
for i in 0..vec.len() {
out = format!("{}{}", out, vec[i]);
if i < vec.len() - 1 {
out.push_str(", ");
}
}
out.push(']');
out
}
};
let mut to_list = String::from("[");
for i in 0..self.config.to.len() {
to_list.push_str(&self.config.to[i]);
if i < self.config.to.len() - 1 {
to_list.push_str(", ");
}
};
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\
{}"
, 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())
})
}
}
#[derive(Deserialize)]
pub struct Config {
struct Config {
from: String,
to: Vec<String>,
branches: Vec<String>,
branches: Option<Vec<String>>,
git: Git,
schedule: Schedule
}
@ -21,28 +81,43 @@ struct Git {
#[derive(Deserialize)]
struct Schedule {
enabled: bool,
duration: i32,
interval: Option<i32>,
}
pub fn read_config(paths: Vec<PathBuf>) -> Vec<Config> {
let mut configs: Vec<Config> = vec![];
pub fn read_config(paths: Vec<PathBuf>, refractr: &common::Refractr) -> Vec<ConfigFile> {
let mut config_files: Vec<ConfigFile> = vec![];
for path in paths {
if refractr.verbose >= 1 {
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!("unable to open {}: {}", path.as_path().display(), e),
Err(e) => panic!("refractr: unable to open {}: {}", path.as_path().display(), e),
Ok(file) => file
};
if let Err(e) = file.read_to_string(&mut data) {
panic!("unable to read {}: {}", path.as_path().display(), e)
panic!("refractr: unable to read {}: {}", path.as_path().display(), e)
}
configs.push(verify_config(toml::from_str(&data).unwrap()));
let config_file = ConfigFile {
path: String::from(path.to_string_lossy()),
file: match fs::metadata(&path) {
Err(e) => 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);
}
return configs;
return config_files;
}
fn verify_config(config: Config) -> Config {
if config.schedule.enabled {
assert_ne!(config.schedule.interval, None);
}
return config;
}

View file

@ -29,7 +29,7 @@
# This field is REQUIRED.
#enabled = false
# The "duration" field is the amount of seconds refractor will wait before
# The "interval" field is the amount of seconds refractor will wait before
# pulling updates from the original repository if the schedule feature is enabled.
# This field is REQUIRED if "enabled" is set to true, otherwise OPTIONAL
#duration = 300
#interval = 300

View file

@ -22,16 +22,28 @@ struct Args {
fn main() {
let args = Args::parse();
if args.verbose >= 1 {
common::verbose(args.verbose, 1, format!("Level {} verbosity enabled", args.verbose.to_string()));
let refractr = common::Refractr {
verbose: args.verbose
};
if refractr.verbose >= 1 {
common::verbose(refractr.verbose, 1, format!("Level {} verbosity enabled", refractr.verbose.to_string()));
}
common::verbose(args.verbose, 2, format!("Checking for create flag"));
common::verbose(refractr.verbose, 2, format!("Checking for create flag"));
if args.create {
common::verbose(args.verbose, 2, format!("Printing sample config"));
common::verbose(refractr.verbose, 2, format!("Printing sample config"));
let example = include_str!("example/config.toml");
println!("{}", example);
} else {
let cfg = config::read_config(args.config);
let cfgs = config::read_config(args.config, &refractr);
if refractr.verbose >= 2 {
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"));
}
}
}