use clish::prelude::*;
#[command(
help = "Deploy the application to an environment",
details = "Runs pre-flight checks, builds the release artifact, then pushes it.\nUse --force to skip checks in emergencies.",
aliases = ["ship", "release"],
param(target, help = "Target host or cluster", short = 't', placeholder = "HOST"),
param(env, help = "Environment name", name = "environment", short = 'e', env = "DEPLOY_ENV"),
param(force, help = "Skip pre-flight checks", short = 'f')
)]
fn deploy(target: Pos<String>, env: Named<String>, force: bool) {
if force {
println!("Force deploying {} to {}...", target, env);
} else {
println!("Deploying {} to {}...", target, env);
}
}
#[command(
help = "Install a package",
param(package, help = "Package to install", placeholder = "PKG"),
param(version, help = "Pin to a specific version", short = 'v'),
param(tag, help = "Tags to apply (repeatable)", short = 't'),
param(force, help = "Overwrite an existing installation", short = 'f')
)]
fn install(
package: Pos<String>,
version: Pos<Option<String>>,
tag: Named<Vec<String>>,
force: bool,
) {
println!(
"Installing {}{}{}",
package,
version
.as_deref()
.map(|v| format!("@{}", v))
.unwrap_or_default(),
if force { " (forced)" } else { "" },
);
if !tag.is_empty() {
println!("Tags: {}", tag.join(", "));
}
}
#[command(
help = "Search for packages",
hidden = true,
param(query, help = "Search term", short = 'q'),
param(limit, help = "Maximum results to return", short = 'n')
)]
fn search(query: Pos<String>, limit: Named<Option<u32>>) {
match limit {
Some(n) => println!("Searching for '{}' (limit: {})", query, n),
None => println!("Searching for '{}'...", query),
}
}
#[command(
help = "Publish files to the registry",
deprecated = true,
deprecation_note = "use 'upload' instead",
param(files, help = "Files to publish"),
param(
dry_run,
help = "Print what would be published without doing it",
name = "dry-run",
short = 'n'
)
)]
fn publish(files: Pos<Vec<String>>, dry_run: bool) {
if files.is_empty() {
println!("No files specified.");
return;
}
if dry_run {
println!("Dry run: would publish: {}", files.join(", "));
} else {
println!("Publishing: {}", files.join(", "));
}
}
#[command(
help = "Set configuration values",
param(key, help = "Configuration key", short = 'k', choices = ["debug", "log_level", "port"]),
param(value, help = "Value to set", short = 'v', placeholder = "VAL")
)]
fn config(key: Named<String>, value: Pos<String>) {
println!("Setting {} = {}", key, value);
}
fn main() {
app!()
.details("You shouldn't manually wire commands to functions when the functions themselves are the commands.")
.run();
}