From ccfb8d6f363a66f5036c96601c70489a8a9ad005 Mon Sep 17 00:00:00 2001 From: Malte Meiboom Date: Wed, 3 Jun 2026 14:38:35 +0200 Subject: [PATCH] Add shell completions - Add a `build.rs` (plus dependencies) to generate the shell completions clap knows. --- Cargo.lock | 11 +++++++++++ Cargo.toml | 6 ++++++ build.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 build.rs diff --git a/Cargo.lock b/Cargo.lock index 72c7e1a..05ab558 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -326,6 +326,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.6.1" @@ -1028,6 +1037,8 @@ dependencies = [ "anyhow", "bytes", "clap", + "clap_complete", + "fastrand", "indymilter", "log", "log4rs", diff --git a/Cargo.toml b/Cargo.toml index 294b94b..a9add1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ aho-corasick = "1.1.4" anyhow = "1.0.100" bytes = "1.11.1" clap = { version = "4", features = ["derive"] } +fastrand = "2.4.1" indymilter = "0.3.0" log = "0.4.30" log4rs = "1.3.0" @@ -28,3 +29,8 @@ serde_derive = "1.0.228" thiserror = "2.0.17" tokio = { version = "1.52.3", features = [ "tokio-macros", "rt-multi-thread", "signal" ] } toml = "0.9.8" + +[build-dependencies] +anyhow = "1.0.100" +clap = { version = "4", features = ["derive"] } +clap_complete = "4" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..c27cca5 --- /dev/null +++ b/build.rs @@ -0,0 +1,50 @@ +//! build + +use anyhow::Result; +use anyhow; +use clap::CommandFactory; +use clap::ValueEnum; +use clap_complete::Shell; + +use std::env; +use std::fs; +use std::path::PathBuf; + +// include the cli definition +pub mod cli { + include!("src/cli/cli_args.rs"); +} + +const ASSET_OUT_ENV_NAME: &str = "ASSET_OUT_DIR"; + +/// Returns a path to a directory suitable as a target for generated +/// files. +fn out_dir(section: &str) -> Result { + println!("cargo:rerun-if-env-changed={}", ASSET_OUT_ENV_NAME); + + let outdir: PathBuf = env::var_os(ASSET_OUT_ENV_NAME) + .unwrap_or_else(|| env::var_os("OUT_DIR") + .expect("OUT_DIR not set") + ).into(); + + if outdir.exists() && ! outdir.is_dir() { + return Err(anyhow::anyhow!("{:?} is not a directory", outdir)); + } + let path = outdir.join(section); + fs::create_dir_all(&path)?; + Ok(path) +} + +fn main() -> Result<()> { + let mut husk = cli::CliArgs::command(); + + // shell completions + let shell_completion_path = out_dir("shell_completions")?; + for shell in Shell::value_variants() { + clap_complete::generate_to(*shell, &mut husk, "husk", &shell_completion_path)?; + } + + println!("cargo:warning=shell completions written to {}", shell_completion_path.display()); + + Ok(()) +}