diff --git a/Cargo.lock b/Cargo.lock index 5521ef4..f465eb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -222,21 +222,30 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", +] + +[[package]] +name = "clap_complete" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b4be9c4c4b1f30b78d8a750e0822b6a6102d97e62061c583a6c1dea2dfb33ae" +dependencies = [ + "clap", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck", "proc-macro2", @@ -246,9 +255,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "colorchoice" @@ -346,7 +355,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn", ] @@ -563,9 +572,9 @@ checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -944,6 +953,7 @@ dependencies = [ "anyhow", "assert_cmd", "clap", + "clap_complete", "colored", "ctor", "nix_health", @@ -1513,6 +1523,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 = "syn" version = "2.0.58" diff --git a/Cargo.toml b/Cargo.toml index ba33c39..c1f5b30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ nix_rs = { version = "0.5.0", features = ["clap"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } tracing = "0.1.37" nix_health = "0.4.1" +clap_complete = "4.4.0" [dev-dependencies] regex = "1.9" diff --git a/flake.nix b/flake.nix index ec0e633..bf19920 100644 --- a/flake.nix +++ b/flake.nix @@ -78,7 +78,15 @@ }; # Flake outputs - packages.default = self'.packages.nixci; + packages.default = self'.packages.nixci.overrideAttrs (oa: { + nativeBuildInputs = (oa.nativeBuildInputs or [ ]) ++ [ pkgs.installShellFiles pkgs.nix ]; + postInstall = '' + installShellCompletion --cmd nixci \ + --bash <($out/bin/nixci completion bash) \ + --zsh <($out/bin/nixci completion zsh) \ + --fish <($out/bin/nixci completion fish) + ''; + }); overlayAttrs.nixci = self'.packages.default; devShells.default = pkgs.mkShell { diff --git a/src/cli.rs b/src/cli.rs index 339f48d..c14f4ab 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -108,15 +108,17 @@ pub enum Command { #[arg(long, value_parser, value_delimiter = ',')] systems: Vec, }, + + /// Generates shell completion scripts + Completion { + #[arg(value_enum)] + shell: clap_complete::Shell, + }, } impl Command { /// Get the nixci [config::Config] associated with this subcommand - pub async fn get_config(&self, cmd: &NixCmd) -> anyhow::Result { - let flake_ref = match self { - Command::Build(build_cfg) => &build_cfg.flake_ref, - Command::DumpGithubActionsMatrix { flake_ref, .. } => flake_ref, - }; + pub async fn get_config(cmd: &NixCmd, flake_ref: &FlakeRef) -> anyhow::Result { let url = flake_ref.to_flake_url().await?; tracing::info!("{}", format!("🍏 {}", url.0).bold()); let cfg = config::Config::from_flake_url(cmd, &url).await?; diff --git a/src/lib.rs b/src/lib.rs index 30dce4b..458c361 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,9 +4,12 @@ pub mod github; pub mod logging; pub mod nix; +use anyhow::{Context, Ok}; +use clap::CommandFactory; +use clap_complete::generate; use std::collections::HashSet; +use std::io; -use anyhow::Context; use cli::{BuildConfig, CliArgs}; use colored::Colorize; use nix::{ @@ -21,9 +24,10 @@ use tracing::instrument; #[instrument(name = "nixci", skip(args))] pub async fn nixci(args: CliArgs) -> anyhow::Result> { tracing::debug!("Args: {args:?}"); - let cfg = args.command.get_config(&args.nixcmd).await?; + match args.command { cli::Command::Build(build_cfg) => { + let cfg = cli::Command::get_config(&args.nixcmd, &build_cfg.flake_ref).await?; let nix_info = NixInfo::from_nix(&args.nixcmd) .await .with_context(|| "Unable to gather nix info")?; @@ -39,11 +43,20 @@ pub async fn nixci(args: CliArgs) -> anyhow::Result> { ) .await } - cli::Command::DumpGithubActionsMatrix { systems, .. } => { + cli::Command::DumpGithubActionsMatrix { + systems, flake_ref, .. + } => { + let cfg = cli::Command::get_config(&args.nixcmd, &flake_ref).await?; let matrix = github::matrix::GitHubMatrix::from(systems, &cfg.subflakes); println!("{}", serde_json::to_string(&matrix)?); Ok(vec![]) } + cli::Command::Completion { shell } => { + let mut cli = CliArgs::command(); + let name = cli.get_name().to_string(); + generate(shell, &mut cli, name, &mut io::stdout()); + Ok(vec![]) + } } }