diff --git a/src/main.rs b/src/main.rs index 1ba756a..24fc799 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,7 +45,7 @@ struct Args { #[command(subcommand)] command: Command, /// 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 = 0.., value_parser = ServerReference::from_str)] servers: Vec, /// How verbose logging output should be #[arg(long, default_value = "info", conflicts_with_all = ["quiet", "info"])] @@ -86,6 +86,9 @@ enum Command { /// Only upload files which are not present yet on the target server #[arg(short, long, default_value = "false")] pure: bool, + /// The prefixes of the names of files not to upload + #[arg(short, long, num_args = 0..)] + exclude: Vec, }, /// Execute a command on the servers #[command(visible_short_flag_alias = 'c')] @@ -190,6 +193,7 @@ fn main() -> Result<(), String> { no_confirm, file_name, pure, + exclude, } => { require_non_empty_servers(&servers)?; require_non_empty(&files, "files to upload")?; @@ -241,7 +245,6 @@ fn main() -> Result<(), String> { .into_iter() .flatten() .collect(); - log!(logger, debug, "canonical files: {files:?}"); } ServerAddress::Localhost => files .iter() @@ -252,13 +255,25 @@ fn main() -> Result<(), String> { } let file_details = files - .iter() + .into_iter() .map(|file| { FileNameInfo::try_from(file.clone()) - .map(|info| (PathBuf::from(file), info)) + .map(|info| (PathBuf::from(&file), info)) .map_err(|e| format!("Bad file '{}': {e}", file.to_string_lossy())) }) - .collect::, _>>()?; + .collect::, _>>()? + .into_iter() + .filter(|(_, info)| { + !exclude + .iter() + .any(|exclude| info.to_full_file_name().starts_with(exclude)) + }) + .collect::>(); + + log!(logger, debug, "Files to upload: "); + for (file, _) in &file_details { + log!(logger, debug, "- {}", file.to_string_lossy()); + } //create overview of what has to be done on each server let actions = servers @@ -310,7 +325,7 @@ fn main() -> Result<(), String> { let mut ls_lines = ls_output.lines(); if pure && ls_lines.clone().any(|file| file == file_name) { - log!(logger, debug, "file is already present: {}", file_name); + log!(logger, debug, "file is already present on {}: {}", server.get_name(), file_name); return vec![]; //ignore that file, since it is already present } @@ -362,10 +377,10 @@ fn main() -> Result<(), String> { .into_iter() .filter(|server_actions| !server_actions.actions.is_empty()) .collect::>(); - - if actions.is_empty() { + + if actions.is_empty() { log!(logger, "Nothing to be done, everything is up to date"); - return Ok(()) + return Ok(()); } log!(logger, "The following actions will be performed: ");