diff --git a/CHANGELOG.md b/CHANGELOG.md index 810a8585b..41ed0f191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - A default value (`datastore.np`) is now set for commands that take a datastore option ([#74](https://github.com/praetorian-inc/noseyparker/issues/74)). This makes simpler `noseyparker` command-line invocations possible. +- A new `shell-completions` command has been added, which generates shell-specific completion scripts for zsh, bash, fish, powershell, and elvish ([#76](https://github.com/praetorian-inc/noseyparker/pull/76)). + These generated completion scripts make discovery of Nosey Parker's command-line API simpler. + Thank you @Coruscant11! + ## [v0.14.0](https://github.com/praetorian-inc/noseyparker/releases/v0.14.0) (2023-08-17) diff --git a/Cargo.lock b/Cargo.lock index d46d87af3..9d867f2dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "clap_complete" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.3.12" @@ -2396,6 +2405,7 @@ dependencies = [ "assert_fs", "bstr", "clap", + "clap_complete", "console", "crossbeam-channel", "ignore", diff --git a/crates/noseyparker-cli/Cargo.toml b/crates/noseyparker-cli/Cargo.toml index f01ba1a24..8d48925cc 100644 --- a/crates/noseyparker-cli/Cargo.toml +++ b/crates/noseyparker-cli/Cargo.toml @@ -36,6 +36,7 @@ vergen = { version = "8.1", features = ["build", "cargo", "git", "gitcl", "rustc anyhow = { version = "1.0" } bstr = { version = "1.0" } clap = { version = "4.3", features = ["cargo", "derive", "env", "unicode", "wrap_help"] } +clap_complete = "4.4" console = "0.15" crossbeam-channel = "0.5" indenter = "0.3" diff --git a/crates/noseyparker-cli/src/bin/noseyparker/args.rs b/crates/noseyparker-cli/src/bin/noseyparker/args.rs index e6a1d5340..c12a2b82b 100644 --- a/crates/noseyparker-cli/src/bin/noseyparker/args.rs +++ b/crates/noseyparker-cli/src/bin/noseyparker/args.rs @@ -168,6 +168,10 @@ pub enum Command { #[command(display_order = 30)] /// Manage rules Rules(RulesArgs), + + #[command(display_order = 30)] + /// Generate shell completions + ShellCompletions(ShellCompletionsArgs), } // ----------------------------------------------------------------------------- @@ -612,6 +616,39 @@ pub struct ReportArgs { pub output_args: OutputArgs, } + +// ----------------------------------------------------------------------------- +// `shell_completions` command +// ----------------------------------------------------------------------------- +#[derive(ValueEnum, Debug, Clone)] +#[clap(rename_all = "lower")] +pub enum ShellFormat { + Bash, + Zsh, + Fish, + PowerShell, + Elvish +} + +impl std::fmt::Display for ShellFormat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + ShellFormat::Bash => "bash", + ShellFormat::Zsh => "zsh", + ShellFormat::Fish => "fish", + ShellFormat::PowerShell => "powershell", + ShellFormat::Elvish => "elvish", + }; + write!(f, "{s}") + } +} + +#[derive(Args, Debug)] +pub struct ShellCompletionsArgs { + #[arg(long, short, value_name = "SHELL")] + pub shell: ShellFormat, +} + // ----------------------------------------------------------------------------- // output options // ----------------------------------------------------------------------------- diff --git a/crates/noseyparker-cli/src/bin/noseyparker/cmd_shell_completions.rs b/crates/noseyparker-cli/src/bin/noseyparker/cmd_shell_completions.rs new file mode 100644 index 000000000..4146169c8 --- /dev/null +++ b/crates/noseyparker-cli/src/bin/noseyparker/cmd_shell_completions.rs @@ -0,0 +1,24 @@ +use crate::args::{GlobalArgs, ShellFormat, ShellCompletionsArgs, CommandLineArgs}; +use anyhow::Result; +use clap::{CommandFactory, Command}; +use clap_complete::{generate, shells::Bash, shells::Zsh, shells::Fish, shells::PowerShell, shells::Elvish}; + +pub fn run(_global_args: &GlobalArgs, args: &ShellCompletionsArgs) -> Result<()> { + let mut cmd = CommandLineArgs::command(); + generate_completions_for_shell(&args.shell, &mut cmd) +} + +fn generate_completions_for_shell(shell: &ShellFormat, cmd: &mut Command) -> Result<()> { + let bin_name = "noseyparker"; + let std_out = &mut std::io::stdout(); + + match shell { + ShellFormat::Bash => generate(Bash, cmd, bin_name, std_out), + ShellFormat::Zsh => generate(Zsh, cmd, bin_name, std_out), + ShellFormat::Fish => generate(Fish, cmd, bin_name, std_out), + ShellFormat::PowerShell => generate(PowerShell, cmd, bin_name, std_out), + ShellFormat::Elvish => generate(Elvish, cmd, bin_name, std_out), + } + + Ok(()) +} diff --git a/crates/noseyparker-cli/src/bin/noseyparker/main.rs b/crates/noseyparker-cli/src/bin/noseyparker/main.rs index 166499978..b4b1675c2 100644 --- a/crates/noseyparker-cli/src/bin/noseyparker/main.rs +++ b/crates/noseyparker-cli/src/bin/noseyparker/main.rs @@ -7,6 +7,7 @@ mod cmd_github; mod cmd_report; mod cmd_rules; mod cmd_scan; +mod cmd_shell_completions; mod cmd_summarize; use args::GlobalArgs; @@ -80,6 +81,7 @@ fn try_main() -> Result<()> { args::Command::Scan(args) => cmd_scan::run(global_args, args), args::Command::Summarize(args) => cmd_summarize::run(global_args, args), args::Command::Report(args) => cmd_report::run(global_args, args), + args::Command::ShellCompletions(args) => cmd_shell_completions::run(global_args, args), } } diff --git a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help-2.snap b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help-2.snap index a81f65df5..0fc9f0502 100644 --- a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help-2.snap +++ b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help-2.snap @@ -8,13 +8,14 @@ and Git history. Usage: noseyparker [OPTIONS] Commands: - scan Scan content for secrets - summarize Summarize scan findings - report Report detailed scan findings - github Interact with GitHub - datastore Manage datastores - rules Manage rules - help Print this message or the help of the given subcommand(s) + scan Scan content for secrets + summarize Summarize scan findings + report Report detailed scan findings + github Interact with GitHub + datastore Manage datastores + rules Manage rules + shell-completions Generate shell completions + help Print this message or the help of the given subcommand(s) Options: -h, --help diff --git a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help_short-2.snap b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help_short-2.snap index 220bec2ab..d317652a7 100644 --- a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help_short-2.snap +++ b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__help_short-2.snap @@ -8,13 +8,14 @@ and Git history. Usage: noseyparker [OPTIONS] Commands: - scan Scan content for secrets - summarize Summarize scan findings - report Report detailed scan findings - github Interact with GitHub - datastore Manage datastores - rules Manage rules - help Print this message or the help of the given subcommand(s) + scan Scan content for secrets + summarize Summarize scan findings + report Report detailed scan findings + github Interact with GitHub + datastore Manage datastores + rules Manage rules + shell-completions Generate shell completions + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help (see more with '--help') diff --git a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__no_args-3.snap b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__no_args-3.snap index f11b6a29d..8b05a6110 100644 --- a/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__no_args-3.snap +++ b/crates/noseyparker-cli/tests/help/snapshots/test_noseyparker__help__no_args-3.snap @@ -8,13 +8,14 @@ and Git history. Usage: noseyparker [OPTIONS] Commands: - scan Scan content for secrets - summarize Summarize scan findings - report Report detailed scan findings - github Interact with GitHub - datastore Manage datastores - rules Manage rules - help Print this message or the help of the given subcommand(s) + scan Scan content for secrets + summarize Summarize scan findings + report Report detailed scan findings + github Interact with GitHub + datastore Manage datastores + rules Manage rules + shell-completions Generate shell completions + help Print this message or the help of the given subcommand(s) Options: -h, --help Print help (see more with '--help')