diff options
Diffstat (limited to 'src/cli.rs')
| -rw-r--r-- | src/cli.rs | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..4525781 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,172 @@ +use std::path::PathBuf; + +use clap::Parser; +use repo2markdown::{ + logger::Verbosity, + renderer::{DEFAULT_MAX_FILE_SIZE, RenderOptions}, +}; + +#[derive(Debug, Parser)] +#[command(version, about, long_about = None)] +pub struct Cli { + /// Root path to which file paths displayed in the generated markdown are relative. + #[arg(long, default_value = ".")] + pub root: PathBuf, + + /// Base path used to resolve relative input paths. + #[arg(long, default_value = ".")] + pub origin: PathBuf, + + /// Project title to use in the markdown header. + #[arg(long)] + pub name: Option<String>, + + /// Wrap the entire output in a markdown code fence. + #[arg(long)] + pub fenced: bool, + + /// Maximum file size, in bytes, to include in the generated markdown. + #[arg(long, default_value_t = DEFAULT_MAX_FILE_SIZE, value_name = "BYTES")] + max_file_size: u64, + + /// Include a placeholder entry when a binary file is skipped. + #[arg(long)] + placeholder_binary_files: bool, + + /// Include a placeholder entry when a large file is skipped. + #[arg(long)] + placeholder_large_files: bool, + + /// Suppress warnings and informational logs. + #[arg(long, conflicts_with = "verbose")] + quiet: bool, + + /// Include informational logs. + #[arg(long, conflicts_with = "quiet")] + verbose: bool, +} + +impl Cli { + pub fn render_options(&self) -> RenderOptions { + RenderOptions { + max_file_size: self.max_file_size, + placeholder_for_binary_files: self.placeholder_binary_files, + placeholder_for_large_files: self.placeholder_large_files, + } + } + + pub fn verbosity(&self) -> Verbosity { + if self.quiet { + Verbosity::Quiet + } else if self.verbose { + Verbosity::Verbose + } else { + Verbosity::Normal + } + } +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use clap::Parser; + use repo2markdown::logger::Verbosity; + + use super::{Cli, RenderOptions}; + + #[test] + fn cli_uses_default_paths_and_normal_verbosity() { + let cli = Cli::try_parse_from(["repo2markdown"]).unwrap(); + + assert_eq!(cli.root, PathBuf::from(".")); + assert_eq!(cli.origin, PathBuf::from(".")); + assert_eq!(cli.name, None); + assert_eq!(cli.verbosity(), Verbosity::Normal); + } + + #[test] + fn cli_accepts_root_origin_and_name() { + let cli = Cli::try_parse_from([ + "repo2markdown", + "--root", + "/repo", + "--origin", + "/repo/src", + "--name", + "My Project", + ]) + .unwrap(); + + assert_eq!(cli.root, PathBuf::from("/repo")); + assert_eq!(cli.origin, PathBuf::from("/repo/src")); + assert_eq!(cli.name.as_deref(), Some("My Project")); + } + + #[test] + fn cli_accepts_render_options() { + let cli = Cli::try_parse_from([ + "repo2markdown", + "--max-file-size", + "5", + "--placeholder-binary-files", + "--placeholder-large-files", + ]) + .unwrap(); + + let options = cli.render_options(); + + assert_eq!(options.max_file_size, 5); + assert!(options.placeholder_for_binary_files); + assert!(options.placeholder_for_large_files); + } + + #[test] + fn cli_defaults_unspecified_render_options() { + let cli = Cli::try_parse_from(["repo2markdown"]).unwrap(); + + assert_eq!(cli.render_options(), RenderOptions::default()); + } + + #[test] + fn cli_accepts_quiet_verbosity() { + let cli = Cli::try_parse_from(["repo2markdown", "--quiet"]).unwrap(); + + assert_eq!(cli.verbosity(), Verbosity::Quiet); + } + + #[test] + fn cli_accepts_verbose_verbosity() { + let cli = Cli::try_parse_from(["repo2markdown", "--verbose"]).unwrap(); + + assert_eq!(cli.verbosity(), Verbosity::Verbose); + } + + #[test] + fn cli_rejects_quiet_and_verbose_together() { + let result = Cli::try_parse_from(["repo2markdown", "--quiet", "--verbose"]); + + assert!(result.is_err()); + } + + #[test] + fn cli_rejects_invalid_max_file_size() { + let result = Cli::try_parse_from(["repo2markdown", "--max-file-size", "not-a-number"]); + + assert!(result.is_err()); + } + + #[test] + fn cli_does_not_use_fenced_output_by_default() { + let cli = Cli::try_parse_from(["repo2markdown"]).unwrap(); + + assert!(!cli.fenced); + } + + #[test] + fn cli_accepts_fenced_output_option() { + let cli = Cli::try_parse_from(["repo2markdown", "--fenced"]).unwrap(); + + assert!(cli.fenced); + } +} |
