diff options
-rw-r--r-- | src/args.rs | 10 | ||||
-rw-r--r-- | src/main.rs | 16 | ||||
-rw-r--r-- | tests/cli.rs | 28 |
3 files changed, 45 insertions, 9 deletions
diff --git a/src/args.rs b/src/args.rs index 909a88f..d6cfc69 100644 --- a/src/args.rs +++ b/src/args.rs @@ -21,7 +21,7 @@ const ROUTE_ALPHABET: [char; 16] = [ about, global_settings = &[structopt::clap::AppSettings::ColoredHelp], )] -struct CliArgs { +pub struct CliArgs { /// Be verbose, includes emitting access logs #[structopt(short = "v", long = "verbose")] verbose: bool, @@ -131,6 +131,10 @@ struct CliArgs { /// Hide version footer #[structopt(short = "F", long = "hide-version-footer")] hide_version_footer: bool, + + /// Generate completion file for a shell + #[structopt(long = "print-completions", value_name = "shell")] + pub print_completions: Option<structopt::clap::Shell>, } /// Checks wether an interface is valid, i.e. it can be parsed into an IP address @@ -205,9 +209,7 @@ pub fn parse_header(src: &str) -> Result<HeaderMap, httparse::Error> { } /// Parses the command line arguments -pub fn parse_args() -> crate::MiniserveConfig { - let args = CliArgs::from_args(); - +pub fn parse_args(args: CliArgs) -> crate::MiniserveConfig { let interfaces = if !args.interfaces.is_empty() { args.interfaces } else { diff --git a/src/main.rs b/src/main.rs index 17ab204..747a705 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::thread; use std::time::Duration; use structopt::clap::crate_version; +use structopt::StructOpt; use yansi::{Color, Paint}; mod archive; @@ -101,20 +102,27 @@ pub struct MiniserveConfig { } fn main() { - match run() { + let args = args::CliArgs::from_args(); + + if let Some(shell) = args.print_completions { + args::CliArgs::clap().gen_completions_to("miniserve", shell, &mut std::io::stdout()); + return; + } + + let miniserve_config = args::parse_args(args); + + match run(miniserve_config) { Ok(()) => (), Err(e) => errors::log_error_chain(e.to_string()), } } #[actix_web::main(miniserve)] -async fn run() -> Result<(), ContextualError> { +async fn run(miniserve_config: MiniserveConfig) -> Result<(), ContextualError> { if cfg!(windows) && !Paint::enable_windows_ascii() { Paint::disable(); } - let miniserve_config = args::parse_args(); - let log_level = if miniserve_config.verbose { simplelog::LevelFilter::Info } else { diff --git a/tests/cli.rs b/tests/cli.rs index e09473d..f88b284 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -3,7 +3,7 @@ mod fixtures; use assert_cmd::prelude::*; use fixtures::Error; use std::process::Command; -use structopt::clap::{crate_name, crate_version}; +use structopt::clap::{crate_name, crate_version, Shell}; #[test] /// Show help and exit. @@ -27,3 +27,29 @@ fn version_shows() -> Result<(), Error> { Ok(()) } + +#[test] +/// Print completions and exit. +fn print_completions() -> Result<(), Error> { + for shell in &Shell::variants() { + Command::cargo_bin("miniserve")? + .arg("--print-completions") + .arg(&shell) + .assert() + .success(); + } + + Ok(()) +} + +#[test] +/// Print completions rejects invalid shells. +fn print_completions_invalid_shell() -> Result<(), Error> { + Command::cargo_bin("miniserve")? + .arg("--print-completions") + .arg("fakeshell") + .assert() + .failure(); + + Ok(()) +} |