Compare commits
7 Commits
45914bd567
...
bdd1652595
| Author | SHA1 | Date | |
|---|---|---|---|
| bdd1652595 | |||
| b88fabb725 | |||
| 4a3fd978a4 | |||
| 7f3adc9bc2 | |||
| c25e0264b4 | |||
| 058830e510 | |||
| 5ea52fdf0e |
56
src/logger.rs
Normal file
56
src/logger.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use clap::ValueEnum;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Logger {
|
||||||
|
pub level: LogLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! define_log_function {
|
||||||
|
($name:ident, $level:ident) => {
|
||||||
|
pub fn $name<S>(&self, message: S) where S: ToString {
|
||||||
|
self.log(LogLevel::$level, message.to_string());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Logger {
|
||||||
|
pub fn log<S>(&self, level: LogLevel, message: S) where S: ToString {
|
||||||
|
if level >= self.level {
|
||||||
|
println!("{}", message.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_log_function!(info, Info);
|
||||||
|
define_log_function!(debug, Debug);
|
||||||
|
define_log_function!(error, Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default, ValueEnum)]
|
||||||
|
pub enum LogLevel {
|
||||||
|
Debug,
|
||||||
|
#[default]
|
||||||
|
Info,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! log {
|
||||||
|
($logger:expr, $level:ident, $($args:tt)*) => {
|
||||||
|
$logger.$level(format!($($args)*));
|
||||||
|
};
|
||||||
|
($logger:expr, $($args:tt)*) => {
|
||||||
|
log!($logger, info, $($args)*);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::logger::Logger;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn syntax_test() {
|
||||||
|
let logger = Logger::default();
|
||||||
|
log!(logger, "Foo {}", "bar");
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/main.rs
60
src/main.rs
@ -1,10 +1,12 @@
|
|||||||
mod action;
|
mod action;
|
||||||
mod file;
|
mod file;
|
||||||
|
mod logger;
|
||||||
mod os_string_builder;
|
mod os_string_builder;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use crate::action::{Action, FileAction, ServerActions};
|
use crate::action::{Action, FileAction, ServerActions};
|
||||||
use crate::file::{FileMatcher, FileNameInfo};
|
use crate::file::{FileMatcher, FileNameInfo};
|
||||||
|
use crate::logger::{LogLevel, Logger};
|
||||||
use crate::os_string_builder::ReplaceWithOsStr;
|
use crate::os_string_builder::ReplaceWithOsStr;
|
||||||
use clap::{Parser, Subcommand, ValueEnum};
|
use clap::{Parser, Subcommand, ValueEnum};
|
||||||
use lazy_regex::{lazy_regex, Lazy, Regex};
|
use lazy_regex::{lazy_regex, Lazy, Regex};
|
||||||
@ -41,6 +43,15 @@ struct Args {
|
|||||||
/// The ssh names and optionally home directories of the servers to perform the action on
|
/// The ssh names and optionally home directories of the servers to perform the action on
|
||||||
#[arg(num_args = 1.., value_parser = ServerReference::from_str)]
|
#[arg(num_args = 1.., value_parser = ServerReference::from_str)]
|
||||||
servers: Vec<ServerReference>,
|
servers: Vec<ServerReference>,
|
||||||
|
/// How verbose logging output should be
|
||||||
|
#[arg(long, default_value = "info", conflicts_with_all = ["quiet", "info"])]
|
||||||
|
log_level: LogLevel,
|
||||||
|
/// Only log errors
|
||||||
|
#[arg(short, long, default_value = "false", conflicts_with_all = ["info"])]
|
||||||
|
quiet: bool,
|
||||||
|
/// Log additional debugging info
|
||||||
|
#[arg(short = 'v', long, default_value = "false")]
|
||||||
|
info: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
@ -110,6 +121,17 @@ enum OldVersionPolicy {
|
|||||||
fn main() -> Result<(), String> {
|
fn main() -> Result<(), String> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let logger = Logger {
|
||||||
|
//all the below options are conflicting with each other so an if else is fine
|
||||||
|
level: if args.quiet {
|
||||||
|
LogLevel::Error
|
||||||
|
} else if args.info {
|
||||||
|
LogLevel::Debug
|
||||||
|
} else {
|
||||||
|
args.log_level
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let mut configured_servers = LazyCell::new(parse_server_configuration_from_env);
|
let mut configured_servers = LazyCell::new(parse_server_configuration_from_env);
|
||||||
let servers = args
|
let servers = args
|
||||||
.servers
|
.servers
|
||||||
@ -136,11 +158,7 @@ fn main() -> Result<(), String> {
|
|||||||
no_confirm,
|
no_confirm,
|
||||||
file_name,
|
file_name,
|
||||||
} => {
|
} => {
|
||||||
if servers.is_empty() {
|
require_non_empty_servers(&servers)?;
|
||||||
println!("Please provide some servers to upload to. See --help");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
start_ssh_agent()?;
|
start_ssh_agent()?;
|
||||||
|
|
||||||
let file_name_info =
|
let file_name_info =
|
||||||
@ -226,13 +244,13 @@ fn main() -> Result<(), String> {
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, String>>()?;
|
.collect::<Result<Vec<_>, String>>()?;
|
||||||
|
|
||||||
println!("The following actions will be performed:");
|
log!(logger, "The following actions will be performed: ");
|
||||||
for server_actions in &actions {
|
for server_actions in &actions {
|
||||||
println!("{server_actions}");
|
log!(logger, "{server_actions}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if !no_confirm {
|
if !no_confirm {
|
||||||
print!("Continue? [Y|n] ");
|
log!(logger, "Continue? [Y|n] ");
|
||||||
std::io::stdout().flush().expect("failed to flush stdout");
|
std::io::stdout().flush().expect("failed to flush stdout");
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
std::io::stdin()
|
std::io::stdin()
|
||||||
@ -240,7 +258,7 @@ fn main() -> Result<(), String> {
|
|||||||
.expect("failed to read stdin");
|
.expect("failed to read stdin");
|
||||||
match buffer.to_lowercase().trim() {
|
match buffer.to_lowercase().trim() {
|
||||||
"n" | "no" => {
|
"n" | "no" => {
|
||||||
println!("Aborting...");
|
log!(logger, "Aborting...");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -249,7 +267,7 @@ fn main() -> Result<(), String> {
|
|||||||
|
|
||||||
for server_actions in actions {
|
for server_actions in actions {
|
||||||
let server = server_actions.server;
|
let server = server_actions.server;
|
||||||
println!("Performing actions on {}...", server.ssh_name);
|
log!(logger, "Performing actions on {}...", server.ssh_name);
|
||||||
for file_action in server_actions.actions {
|
for file_action in server_actions.actions {
|
||||||
match file_action.kind {
|
match file_action.kind {
|
||||||
Action::Add | Action::Replace => {
|
Action::Add | Action::Replace => {
|
||||||
@ -290,12 +308,13 @@ fn main() -> Result<(), String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Done!");
|
log!(logger, "Done!");
|
||||||
}
|
}
|
||||||
Command::Command { command } => {
|
Command::Command { command } => {
|
||||||
start_ssh_agent()?;
|
start_ssh_agent()?;
|
||||||
|
require_non_empty_servers(&servers)?;
|
||||||
for server in servers {
|
for server in servers {
|
||||||
println!("Running command on '{}'...", server.ssh_name);
|
log!(logger, "Running command on '{}'...", server.ssh_name);
|
||||||
ShellCmd::new("ssh")
|
ShellCmd::new("ssh")
|
||||||
.arg(server.ssh_name)
|
.arg(server.ssh_name)
|
||||||
.arg(osf!("cd ") + server.server_directory_path + "; " + &command)
|
.arg(osf!("cd ") + server.server_directory_path + "; " + &command)
|
||||||
@ -304,7 +323,7 @@ fn main() -> Result<(), String> {
|
|||||||
.wait()
|
.wait()
|
||||||
.map_err(|e| format!("failed to wait for ssh command completion: {e}"))?;
|
.map_err(|e| format!("failed to wait for ssh command completion: {e}"))?;
|
||||||
}
|
}
|
||||||
println!("Done!");
|
log!(logger, "Done!");
|
||||||
}
|
}
|
||||||
Command::Editor {
|
Command::Editor {
|
||||||
file,
|
file,
|
||||||
@ -331,16 +350,17 @@ fn main() -> Result<(), String> {
|
|||||||
.any(|entry| entry.file_name() == file_name)
|
.any(|entry| entry.file_name() == file_name)
|
||||||
{
|
{
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"A file with the name {} already exists in {}. You can override it with --override",
|
"A file with the name {} already exists in {}. You can override it with --override or -f",
|
||||||
file_name.to_string_lossy(),
|
file_name.to_string_lossy(),
|
||||||
working_directory.to_string_lossy()
|
working_directory.to_string_lossy()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
require_non_empty_servers(&servers)?;
|
||||||
start_ssh_agent()?;
|
start_ssh_agent()?;
|
||||||
|
|
||||||
for server in servers {
|
for server in servers {
|
||||||
println!("Downloading file from {}...", server.ssh_name);
|
log!(logger, "Downloading file from {}...", server.ssh_name);
|
||||||
ShellCmd::new("scp")
|
ShellCmd::new("scp")
|
||||||
.arg(osf!(&server.ssh_name) + ":" + server.server_directory_path.join(&file))
|
.arg(osf!(&server.ssh_name) + ":" + server.server_directory_path.join(&file))
|
||||||
.arg(&working_directory)
|
.arg(&working_directory)
|
||||||
@ -368,13 +388,21 @@ fn main() -> Result<(), String> {
|
|||||||
.map_err(|e| format!("failed to upload file again: {e}"))?;
|
.map_err(|e| format!("failed to upload file again: {e}"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Done!");
|
log!(logger, "Done!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn require_non_empty_servers(servers: &[Server]) -> Result<(), String> {
|
||||||
|
if servers.is_empty() {
|
||||||
|
Err("You did not provide any servers for this operation. Please see --help".to_string())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn start_ssh_agent() -> Result<(), String> {
|
fn start_ssh_agent() -> Result<(), String> {
|
||||||
//start the ssh agent
|
//start the ssh agent
|
||||||
let agent_output = ShellCmd::new("ssh-agent")
|
let agent_output = ShellCmd::new("ssh-agent")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user