Add Nushell completion script generation support (#1756)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Copilot
2026-01-11 18:41:02 +08:00
committed by GitHub
parent b590700540
commit bd8f01fb26
5 changed files with 142 additions and 12 deletions
Generated
+92 -4
View File
@@ -508,6 +508,29 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "aws-lc-rs"
version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba"
dependencies = [
"aws-lc-sys",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff"
dependencies = [
"bindgen 0.69.5",
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]] [[package]]
name = "axum" name = "axum"
version = "0.7.7" version = "0.7.7"
@@ -761,6 +784,29 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "bindgen"
version = "0.69.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
dependencies = [
"bitflags 2.8.0",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"lazy_static",
"lazycell",
"log",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash 1.1.0",
"shlex",
"syn 2.0.87",
"which 4.4.2",
]
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.71.1" version = "0.71.1"
@@ -774,7 +820,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"regex", "regex",
"rustc-hash", "rustc-hash 2.1.0",
"shlex", "shlex",
"syn 2.0.87", "syn 2.0.87",
] ]
@@ -1301,6 +1347,16 @@ dependencies = [
"clap", "clap",
] ]
[[package]]
name = "clap_complete_nushell"
version = "4.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685bc86fd34b7467e0532a4f8435ab107960d69a243785ef0275e571b35b641a"
dependencies = [
"clap",
"clap_complete",
]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "4.5.28" version = "4.5.28"
@@ -1328,6 +1384,15 @@ dependencies = [
"error-code", "error-code",
] ]
[[package]]
name = "cmake"
version = "0.1.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "codepage" name = "codepage"
version = "0.1.2" version = "0.1.2"
@@ -2100,6 +2165,7 @@ dependencies = [
"cidr", "cidr",
"clap", "clap",
"clap_complete", "clap_complete",
"clap_complete_nushell",
"console-subscriber", "console-subscriber",
"crossbeam", "crossbeam",
"dashmap", "dashmap",
@@ -2245,6 +2311,7 @@ dependencies = [
"gethostname 1.0.2", "gethostname 1.0.2",
"libc", "libc",
"once_cell", "once_cell",
"rustls",
"security-framework-sys", "security-framework-sys",
"serde", "serde",
"serde_json", "serde_json",
@@ -2771,6 +2838,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]] [[package]]
name = "funty" name = "funty"
version = "2.0.0" version = "2.0.0"
@@ -4253,7 +4326,7 @@ source = "git+https://github.com/EasyTier/kcp-sys?rev=71eff18c573a4a71bf99c7fabc
dependencies = [ dependencies = [
"anyhow", "anyhow",
"auto_impl", "auto_impl",
"bindgen", "bindgen 0.71.1",
"bitflags 2.8.0", "bitflags 2.8.0",
"bytes", "bytes",
"cc", "cc",
@@ -4300,6 +4373,12 @@ dependencies = [
"spin", "spin",
] ]
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libappindicator" name = "libappindicator"
version = "0.9.0" version = "0.9.0"
@@ -6425,7 +6504,7 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"quinn-proto", "quinn-proto",
"quinn-udp", "quinn-udp",
"rustc-hash", "rustc-hash 2.1.0",
"rustls", "rustls",
"socket2 0.5.10", "socket2 0.5.10",
"thiserror 2.0.11", "thiserror 2.0.11",
@@ -6446,7 +6525,7 @@ dependencies = [
"lru-slab", "lru-slab",
"rand 0.9.1", "rand 0.9.1",
"ring", "ring",
"rustc-hash", "rustc-hash 2.1.0",
"rustls", "rustls",
"rustls-pki-types", "rustls-pki-types",
"rustls-platform-verifier", "rustls-platform-verifier",
@@ -7037,6 +7116,12 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
version = "2.1.0" version = "2.1.0"
@@ -7084,6 +7169,8 @@ version = "0.23.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
dependencies = [ dependencies = [
"aws-lc-rs",
"log",
"once_cell", "once_cell",
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
@@ -7155,6 +7242,7 @@ version = "0.103.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
dependencies = [ dependencies = [
"aws-lc-rs",
"ring", "ring",
"rustls-pki-types", "rustls-pki-types",
"untrusted", "untrusted",
+1
View File
@@ -135,6 +135,7 @@ clap = { version = "4.5.30", features = [
"env", "env",
] } ] }
clap_complete = { version = "4.5.55" } clap_complete = { version = "4.5.55" }
clap_complete_nushell = { version = "4.5.10" }
async-recursion = "1.0.5" async-recursion = "1.0.5"
+8 -4
View File
@@ -23,12 +23,11 @@ use crate::{
rpc_service::ApiRpcServer, rpc_service::ApiRpcServer,
tunnel::PROTO_PORT_OFFSET, tunnel::PROTO_PORT_OFFSET,
utils::{init_logger, setup_panic_handler}, utils::{init_logger, setup_panic_handler},
web_client, web_client, ShellType,
}; };
use anyhow::Context; use anyhow::Context;
use cidr::IpCidr; use cidr::IpCidr;
use clap::{CommandFactory, Parser}; use clap::{CommandFactory, Parser};
use clap_complete::Shell;
use rust_i18n::t; use rust_i18n::t;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
@@ -126,7 +125,7 @@ struct Cli {
rpc_portal_options: RpcPortalOptions, rpc_portal_options: RpcPortalOptions,
#[clap(long, help = t!("core_clap.generate_completions").to_string())] #[clap(long, help = t!("core_clap.generate_completions").to_string())]
gen_autocomplete: Option<Shell>, gen_autocomplete: Option<ShellType>,
#[clap(long, help = t!("core_clap.check_config").to_string())] #[clap(long, help = t!("core_clap.check_config").to_string())]
check_config: bool, check_config: bool,
@@ -1380,7 +1379,12 @@ pub async fn main() -> ExitCode {
if let Some(shell) = cli.gen_autocomplete { if let Some(shell) = cli.gen_autocomplete {
let mut cmd = Cli::command(); let mut cmd = Cli::command();
crate::print_completions(shell, &mut cmd, "easytier-core"); if let Some(shell) = shell.to_shell() {
crate::print_completions(shell, &mut cmd, "easytier-core");
} else {
// Handle Nushell
crate::print_nushell_completions(&mut cmd, "easytier-core");
}
return ExitCode::SUCCESS; return ExitCode::SUCCESS;
} }
+8 -3
View File
@@ -10,8 +10,8 @@ use std::{
use anyhow::Context; use anyhow::Context;
use cidr::Ipv4Inet; use cidr::Ipv4Inet;
use clap::{Args, CommandFactory, Parser, Subcommand}; use clap::{Args, CommandFactory, Parser, Subcommand};
use clap_complete::Shell;
use dashmap::DashMap; use dashmap::DashMap;
use easytier::ShellType;
use humansize::format_size; use humansize::format_size;
use rust_i18n::t; use rust_i18n::t;
use service_manager::*; use service_manager::*;
@@ -126,7 +126,7 @@ enum SubCommand {
#[command(about = "manage logger configuration")] #[command(about = "manage logger configuration")]
Logger(LoggerArgs), Logger(LoggerArgs),
#[command(about = t!("core_clap.generate_completions").to_string())] #[command(about = t!("core_clap.generate_completions").to_string())]
GenAutocomplete { shell: Shell }, GenAutocomplete { shell: ShellType },
} }
#[derive(clap::ValueEnum, Debug, Clone, PartialEq)] #[derive(clap::ValueEnum, Debug, Clone, PartialEq)]
@@ -1950,7 +1950,12 @@ async fn main() -> Result<(), Error> {
}, },
SubCommand::GenAutocomplete { shell } => { SubCommand::GenAutocomplete { shell } => {
let mut cmd = Cli::command(); let mut cmd = Cli::command();
easytier::print_completions(shell, &mut cmd, "easytier-cli"); if let Some(shell) = shell.to_shell() {
easytier::print_completions(shell, &mut cmd, "easytier-cli");
} else {
// Handle Nushell
easytier::print_nushell_completions(&mut cmd, "easytier-cli");
}
} }
} }
+33 -1
View File
@@ -3,7 +3,7 @@
use std::io; use std::io;
use clap::Command; use clap::Command;
use clap_complete::Generator; use clap_complete::{Generator, Shell};
mod arch; mod arch;
mod gateway; mod gateway;
@@ -30,6 +30,38 @@ mod tests;
pub const VERSION: &str = common::constants::EASYTIER_VERSION; pub const VERSION: &str = common::constants::EASYTIER_VERSION;
rust_i18n::i18n!("locales", fallback = "en"); rust_i18n::i18n!("locales", fallback = "en");
#[derive(clap::ValueEnum, Debug, Clone, PartialEq)]
pub enum ShellType {
Bash,
Elvish,
Fish,
Powershell,
Zsh,
Nu,
}
impl ShellType {
pub fn to_shell(&self) -> Option<Shell> {
match self {
ShellType::Bash => Some(Shell::Bash),
ShellType::Elvish => Some(Shell::Elvish),
ShellType::Fish => Some(Shell::Fish),
ShellType::Powershell => Some(Shell::PowerShell),
ShellType::Zsh => Some(Shell::Zsh),
ShellType::Nu => None,
}
}
}
pub fn print_completions<G: Generator>(generator: G, cmd: &mut Command, bin_name: &str) { pub fn print_completions<G: Generator>(generator: G, cmd: &mut Command, bin_name: &str) {
clap_complete::generate(generator, cmd, bin_name, &mut io::stdout()); clap_complete::generate(generator, cmd, bin_name, &mut io::stdout());
} }
pub fn print_nushell_completions(cmd: &mut Command, bin_name: &str) {
clap_complete::generate(
clap_complete_nushell::Nushell,
cmd,
bin_name,
&mut io::stdout(),
);
}