Merge pull request #1425 from alexmaco/completions

Add ability to generate shell completions via clap
This commit is contained in:
Eric Huss 2021-07-06 08:59:06 -07:00 committed by GitHub
commit 96b6f02834
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 50 additions and 21 deletions

View File

@ -3,8 +3,9 @@ extern crate clap;
#[macro_use]
extern crate log;
use anyhow::anyhow;
use chrono::Local;
use clap::{App, AppSettings, ArgMatches};
use clap::{App, AppSettings, Arg, ArgMatches, Shell, SubCommand};
use env_logger::Builder;
use log::LevelFilter;
use mdbook::utils;
@ -20,7 +21,40 @@ const VERSION: &str = concat!("v", crate_version!());
fn main() {
init_logger();
// Create a list of valid arguments and sub-commands
let app = create_clap_app();
// Check which subcomamnd the user ran...
let res = match app.get_matches().subcommand() {
("init", Some(sub_matches)) => cmd::init::execute(sub_matches),
("build", Some(sub_matches)) => cmd::build::execute(sub_matches),
("clean", Some(sub_matches)) => cmd::clean::execute(sub_matches),
#[cfg(feature = "watch")]
("watch", Some(sub_matches)) => cmd::watch::execute(sub_matches),
#[cfg(feature = "serve")]
("serve", Some(sub_matches)) => cmd::serve::execute(sub_matches),
("test", Some(sub_matches)) => cmd::test::execute(sub_matches),
("completions", Some(sub_matches)) => (|| {
let shell: Shell = sub_matches
.value_of("shell")
.ok_or_else(|| anyhow!("Shell name missing."))?
.parse()
.map_err(|s| anyhow!("Invalid shell: {}", s))?;
create_clap_app().gen_completions_to("mdbook", shell, &mut std::io::stdout().lock());
Ok(())
})(),
(_, _) => unreachable!(),
};
if let Err(e) = res {
utils::log_backtrace(&e);
std::process::exit(101);
}
}
/// Create a list of valid arguments and sub-commands
fn create_clap_app<'a, 'b>() -> App<'a, 'b> {
let app = App::new(crate_name!())
.about(crate_description!())
.author("Mathieu David <mathieudavid@mathieudavid.org>")
@ -35,31 +69,26 @@ fn main() {
.subcommand(cmd::init::make_subcommand())
.subcommand(cmd::build::make_subcommand())
.subcommand(cmd::test::make_subcommand())
.subcommand(cmd::clean::make_subcommand());
.subcommand(cmd::clean::make_subcommand())
.subcommand(
SubCommand::with_name("completions")
.about("Generate shell completions for your shell to stdout")
.arg(
Arg::with_name("shell")
.takes_value(true)
.possible_values(&Shell::variants())
.help("the shell to generate completions for")
.value_name("SHELL")
.required(true),
),
);
#[cfg(feature = "watch")]
let app = app.subcommand(cmd::watch::make_subcommand());
#[cfg(feature = "serve")]
let app = app.subcommand(cmd::serve::make_subcommand());
// Check which subcomamnd the user ran...
let res = match app.get_matches().subcommand() {
("init", Some(sub_matches)) => cmd::init::execute(sub_matches),
("build", Some(sub_matches)) => cmd::build::execute(sub_matches),
("clean", Some(sub_matches)) => cmd::clean::execute(sub_matches),
#[cfg(feature = "watch")]
("watch", Some(sub_matches)) => cmd::watch::execute(sub_matches),
#[cfg(feature = "serve")]
("serve", Some(sub_matches)) => cmd::serve::execute(sub_matches),
("test", Some(sub_matches)) => cmd::test::execute(sub_matches),
(_, _) => unreachable!(),
};
if let Err(e) = res {
utils::log_backtrace(&e);
std::process::exit(101);
}
app
}
fn init_logger() {