Generate Bash and Fish completions
This commit is contained in:
parent
aa1d311745
commit
728c66fb70
@ -11,3 +11,9 @@ clap_complete = "4.0.6"
|
|||||||
clap_complete_nushell = "0.1.8"
|
clap_complete_nushell = "0.1.8"
|
||||||
clap_mangen = "0.2.5"
|
clap_mangen = "0.2.5"
|
||||||
hostname = { version = "0.3", features = ["set"] }
|
hostname = { version = "0.3", features = ["set"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
strip = true
|
||||||
|
lto = true
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
use crate::cmd;
|
use crate::cmd;
|
||||||
use clap::{value_parser, Arg, ArgMatches, Command};
|
use clap::{value_parser, Arg, ArgMatches, Command, ArgAction};
|
||||||
|
use clap_complete::{generate_to, shells};
|
||||||
use clap_mangen::Man;
|
use clap_mangen::Man;
|
||||||
use std::{fs, io, path::PathBuf, process};
|
use std::{fs, io, path::{Path, PathBuf}, process};
|
||||||
|
|
||||||
const programs: [&str; 8] = [
|
const COMMANDS: [fn() -> clap::Command; 8] = [
|
||||||
"shitbox",
|
cmd::bootstrap::cli,
|
||||||
"bootstrap",
|
cmd::echo::cli,
|
||||||
"echo",
|
cmd::r#false::cli,
|
||||||
"false",
|
cmd::head::cli,
|
||||||
"head",
|
cmd::hostname::cli,
|
||||||
"hostname",
|
cmd::r#true::cli,
|
||||||
"true",
|
cmd::sleep::cli,
|
||||||
"sleep",
|
crate::cli::cli,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -60,38 +61,37 @@ pub fn cli() -> Command {
|
|||||||
Arg::new("all")
|
Arg::new("all")
|
||||||
.help("Install completions for all supported shells")
|
.help("Install completions for all supported shells")
|
||||||
.short('a')
|
.short('a')
|
||||||
.long("all"),
|
.long("all")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("bash")
|
Arg::new("bash")
|
||||||
.help("Bash shell completions")
|
.help("Bash shell completions")
|
||||||
.short('b')
|
.short('b')
|
||||||
.long("bash"),
|
.long("bash")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("fish")
|
Arg::new("fish")
|
||||||
.help("Fish shell completions")
|
.help("Fish shell completions")
|
||||||
.short('f')
|
.short('f')
|
||||||
.long("fish"),
|
.long("fish")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("nu")
|
Arg::new("nu")
|
||||||
.help("Nushell completions")
|
.help("Nushell completions")
|
||||||
.short('n')
|
.short('n')
|
||||||
.long("nu"),
|
.long("nu")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
Arg::new("pwsh")
|
Arg::new("pwsh")
|
||||||
.help("PowerShell completions")
|
.help("PowerShell completions")
|
||||||
.short('p')
|
.short('p')
|
||||||
.long("pwsh"),
|
.long("pwsh")
|
||||||
|
.action(ArgAction::SetTrue),
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manpage(prefix: &str, cmd: &str) -> Result<(), io::Error> {
|
fn manpage(prefix: &str, f: &dyn Fn() -> Command) -> Result<(), io::Error> {
|
||||||
let (fname, cmd) = match cmd {
|
let cmd = f();
|
||||||
"shitbox" => ("shitbox.1", crate::cli::cli()),
|
let fname = match cmd.get_name() {
|
||||||
"bootstrap" => ("shitbox-bootstrap.1", cli()),
|
"bootstrap" => "shitbox-bootstrap.1".to_string(),
|
||||||
"echo" => ("echo.1", cmd::echo::cli()),
|
s => format!("{s}.1"),
|
||||||
"false" => ("false.1", cmd::r#false::cli()),
|
|
||||||
"head" => ("head.1", cmd::head::cli()),
|
|
||||||
"hostname" => ("hostname.1", cmd::hostname::cli()),
|
|
||||||
"true" => ("true.1", cmd::r#true::cli()),
|
|
||||||
"sleep" => ("sleep.1", cmd::sleep::cli()),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
};
|
};
|
||||||
let outdir: PathBuf = [prefix, "usr", "share", "man", "man1"].iter().collect();
|
let outdir: PathBuf = [prefix, "usr", "share", "man", "man1"].iter().collect();
|
||||||
if !outdir.exists() {
|
if !outdir.exists() {
|
||||||
@ -109,7 +109,56 @@ fn manpage(prefix: &str, cmd: &str) -> Result<(), io::Error> {
|
|||||||
|
|
||||||
fn manpages(prefix: &str) -> Result<(), io::Error> {
|
fn manpages(prefix: &str) -> Result<(), io::Error> {
|
||||||
println!("Generating Unix man pages:");
|
println!("Generating Unix man pages:");
|
||||||
programs.iter().try_for_each(|cmd| manpage(prefix, cmd))?;
|
COMMANDS.iter().try_for_each(|cmd| {
|
||||||
|
manpage(prefix, &cmd)
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_bash_completion(outdir: &Path, f: &dyn Fn() -> Command) -> Result<(), io::Error> {
|
||||||
|
let cmd = f();
|
||||||
|
let name = cmd.get_name();
|
||||||
|
let mut cmd = cmd.clone();
|
||||||
|
let path = generate_to(shells::Bash, &mut cmd, name, outdir)?;
|
||||||
|
println!(" {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_fish_completion(outdir: &Path, f: &dyn Fn() -> Command) -> Result<(), io::Error> {
|
||||||
|
let cmd = f();
|
||||||
|
let name = cmd.get_name();
|
||||||
|
let mut cmd = cmd.clone();
|
||||||
|
let path = generate_to(shells::Fish, &mut cmd, name, outdir)?;
|
||||||
|
println!(" {}", path.display());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn completions(prefix: &str, matches: &ArgMatches) -> Result<(), io::Error> {
|
||||||
|
println!("Generating completions:");
|
||||||
|
if matches.get_flag("bash") || matches.get_flag("all") {
|
||||||
|
let outdir: PathBuf = [prefix, "share", "bash-completion", "completion"]
|
||||||
|
.iter()
|
||||||
|
.collect();
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(&outdir)?;
|
||||||
|
}
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| gen_bash_completion(&outdir, &cmd) )?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("fish") || matches.get_flag("all") {
|
||||||
|
let outdir: PathBuf = ["target", "dist", "share", "fish", "completions"]
|
||||||
|
.iter()
|
||||||
|
.collect();
|
||||||
|
if !outdir.exists() {
|
||||||
|
fs::create_dir_all(&outdir)?;
|
||||||
|
}
|
||||||
|
COMMANDS.iter().try_for_each(|cmd| gen_fish_completion(&outdir, &cmd) )?;
|
||||||
|
}
|
||||||
|
if matches.get_flag("nu") || matches.get_flag("all") {
|
||||||
|
}
|
||||||
|
if matches.get_flag("pwsh") || matches.get_flag("all") {
|
||||||
|
}
|
||||||
|
if matches.get_flag("zsh") || matches.get_flag("all") {
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +166,19 @@ pub fn run(matches: &ArgMatches) {
|
|||||||
if let Some(prefix) = matches.get_one::<String>("prefix") {
|
if let Some(prefix) = matches.get_one::<String>("prefix") {
|
||||||
match matches.subcommand() {
|
match matches.subcommand() {
|
||||||
Some(("manpages", _matches)) => {
|
Some(("manpages", _matches)) => {
|
||||||
if let Err(e) = manpages(&prefix) {
|
if let Err(e) = manpages(prefix) {
|
||||||
|
eprintln!("{e}");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(("completions", matches)) => {
|
||||||
|
if let Err(e) = completions(prefix, matches) {
|
||||||
|
eprintln!("{e}");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(("all", _matches)) => {
|
||||||
|
if let Err(e) = manpages(prefix) {
|
||||||
eprintln!("{e}");
|
eprintln!("{e}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ pub fn cli() -> Command {
|
|||||||
.short('n')
|
.short('n')
|
||||||
.long("lines")
|
.long("lines")
|
||||||
.default_value("10")
|
.default_value("10")
|
||||||
|
.allow_negative_numbers(false)
|
||||||
.value_parser(value_parser!(usize))
|
.value_parser(value_parser!(usize))
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ pub fn cli() -> Command {
|
|||||||
Arg::new("seconds")
|
Arg::new("seconds")
|
||||||
.help("The number of seconds to sleep")
|
.help("The number of seconds to sleep")
|
||||||
.num_args(1)
|
.num_args(1)
|
||||||
|
.allow_negative_numbers(false)
|
||||||
.value_parser(value_parser!(f64))
|
.value_parser(value_parser!(f64))
|
||||||
.required(true)
|
.required(true)
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
|
Loading…
Reference in New Issue
Block a user