Complete the end-to-end CLI parity audit

This commit is contained in:
Hermes Agent
2026-08-10 01:51:47 +00:00
parent 4bd39b1ef2
commit 0a905e5e14
14 changed files with 1476 additions and 95 deletions

View File

@@ -3,12 +3,13 @@
use std::{error::Error, ffi::OsString, fmt, num::NonZeroUsize, path::PathBuf};
use clap::{Args, CommandFactory, Parser, Subcommand, error::ErrorKind};
use clap_complete::{Shell, generate};
use crate::PRODUCT_NAME;
pub const EXIT_SUCCESS: u8 = 0;
pub const EXIT_FAILURE: u8 = 1;
pub const EXIT_USAGE: u8 = 2;
pub const EXIT_USAGE: u8 = EXIT_FAILURE;
pub const EXIT_UNAVAILABLE: u8 = 69;
pub const EXIT_CONFIG: u8 = 78;
@@ -53,10 +54,32 @@ pub enum CommandRequest {
Copy(CopyRequest),
Git(GitRequest),
Otp(OtpRequest),
Completion { shell: CompletionShell },
Help { topic: Option<HelpTopic> },
Version,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CompletionShell {
Bash,
Elvish,
Fish,
PowerShell,
Zsh,
}
impl CompletionShell {
fn generator(self) -> Shell {
match self {
Self::Bash => Shell::Bash,
Self::Elvish => Shell::Elvish,
Self::Fish => Shell::Fish,
Self::PowerShell => Shell::PowerShell,
Self::Zsh => Shell::Zsh,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct InitRequest {
pub path: Option<String>,
@@ -417,6 +440,13 @@ pub fn otp_version_text() -> &'static str {
"1.1.1\n"
}
pub fn completion_script(shell: CompletionShell) -> Vec<u8> {
let mut command = CliArguments::command();
let mut output = Vec::new();
generate(shell.generator(), &mut command, "ironstorage", &mut output);
output
}
#[derive(Parser)]
#[command(
name = "ironstorage",
@@ -452,10 +482,26 @@ enum CommandArguments {
Copy(CopyArguments),
Git(GitArguments),
Otp(OtpArguments),
Completion(CompletionArguments),
Help(HelpArguments),
Version,
}
#[derive(Args)]
struct CompletionArguments {
#[arg(value_enum)]
shell: CompletionShellArgument,
}
#[derive(Clone, Copy, clap::ValueEnum)]
enum CompletionShellArgument {
Bash,
Elvish,
Fish,
Powershell,
Zsh,
}
#[derive(Args)]
struct InitArguments {
#[arg(short = 'p', long = "path")]
@@ -784,6 +830,15 @@ fn convert_arguments(arguments: CliArguments) -> Result<CliInvocation, CliParseE
Some(CommandArguments::Otp(arguments)) => {
CommandRequest::Otp(convert_otp(arguments.command)?)
}
Some(CommandArguments::Completion(arguments)) => CommandRequest::Completion {
shell: match arguments.shell {
CompletionShellArgument::Bash => CompletionShell::Bash,
CompletionShellArgument::Elvish => CompletionShell::Elvish,
CompletionShellArgument::Fish => CompletionShell::Fish,
CompletionShellArgument::Powershell => CompletionShell::PowerShell,
CompletionShellArgument::Zsh => CompletionShell::Zsh,
},
},
Some(CommandArguments::Help(arguments)) => {
let topic = arguments
.topic
@@ -914,9 +969,29 @@ fn normalize_dispatch(mut arguments: Vec<OsString>) -> Vec<OsString> {
};
let command = arguments[command_index].to_string_lossy();
const ROOT_COMMANDS: &[&str] = &[
"init", "ls", "list", "show", "find", "search", "grep", "insert", "add", "edit",
"generate", "rm", "remove", "delete", "mv", "rename", "cp", "copy", "git", "otp", "help",
"init",
"ls",
"list",
"show",
"find",
"search",
"grep",
"insert",
"add",
"edit",
"generate",
"rm",
"remove",
"delete",
"mv",
"rename",
"cp",
"copy",
"git",
"otp",
"help",
"version",
"completion",
];
if !ROOT_COMMANDS.contains(&command.as_ref()) && !command.starts_with('-') {
arguments.insert(command_index, OsString::from("show"));
@@ -998,7 +1073,9 @@ fn normalize_otp_dispatch(arguments: &mut Vec<OsString>, mut index: usize) {
const OTP_COMMANDS: &[&str] = &[
"code", "show", "insert", "add", "append", "uri", "validate", "help", "version",
];
if argument == "--version" {
if argument == "help" {
arguments[index] = OsString::from("--help");
} else if argument == "--version" {
arguments[index] = OsString::from("version");
} else if !OTP_COMMANDS.contains(&argument.as_ref()) && argument != "--help" && argument != "-h"
{