149 lines
3.7 KiB
Rust
149 lines
3.7 KiB
Rust
/*
|
|
* Copyright 2025 Bryson Steck <me@brysonsteck.xyz>
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
mod common;
|
|
mod config;
|
|
mod refractr;
|
|
|
|
use crate::refractr::Refractr;
|
|
|
|
use clap::Parser;
|
|
use std::path::PathBuf;
|
|
use std::process;
|
|
#[cfg(target_family = "windows")]
|
|
use username;
|
|
#[cfg(target_family = "unix")]
|
|
use users;
|
|
|
|
#[derive(Parser)]
|
|
#[command(name = "refractr")]
|
|
#[command(version = option_env!("CARGO_PKG_VERSION"))]
|
|
#[command(about = "An automated pull/push utility for mirroring Git repositories")]
|
|
#[command(long_about = None)]
|
|
struct Args {
|
|
#[arg(short, long, help = "Specify a config file", default_value = get_config_default())]
|
|
config: Vec<PathBuf>,
|
|
|
|
#[arg(short, long, help = "Specify the level of verbosity", action = clap::ArgAction::Count)]
|
|
verbose: u8,
|
|
|
|
#[arg(
|
|
short = 'e',
|
|
long,
|
|
help = "Output a full, commented config file and exit"
|
|
)]
|
|
create: bool,
|
|
|
|
#[arg(
|
|
short = 's',
|
|
long,
|
|
help = "Exit on push and unknown host errors instead of ignoring them"
|
|
)]
|
|
strict: bool,
|
|
}
|
|
|
|
fn get_config_default() -> &'static str {
|
|
#[cfg(target_os = "windows")]
|
|
return "C:\\ProgramData\\refractr\\config.toml";
|
|
#[cfg(target_os = "linux")]
|
|
return "/etc/refractr/config.toml";
|
|
#[cfg(any(
|
|
target_os = "freebsd",
|
|
target_os = "openbsd",
|
|
target_os = "netbsd",
|
|
target_os = "macos"
|
|
))]
|
|
return "/usr/local/etc/refractr/config.toml";
|
|
}
|
|
|
|
#[quit::main]
|
|
fn main() -> Result<(), String> {
|
|
let args = Args::parse();
|
|
let refractr = Refractr {
|
|
docker: match option_env!("REFRACTR_DOCKER") {
|
|
Some(v) => match v {
|
|
"true" => true,
|
|
_ => false,
|
|
},
|
|
None => false,
|
|
},
|
|
pid: process::id(),
|
|
strict: args.strict,
|
|
unix: cfg!(unix),
|
|
verbose: args.verbose,
|
|
};
|
|
|
|
// warn to avoid root/admin
|
|
// unix-like
|
|
#[cfg(target_family = "unix")]
|
|
if users::get_current_uid() == 0 {
|
|
common::warning(format!("this program should not ran as root"));
|
|
}
|
|
// windows
|
|
#[cfg(target_family = "windows")]
|
|
match username::get_user_name() {
|
|
Ok(user) => {
|
|
if user.contains("Administrator") || user.contains("SYSTEM") {
|
|
common::warning(format!("this program should not ran as {}", user));
|
|
}
|
|
},
|
|
Err(_) => common::warning(format!("failed to get process username")),
|
|
}
|
|
|
|
common::verbose(
|
|
refractr.verbose,
|
|
1,
|
|
format!(
|
|
"refractr started with level {} verbosity enabled",
|
|
refractr.verbose.to_string()
|
|
),
|
|
);
|
|
common::verbose(refractr.verbose, 3, format!("Process ID: {}", refractr.pid));
|
|
common::verbose(
|
|
refractr.verbose,
|
|
3,
|
|
format!("Running in Docker: {}", refractr.docker),
|
|
);
|
|
common::verbose(
|
|
refractr.verbose,
|
|
3,
|
|
format!("System is UNIX(-like): {}", refractr.unix),
|
|
);
|
|
common::verbose(refractr.verbose, 2, format!("Checking for create flag"));
|
|
if args.create {
|
|
common::verbose(refractr.verbose, 3, format!("Printing sample config"));
|
|
let example = include_str!("example/config.toml");
|
|
println!("{}", example);
|
|
return Ok(());
|
|
}
|
|
|
|
let mut cfgs = vec![];
|
|
match config::read_config(args.config, &refractr) {
|
|
Ok(c) => cfgs = c,
|
|
Err(e) => common::error(format!("{}", e), common::ExitCode::ConfigError),
|
|
};
|
|
|
|
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));
|
|
}
|
|
}
|
|
|
|
common::verbose(
|
|
refractr.verbose,
|
|
1,
|
|
format!("Config file(s) read successfully"),
|
|
);
|
|
match refractr.run(cfgs) {
|
|
Ok(_) => (),
|
|
Err(e) => common::error(format!("{}", e.msg), e.code),
|
|
};
|
|
|
|
Ok(())
|
|
}
|