cli: add 'completions <SHELL>' subcommand via clap_complete

This commit is contained in:
adlee-was-taken
2026-05-01 18:13:17 -04:00
parent e452d8df02
commit 6cbd011705
4 changed files with 55 additions and 1 deletions

View File

@@ -25,6 +25,7 @@ zeroize = "1"
url = "2"
data-encoding = "2"
tar = { version = "0.4", default-features = false }
clap_complete = "4"
[dev-dependencies]
assert_cmd = "2"

View File

@@ -8,7 +8,8 @@ mod session;
use std::path::PathBuf;
use anyhow::{bail, Context, Result};
use clap::{Parser, Subcommand};
use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::{generate, Shell};
#[derive(Parser)]
#[command(
@@ -163,6 +164,13 @@ enum Commands {
/// Lock the vault (no-op in CLI; present for UX parity with the extension).
Lock,
/// Emit a shell completion script for the given shell.
/// Pipe to your shell's completion file (e.g. `> /etc/bash_completion.d/relicario`).
Completions {
#[arg(value_enum)]
shell: Shell,
},
}
#[derive(Subcommand)]
@@ -354,6 +362,11 @@ fn main() -> Result<()> {
Commands::Status => cmd_status(),
Commands::Device { action } => cmd_device(action),
Commands::Lock => { eprintln!("no cached session to lock"); Ok(()) }
Commands::Completions { shell } => {
let mut cmd = Cli::command();
generate(shell, &mut cmd, "relicario", &mut std::io::stdout());
Ok(())
}
}
}

View File

@@ -0,0 +1,30 @@
use assert_cmd::Command;
use predicates::str::contains;
#[test]
fn completions_bash_emits_script() {
Command::cargo_bin("relicario").unwrap()
.args(["completions", "bash"])
.assert()
.success()
.stdout(contains("_relicario"))
.stdout(contains("complete -F"));
}
#[test]
fn completions_zsh_emits_script() {
Command::cargo_bin("relicario").unwrap()
.args(["completions", "zsh"])
.assert()
.success()
.stdout(contains("#compdef relicario"));
}
#[test]
fn completions_fish_emits_script() {
Command::cargo_bin("relicario").unwrap()
.args(["completions", "fish"])
.assert()
.success()
.stdout(contains("complete -c relicario"));
}