diff --git a/Cargo.lock b/Cargo.lock index c4196c1..30e4233 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,20 +73,13 @@ dependencies = [ [[package]] name = "gather" -version = "0.1.0" +version = "0.2.0" dependencies = [ "clap", "env_logger", - "glob", "log", ] -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - [[package]] name = "hermit-abi" version = "0.1.19" diff --git a/Cargo.toml b/Cargo.toml index 5520bc0..79e719d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gather" -version = "0.1.0" +version = "0.2.0" description = "Gathers files from directories and subdirectories into a target directory." license = "Apache-2.0" authors = ["evensolberg "] @@ -11,7 +11,6 @@ include = ["src/**/*", "README.md"] [dependencies] clap = "2.34.0" env_logger = "0.9.0" -glob = "0.3.0" log = "0.4.14" [features] diff --git a/README.md b/README.md index 4e905d7..c053c49 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,33 @@ Gathers files from directories and subdirectories into a target directory. `gather [FLAGS] ... [--] ` +Example: + +`gather -m -u **/*.png **/*.jpg -- ../images/` + ### Flags |Short Form|Long Form|Description| |:----|:---|:----------| `-d`|`--debug`|Output debug information as we go. Supply it twice for trace-level logs. -`-o`|`--detail-off`|Don't print detailed information about each file processed. `-h`|`--help`|Prints help information. `-m`|`--move`|Move files instead of copying them. +`-o`|`--detail-off`|Don't print detailed information about each file processed. +`-p`|`--print-summary`|Print summary information about the number of files gathered. `-q`|`--quiet`|Don't produce any output except errors while working. +`-r`|`--dry-run`|Iterate through the files and produce output without actually processing anything. `-s`|`--stop-on-error`|Stop on error. If this flag isn't set, the application will attempt to continue in case of error. -`-u`|`--print-summary`|Print summary information about the number of files gathered. `-V`|`--version`|Prints version information ### Arguments |Argument|Description| |:-------|:----------| -`...`|One or more file(s) to process. Wildcards and multiple files (e.g. `2019*.pdf 2020*.pdf`) are supported. Use `**` glob to recurse (i.e. `**/*.pdf`). +`...`|One or more file(s) to process. Wildcards and multiple files (e.g. `2019*.pdf 2020*.pdf`) are supported. Use `**` glob to recurse (i.e. `**/*.pdf`).
**Note: Case sensitive.** ``|The target directory into which files are to be gathered. ## Notes Currently, using `zsh` on the Mac, the program exits with an error if one of the `` arguments isn't found (ie. `*.jpg *.jpeg *.png` - `*.jpeg` not found). This is due to how this is handled in the shell. -You can work around this by using the following command: `setopt NO_MATCH` +You can work around this by using the following command: `setopt +o NO_MATCH` diff --git a/justfile b/justfile index ec15d6d..e3f245a 100644 --- a/justfile +++ b/justfile @@ -142,7 +142,7 @@ alias fmt := format # Copy this settings files to the templates directory @just: cp {{invocation_directory()}}/justfile ~/CloudStation/Source/_Templates/justfile.template - -sd {{application}} gather ~/CloudStation/Source/_Templates/justfile.template + -sd {{application}} myapplication ~/CloudStation/Source/_Templates/justfile.template cp {{invocation_directory()}}/deny.toml ~/CloudStation/Source/_Templates/deny.toml # Check, but verbose diff --git a/src/main.rs b/src/main.rs index 4531ad8..c3ed79e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,6 @@ use clap::{App, Arg}; // Command line use std::error::Error; use std::path::Path; -use glob::glob; - // Logging use env_logger::{Builder, Target}; use log::LevelFilter; @@ -52,6 +50,14 @@ fn run() -> Result<(), Box> { .takes_value(false) .hidden(false), ) + .arg( // Dry-run + Arg::with_name("dry-run") + .short("r") + .long("dry-run") + .multiple(false) + .help("Iterate through the files and produce output without actually processing anything.") + .takes_value(false) + ) .arg( // Hidden debug parameter Arg::with_name("debug") .short("d") @@ -71,7 +77,7 @@ fn run() -> Result<(), Box> { ) .arg( // Print summary information Arg::with_name("summary") - .short("u") + .short("p") .long("print-summary") .multiple(false) .help("Print summary information about the number of files gathered.") @@ -141,6 +147,10 @@ fn run() -> Result<(), Box> { } let show_detail_info = !cli_args.is_present("detail-off"); + let dry_run = cli_args.is_present("dry-run"); + if dry_run { + log::info!("Dry-run starting."); + } let mut total_file_count: usize = 0; let mut processed_file_count: usize = 0; @@ -148,92 +158,81 @@ fn run() -> Result<(), Box> { // Gather files for filename in files_to_gather { - for entry in glob(filename).unwrap() { - if let Ok(path) = entry { - let new_filename = Path::new(target_dir).join(Path::new(path.file_name().unwrap())); - let targetfile = new_filename.as_path(); + let new_filename = + Path::new(target_dir).join(Path::new(&filename).file_name().unwrap_or_default()); + let targetfile = new_filename.as_path(); - total_file_count += 1; + total_file_count += 1; - if move_files { - log::debug!( - "Moving file {} to {}", - &path.to_str().unwrap(), - &targetfile.display() - ); - match std::fs::rename(&path, targetfile) { - Ok(_) => { - if show_detail_info { - log::info!( - " {} ==> {}", - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ); - } - processed_file_count += 1; + if dry_run { + if move_files { + log::info!(" {} ==> {}", filename, targetfile.to_str().unwrap()); + processed_file_count += 1; + } else { + log::info!(" {} --> {}", filename, targetfile.to_str().unwrap()); + processed_file_count += 1; + } + } else { + if move_files { + log::debug!("Moving file {} to {}", filename, targetfile.display()); + match std::fs::rename(&filename, targetfile) { + Ok(_) => { + if show_detail_info { + log::info!(" {} ==> {}", filename, targetfile.to_str().unwrap()); } - Err(err) => { - if stop_on_error { - return Err(format!( - "Error: {}. Unable to move file {} to {}. Halting.", - err, - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ) - .into()); - } else { - log::warn!( - "Unable to move file {} to {}. Continuing.", - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ); - skipped_file_count += 1; - } + processed_file_count += 1; + } + Err(err) => { + if stop_on_error { + return Err(format!( + "Error: {}. Unable to move file {} to {}. Halting.", + err, + filename, + targetfile.to_str().unwrap() + ) + .into()); + } else { + log::warn!( + "Unable to move file {} to {}. Continuing.", + filename, + targetfile.to_str().unwrap() + ); + skipped_file_count += 1; } } - } else { - // Copy files - log::debug!( - "Copying file {} to {}", - &path.to_str().unwrap(), - &targetfile.display() - ); - match std::fs::copy(&path.to_str().unwrap(), targetfile) { - Ok(_) => { - if show_detail_info { - log::info!( - " {} --> {}", - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ); - } - processed_file_count += 1; + } + } else { + // Copy files + log::debug!("Copying file {} to {}", &filename, &targetfile.display()); + match std::fs::copy(&filename, targetfile) { + Ok(_) => { + if show_detail_info { + log::info!(" {} --> {}", filename, targetfile.to_str().unwrap()); } - Err(err) => { - if stop_on_error { - return Err(format!( - "Error: {}. Unable to copy file {} to {}. Halting.", - err, - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ) - .into()); - } else { - log::warn!( - "Unable to copy file {} to {}. Continuing.", - path.to_str().unwrap(), - targetfile.to_str().unwrap() - ); - skipped_file_count += 1; - } + processed_file_count += 1; + } + Err(err) => { + if stop_on_error { + return Err(format!( + "Error: {}. Unable to copy file {} to {}. Halting.", + err, + filename, + targetfile.to_str().unwrap() + ) + .into()); + } else { + log::warn!( + "Unable to copy file {} to {}. Continuing.", + filename, + targetfile.to_str().unwrap() + ); + skipped_file_count += 1; } } - } // if move_files - } else { - log::error!("Unable to process {}", &entry?.to_str().unwrap()); - } - } - } + } + } // if move_files + } // if dry_run + } // for filename // Print summary information if cli_args.is_present("summary") {