use clap::{Args, Parser, Subcommand};
use clap_complete::Shell;
#[derive(Parser)]
#[command(
name = "cotis-cli",
version,
author,
about = "Install, update, and run Cotis routine plugins (cdylib host).",
long_about = "cotis-cli manages dynamic-library routine plugins: install from a local Cargo project, \
crates.io, or GitHub releases, then run them with arguments passed after `--`.",
arg_required_else_help = true,
propagate_version = true,
after_long_help = COMPLETIONS_HINT,
)]
pub struct CotisCli {
#[arg(short, long, global = true)]
pub verbose: bool,
#[arg(
long,
short = 'f',
global = true,
visible_alias = "fo",
help = "Overwrite files if this routine (and version) is already installed (legacy long: --fo)"
)]
pub overwrite: bool,
#[command(subcommand)]
pub command: Commands,
}
const COMPLETIONS_HINT: &str =
"Shell completions: cotis-cli completions <SHELL> (bash, elvish, fish, powershell, zsh).";
#[derive(Subcommand)]
pub enum Commands {
#[command(after_long_help = EXAMPLES_INSTALL)]
Install(InstallArgs),
#[command(alias = "reinstall", after_long_help = EXAMPLES_INSTALL)]
Update(InstallArgs),
#[command(after_long_help = EXAMPLES_RUN)]
Run(RunArgs),
#[command(hide = true)]
Build(RunArgs),
List,
Remove(RemoveArgs),
Info(InfoArgs),
#[command(name = "help-routine", visible_alias = "routine-help")]
HelpRoutine(InfoArgs),
Completions {
#[arg(value_enum)]
shell: Shell,
},
}
const EXAMPLES_INSTALL: &str = "Examples:\n cotis-cli install path:C:\\proj\\my-routine\n cotis-cli install crate:my-routine@0.2.0\n cotis-cli install gh:org/repo@latest my-alias";
const EXAMPLES_RUN: &str = "Examples:\n cotis-cli run my_routine -- --output ./dist\n cotis-cli run my_routine@1.0.0 -- --flag\n\nTip: `cotis-cli list` shows installed names; for custom shell completion you can complete the first argument from that list.";
#[derive(Args, Clone)]
pub struct InstallArgs {
pub spec: Option<String>,
pub alias: Option<String>,
#[arg(
long = "cdylib-name",
visible_alias = "dll-name",
value_name = "NAME",
help = "Built cdylib stem (e.g. my_plugin); default: from cargo metadata. A trailing .dll, .so, or .dylib is stripped"
)]
pub cdylib_name: Option<String>,
}
#[derive(Args, Clone)]
pub struct RunArgs {
pub routine: Option<String>,
#[arg(
trailing_var_arg = true,
allow_hyphen_values = true,
help = "Arguments forwarded to the routine (use `--` before flags meant for the plugin)"
)]
pub passthrough: Vec<String>,
}
#[derive(Args, Clone)]
pub struct RemoveArgs {
pub routine: Option<String>,
}
#[derive(Args, Clone)]
pub struct InfoArgs {
pub spec: Option<String>,
}