use std::path::PathBuf;
use clap::{ArgAction, ArgGroup, Args, Parser, Subcommand, ValueEnum};
#[derive(Debug, Parser)]
#[command(
name = "arca",
about = "Build and publish containerized crate artifacts.",
after_help = "Examples:\n arca login --repo us-west1-docker.pkg.dev/my-project/arca/my-image\n arca build rust ./my-crate --profile dev --features '' --base-image nvidia/cuda:12.8.1-runtime-ubuntu24.04 --set-default\n arca build rust ./my-crate\n arca push\n arca push deadbeef\n arca list\n arca prune local --days 7\n arca prune remote --days 7"
)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, Subcommand)]
pub enum Commands {
#[command(
name = "login",
about = "Detect GCP credentials and configure Google registry publishing."
)]
Login(LoginArgs),
#[command(name = "build", about = "Build a managed runnable container artifact.")]
#[command(subcommand)]
Build(BuildCommands),
#[command(
name = "push",
about = "Push local artifacts to the configured Google registry."
)]
Push(PushArgs),
#[command(
name = "list",
about = "List all arca-tracked local and remote artifacts in a compact view."
)]
List,
#[command(
name = "prune",
about = "Delete arca-tracked local, remote, or all artifacts older than a given age."
)]
Prune(PruneArgs),
}
#[derive(Debug, Subcommand)]
pub enum BuildCommands {
#[command(
name = "rust",
about = "Build a runnable container for the Rust crate at PATH."
)]
Rust(RustArgs),
}
#[derive(Debug, Args, Clone)]
pub struct RustArgs {
#[arg(value_name = "PATH")]
pub path: PathBuf,
#[arg(long = "profile", value_name = "PROFILE")]
pub profile: Option<String>,
#[arg(
short = 'F',
long = "features",
value_name = "FEATURE",
value_delimiter = ',',
action = ArgAction::Append
)]
pub features: Option<Vec<String>>,
#[arg(long = "bin", value_name = "NAME")]
pub bin: Option<String>,
#[arg(long = "base-image", value_name = "IMAGE")]
pub base_image: Option<String>,
#[arg(short = 'u', long = "set-default")]
pub save_defaults: bool,
#[arg(long = "host-build")]
pub host_build: bool,
}
#[derive(Debug, Args)]
pub struct LoginArgs {
#[arg(long = "force")]
pub force: bool,
#[arg(long = "repo", value_name = "REGISTRY_REPO")]
pub repo: Option<String>,
}
#[derive(Debug, Args)]
pub struct PushArgs {
#[arg(value_name = "ARTIFACT")]
pub artifact: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum PruneTarget {
All,
Local,
Remote,
}
#[derive(Debug, Args)]
#[command(group(
ArgGroup::new("age")
.args(["hours", "days"])
.required(true)
.multiple(false)
))]
pub struct PruneArgs {
#[arg(value_enum, value_name = "TARGET", default_value = "all")]
pub target: PruneTarget,
#[arg(long = "hours", value_name = "HOURS")]
pub hours: Option<u64>,
#[arg(long = "days", value_name = "DAYS")]
pub days: Option<u64>,
}