From 4866680cb537191cd811c08151ed4b7b704ffc09 Mon Sep 17 00:00:00 2001 From: zilayo <84344709+zilayo@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:55:25 +0100 Subject: [PATCH] avm, cli: Add completions command to generate shell completions (#3251) --- CHANGELOG.md | 1 + Cargo.lock | 64 +++++++++++++++++++++-------- avm/Cargo.toml | 3 +- avm/src/main.rs | 11 ++++- cli/Cargo.toml | 3 +- cli/src/lib.rs | 16 +++++++- docs/src/pages/docs/installation.md | 39 ++++++++++++++++++ 7 files changed, 116 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b49c0c583c..4be5cecad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Add `LazyAccount` ([#3194](https://github.com/coral-xyz/anchor/pull/3194)). - avm: Ask whether to install if the version is not installed with the `use` command ([#3230](https://github.com/coral-xyz/anchor/pull/3230)). - cli: Warn if a manifest has `solana-program` dependency ([#3250](https://github.com/coral-xyz/anchor/pull/3250)). +- cli: Add completions command to generate shell completions via the clap_complete crate ([#3251](https://github.com/coral-xyz/anchor/pull/3251)). ### Fixes diff --git a/Cargo.lock b/Cargo.lock index 3036d29b56..6867a1613a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -193,7 +193,8 @@ dependencies = [ "bincode", "cargo_toml", "chrono", - "clap 4.4.6", + "clap 4.5.17", + "clap_complete", "dirs", "flate2", "heck 0.4.1", @@ -366,23 +367,24 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -677,7 +679,8 @@ dependencies = [ "cargo_toml", "cfg-if", "chrono", - "clap 4.4.6", + "clap 4.5.17", + "clap_complete", "dirs", "once_cell", "reqwest", @@ -1109,9 +1112,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -1119,23 +1122,32 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.1", - "strsim 0.10.0", + "clap_lex 0.7.2", + "strsim 0.11.1", +] + +[[package]] +name = "clap_complete" +version = "4.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "205d5ef6d485fa47606b98b0ddc4ead26eb850aaa86abfb562a94fb3280ecba0" +dependencies = [ + "clap 4.5.17", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.55", @@ -1152,9 +1164,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" @@ -2015,6 +2027,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -2258,6 +2276,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.9.0" @@ -5129,6 +5153,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.4.1" diff --git a/avm/Cargo.toml b/avm/Cargo.toml index 0571015a55..7dae86c129 100644 --- a/avm/Cargo.toml +++ b/avm/Cargo.toml @@ -15,7 +15,8 @@ path = "src/anchor/main.rs" anyhow = "1.0.32" cfg-if = "1.0.0" cargo_toml = "0.19.2" -clap = { version = "4.2.4", features = ["derive"] } +clap = { version = "4.5.17", features = ["derive"] } +clap_complete = "4.5.26" dirs = "4.0.0" once_cell = "1.8.0" reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "json", "rustls-tls"] } diff --git a/avm/src/main.rs b/avm/src/main.rs index fa7a1a4c67..f4c21a2b2a 100644 --- a/avm/src/main.rs +++ b/avm/src/main.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Error, Result}; use avm::InstallTarget; -use clap::{Parser, Subcommand}; +use clap::{CommandFactory, Parser, Subcommand}; use semver::Version; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -38,6 +38,11 @@ pub enum Commands { List {}, #[clap(about = "Update to the latest Anchor version")] Update {}, + #[clap(about = "Generate shell completions for AVM")] + Completions { + #[clap(value_enum)] + shell: clap_complete::Shell, + }, } // If `latest` is passed use the latest available version. @@ -78,6 +83,10 @@ pub fn entry(opts: Cli) -> Result<()> { Commands::Uninstall { version } => avm::uninstall_version(&version), Commands::List {} => avm::list_versions(), Commands::Update {} => avm::update(), + Commands::Completions { shell } => { + clap_complete::generate(shell, &mut Cli::command(), "avm", &mut std::io::stdout()); + Ok(()) + } } } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 029ca8e60e..0c98d84e89 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -23,7 +23,8 @@ base64 = "0.21" bincode = "1.3.3" cargo_toml = "0.19.2" chrono = "0.4.19" -clap = { version = "4.2.4", features = ["derive"] } +clap = { version = "4.5.17", features = ["derive"] } +clap_complete = "4.5.26" dirs = "4.0" flate2 = "1.0.19" heck = "0.4.0" diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 8e18ffdd3f..11ad61f35e 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -10,7 +10,7 @@ use anchor_lang_idl::convert::convert_idl; use anchor_lang_idl::types::{Idl, IdlArrayLen, IdlDefinedFields, IdlType, IdlTypeDefTy}; use anyhow::{anyhow, Context, Result}; use checks::{check_anchor_version, check_deps, check_idl_build_feature, check_overflow}; -use clap::Parser; +use clap::{CommandFactory, Parser}; use dirs::home_dir; use flate2::read::GzDecoder; use flate2::read::ZlibDecoder; @@ -365,6 +365,11 @@ pub enum Command { #[clap(long)] idl: Option, }, + /// Generates shell completions. + Completions { + #[clap(value_enum)] + shell: clap_complete::Shell, + }, } #[derive(Debug, Parser)] @@ -924,6 +929,15 @@ fn process_command(opts: Opts) -> Result<()> { address, idl, } => account(&opts.cfg_override, account_type, address, idl), + Command::Completions { shell } => { + clap_complete::generate( + shell, + &mut Opts::command(), + "anchor", + &mut std::io::stdout(), + ); + Ok(()) + } } } diff --git a/docs/src/pages/docs/installation.md b/docs/src/pages/docs/installation.md index 4dcd4079e8..eaf48a14ed 100644 --- a/docs/src/pages/docs/installation.md +++ b/docs/src/pages/docs/installation.md @@ -77,3 +77,42 @@ Now verify the CLI is installed properly. ```shell anchor --version ``` + +## Generating Shell Completions + +Shell completions can be generated for `bash`, `elvish`, `fish`, `powershell`, and `zsh`. + +### Bash + +```bash +mkdir -p $HOME/.local/share/bash-completion/completions +anchor completions bash > $HOME/.local/share/bash-completion/completions/anchor +avm completions bash > $HOME/.local/share/bash-completion/completions/avm +exec bash +``` + +### Fish + +```bash +mkdir -p $HOME/.config/fish/completions +anchor completions fish > $HOME/.config/fish/completions/anchor.fish +avm completions fish > $HOME/.config/fish/completions/avm.fish +source $HOME/.config/fish/config.fish +``` + +### Zsh + +First ensure the following is in your `.zshrc` file. If using `oh-my-zsh` this step can be skipped. + +```bash +autoload -U compinit +compinit -i +``` + +Next run: + +```bash +anchor completions zsh | sudo tee /usr/local/share/zsh/site-functions/_anchor +avm completions zsh | sudo tee /usr/local/share/zsh/site-functions/_avm +exec zsh +```