diff --git a/rens-cli/src/cli/renaming.rs b/rens-cli/src/cli/renaming.rs index 3a30ab3..57d8241 100644 --- a/rens-cli/src/cli/renaming.rs +++ b/rens-cli/src/cli/renaming.rs @@ -1,11 +1,11 @@ /* Modules */ -mod options; +pub mod options; +/* Crate imports */ +use self::options::Options; /* Dependencies */ use clap::Subcommand; use regex::{Regex, RegexBuilder}; use rens_common::Strategy; -/* Re-exports */ -pub use self::options::{ConfirmOption, Options, OverrideOption}; #[derive(Debug, Subcommand)] pub enum Mode { diff --git a/rens-cli/src/cli/renaming/options.rs b/rens-cli/src/cli/renaming/options.rs index 5f6aa25..d321d43 100644 --- a/rens-cli/src/cli/renaming/options.rs +++ b/rens-cli/src/cli/renaming/options.rs @@ -1,57 +1,54 @@ /* Modules */ mod confirmations; +mod git; mod paths; mod pattern; mod recursion; /* Built-in imports */ use std::{io, path::PathBuf}; /* Dependencies */ -use clap::{ArgAction, Args, ValueHint}; +use clap::{Args, ValueHint}; use rens_common::RenameTarget; /* Re-exports */ pub use self::{ confirmations::{ConfirmOption, Confirmations, OverrideOption}, + git::Options as GitOpt, paths::Options as PathsOpt, pattern::Options as PatternOpt, recursion::Recursion, }; #[derive(Debug, Args)] +#[command(next_display_order = 0)] pub struct Options { - /// Weather to rename the file stem, extension or both. + /// Wether to rename the file stem, extension or both. /// /// Note: filename = . #[arg(long, short, default_value = "both", value_enum)] pub target: RenameTarget, - #[command(flatten)] - pub recursion: Recursion, + /// Paths to the elements you want to rename. + #[arg( + required = true, + value_parser = path_exists, + value_hint = ValueHint::AnyPath, + )] + pub paths: Vec, #[command(flatten)] pub confirmations: Confirmations, + #[command(flatten)] + pub git_opt: GitOpt, + #[command(flatten)] pub paths_opt: PathsOpt, #[command(flatten)] pub pattern_opt: PatternOpt, - #[arg( - name = "ignore", - long, short, - default_value_t = false, - action = ArgAction::SetTrue, - )] - /// Parse and follow `.gitignore` (local and global), `.ignore` and `.git/info/exclude` files. - pub auto_ignore: bool, - - /// Paths to the elements you want to rename. - #[arg( - required = true, - value_parser = path_exists, - value_hint = ValueHint::AnyPath, - )] - pub paths: Vec, + #[command(flatten)] + pub recursion: Recursion, } fn path_exists(input: &str) -> io::Result { diff --git a/rens-cli/src/cli/renaming/options/confirmations.rs b/rens-cli/src/cli/renaming/options/confirmations.rs index 4cf4fb4..836904a 100644 --- a/rens-cli/src/cli/renaming/options/confirmations.rs +++ b/rens-cli/src/cli/renaming/options/confirmations.rs @@ -2,6 +2,7 @@ use clap::{Args, ValueEnum}; #[derive(Debug, Args)] +#[command(next_help_heading = "Confirmation Options")] pub struct Confirmations { /// Behavior when a renamed file already exists. #[arg( diff --git a/rens-cli/src/cli/renaming/options/git.rs b/rens-cli/src/cli/renaming/options/git.rs new file mode 100644 index 0000000..606ed0c --- /dev/null +++ b/rens-cli/src/cli/renaming/options/git.rs @@ -0,0 +1,33 @@ +/* Dependencies */ +use clap::{ArgAction, Args}; + +#[derive(Debug, Args)] +#[group(id = "git_options")] +#[command(next_help_heading = "Git integration Options", display_order = 0)] +pub struct Options { + #[arg( + name = "ignore", + long, short, + default_value_t = false, + action = ArgAction::SetTrue, + )] + /// Parse and follow `.gitignore` (local and global), `.ignore` and `.git/info/exclude` files. + pub auto_ignore: bool, +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::{CommandFactory, Parser}; + + #[derive(Debug, Parser)] + struct TestParser { + #[command(flatten)] + pub options: Options, + } + + #[test] + fn verify_conformity() { + TestParser::command().debug_assert(); + } +} diff --git a/rens-cli/src/cli/renaming/options/paths.rs b/rens-cli/src/cli/renaming/options/paths.rs index 0b82b91..791bb27 100644 --- a/rens-cli/src/cli/renaming/options/paths.rs +++ b/rens-cli/src/cli/renaming/options/paths.rs @@ -2,7 +2,8 @@ use clap::{ArgAction, Args}; #[derive(Debug, Args)] -#[group(skip)] +#[group(id = "path_options")] +#[command(next_help_heading = "Path Options")] pub struct Options { /// Canonicalize all paths instead of using relative ones. #[arg( diff --git a/rens-cli/src/cli/renaming/options/pattern.rs b/rens-cli/src/cli/renaming/options/pattern.rs index bbd7afc..1ef7836 100644 --- a/rens-cli/src/cli/renaming/options/pattern.rs +++ b/rens-cli/src/cli/renaming/options/pattern.rs @@ -4,9 +4,10 @@ use core::num::NonZeroUsize; use clap::Args; #[derive(Debug, Args)] -#[group(skip)] +#[group(id = "pattern_options")] +#[command(next_help_heading = "Pattern Options")] pub struct Options { - /// Weather or not the pattern should be made case sensitive. + /// Wether or not the pattern should be made case sensitive. /// /// Note: No effect if regex pattern already includes case settings at its beggining. #[arg(long, default_value_t = false)] diff --git a/rens-cli/src/cli/renaming/options/recursion.rs b/rens-cli/src/cli/renaming/options/recursion.rs index e71afd0..03f299f 100644 --- a/rens-cli/src/cli/renaming/options/recursion.rs +++ b/rens-cli/src/cli/renaming/options/recursion.rs @@ -2,30 +2,31 @@ use clap::{builder::ArgPredicate, ArgAction, Args}; #[derive(Debug, Args)] +#[command(next_help_heading = "Recursion Options")] pub struct Recursion { - /// Decides if folder paths includes their children recursively. - /// - /// Note: implied if --depth is used. + /// When traversing directories, include hidden files. #[arg( long, short, default_value_t = false, - default_value_if("depth", ArgPredicate::IsPresent, "true"), action = ArgAction::SetTrue, )] - pub recursive: bool, + pub allow_hidden: bool, /// If recursive mode is enabled, decides how deep the renaming goes. #[arg(long, value_name = "depth")] // Note: None gets used as `As deep as possible`. pub depth: Option, - /// When traversing directories, include hidden files. + /// Decides if folder paths includes their children recursively. + /// + /// Note: implied if --depth is used. #[arg( long, short, default_value_t = false, + default_value_if("depth", ArgPredicate::IsPresent, "true"), action = ArgAction::SetTrue, )] - pub allow_hidden: bool, + pub recursive: bool, } #[cfg(test)] diff --git a/rens-cli/src/main.rs b/rens-cli/src/main.rs index 32367d0..3218ede 100644 --- a/rens-cli/src/main.rs +++ b/rens-cli/src/main.rs @@ -6,7 +6,7 @@ mod utils; use std::{fs, io}; /* Crate imports */ use cli::{ - renaming::{ConfirmOption, Options}, + renaming::options::{ConfirmOption, GitOpt, Options}, Cli, Commands, }; use utils::ask_for_confirm; @@ -55,7 +55,7 @@ fn main() -> anyhow::Result<()> { let ( strategy, Options { - auto_ignore, + git_opt: GitOpt { auto_ignore }, confirmations, paths_opt, recursion, diff --git a/rens-cli/src/utils.rs b/rens-cli/src/utils.rs index 7458d72..63a940c 100644 --- a/rens-cli/src/utils.rs +++ b/rens-cli/src/utils.rs @@ -1,7 +1,7 @@ /* Built-in imports */ use std::io::{self, Write}; /* Crate imports */ -use crate::cli::renaming::OverrideOption; +use crate::cli::renaming::options::OverrideOption; #[allow(clippy::expect_used)] pub fn ask_for_confirm(prompt: &str) -> bool {