From 0174e390f321403b1d7e1cb66b1b9e28eaf4b330 Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sat, 2 Aug 2025 22:46:24 +0300 Subject: [PATCH] try to get completions going Signed-off-by: NotAShelf Change-Id: I6a6a6964dcd3beb752ae2d3a90ab6e545815c692 --- Cargo.lock | 11 +++++++++ Cargo.toml | 1 + xtask/Cargo.toml | 2 ++ xtask/src/main.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6e76d62..562e139 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,15 @@ dependencies = [ "clap_lex", ] +[[package]] +name = "clap_complete" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.5.41" @@ -302,6 +311,8 @@ name = "xtask" version = "0.1.1" dependencies = [ "clap", + "clap_complete", + "eh", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e16edae..38fd81f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ version = "0.1.1" [workspace.dependencies] clap = { default-features = false, features = [ "std", "help", "derive" ], version = "4.5" } +clap_complete = "4.5" regex = "1.11" tracing = "0.1" tracing-subscriber = "0.3" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index a8d8f20..54657fb 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -10,3 +10,5 @@ publish = false [dependencies] clap.workspace = true +clap_complete.workspace = true +eh = { path = "../eh" } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 6a2d7b7..4d92b6a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -4,7 +4,8 @@ use std::{ process, }; -use clap::Parser; +use clap::{CommandFactory, Parser}; +use clap_complete::{Shell, generate}; #[derive(clap::Parser)] struct Cli { @@ -24,6 +25,15 @@ enum Command { #[arg(long, default_value = "target/release/eh")] main_binary: PathBuf, }, + /// Generate shell completion scripts + Completions { + /// Shell to generate completions for + #[arg(value_enum)] + shell: Shell, + /// Directory to output completion files + #[arg(long, default_value = "completions")] + output_dir: PathBuf, + }, } #[derive(Debug, Clone, Copy)] @@ -56,6 +66,12 @@ fn main() { process::exit(1); } } + Command::Completions { shell, output_dir } => { + if let Err(error) = generate_completions(shell, &output_dir) { + eprintln!("error generating completions: {error}"); + process::exit(1); + } + } } } @@ -117,3 +133,43 @@ fn create_multicall_binaries( Ok(()) } + +fn generate_completions(shell: Shell, output_dir: &Path) -> Result<(), Box> { + println!("generating {} completions...", shell); + + fs::create_dir_all(output_dir)?; + + let mut cmd = eh::Cli::command(); + let bin_name = "eh"; + + let completion_file = output_dir.join(format!("{}.{}", bin_name, shell)); + let mut file = fs::File::create(&completion_file)?; + + generate(shell, &mut cmd, bin_name, &mut file); + + println!("completion file generated: {}", completion_file.display()); + + // Create symlinks for multicall binaries + let multicall_names = ["nb", "nr", "ns"]; + for name in &multicall_names { + let symlink_path = output_dir.join(format!("{}.{}", name, shell)); + if symlink_path.exists() { + fs::remove_file(&symlink_path)?; + } + + #[cfg(unix)] + { + std::os::unix::fs::symlink(&completion_file, &symlink_path)?; + println!("completion symlink created: {}", symlink_path.display()); + } + + #[cfg(not(unix))] + { + fs::copy(&completion_file, &symlink_path)?; + println!("completion copy created: {}", symlink_path.display()); + } + } + + println!("completions generated successfully!"); + Ok(()) +}