use std::path::PathBuf;
use clap::{Args, CommandFactory, Parser, Subcommand, ValueEnum};
use clap_complete::Shell;
#[derive(Debug, Clone, Parser)]
#[command(
name = "sbox",
version,
about = "Policy-driven sandboxed command runner"
)]
pub struct Cli {
#[arg(long, global = true)]
pub config: Option<PathBuf>,
#[arg(long, global = true)]
pub workspace: Option<PathBuf>,
#[arg(long, global = true, value_enum)]
pub backend: Option<CliBackendKind>,
#[arg(long, global = true)]
pub image: Option<String>,
#[arg(long, global = true)]
pub profile: Option<String>,
#[arg(long, global = true, value_enum)]
pub mode: Option<CliExecutionMode>,
#[arg(short = 'v', long, global = true, action = clap::ArgAction::Count)]
pub verbose: u8,
#[arg(long, global = true)]
pub quiet: bool,
#[arg(long, global = true)]
pub strict_security: bool,
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, Clone, Subcommand)]
pub enum Commands {
Init(InitCommand),
Run(RunCommand),
Exec(ExecCommand),
Shell(ShellCommand),
Plan(PlanCommand),
Doctor(DoctorCommand),
Clean(CleanCommand),
Shim(ShimCommand),
Bootstrap(BootstrapCommand),
Audit(AuditCommand),
Completions(CompletionsCommand),
}
#[derive(Debug, Clone, Args)]
pub struct InitCommand {
#[arg(long)]
pub force: bool,
#[arg(long)]
pub preset: Option<String>,
#[arg(long)]
pub output: Option<PathBuf>,
#[arg(long, short = 'i')]
pub interactive: bool,
#[arg(long, conflicts_with_all = ["preset", "interactive"])]
pub from_lockfile: bool,
}
#[derive(Debug, Clone, Args)]
#[command(trailing_var_arg = true)]
pub struct RunCommand {
#[arg(long)]
pub dry_run: bool,
#[arg(short = 'e', long = "env", value_name = "NAME=VALUE")]
pub env: Vec<String>,
#[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
pub command: Vec<String>,
}
#[derive(Debug, Clone, Args)]
#[command(trailing_var_arg = true)]
pub struct ExecCommand {
pub profile: String,
#[arg(required = true, num_args = 1.., allow_hyphen_values = true)]
pub command: Vec<String>,
}
#[derive(Debug, Clone, Args, Default)]
pub struct ShellCommand {
#[arg(long)]
pub shell: Option<String>,
}
#[derive(Debug, Clone, Args)]
#[command(trailing_var_arg = true)]
pub struct PlanCommand {
#[arg(long)]
pub show_command: bool,
#[arg(long)]
pub audit: bool,
#[arg(num_args = 0.., allow_hyphen_values = true)]
pub command: Vec<String>,
}
#[derive(Debug, Clone, Args, Default)]
pub struct DoctorCommand {
#[arg(long)]
pub strict: bool,
}
#[derive(Debug, Clone, Args, Default)]
pub struct CleanCommand {
#[arg(long)]
pub sessions: bool,
#[arg(long)]
pub images: bool,
#[arg(long)]
pub caches: bool,
#[arg(long)]
pub all: bool,
#[arg(long = "global")]
pub global_scope: bool,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum CliBackendKind {
Podman,
Docker,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum CliExecutionMode {
Host,
Sandbox,
}
#[derive(Debug, Clone, Args, Default)]
pub struct AuditCommand {
#[arg(num_args = 0.., allow_hyphen_values = true)]
pub extra_args: Vec<String>,
}
#[derive(Debug, Clone, Args, Default)]
pub struct BootstrapCommand {}
#[derive(Debug, Clone, Args)]
pub struct CompletionsCommand {
pub shell: Shell,
}
pub fn generate_completions(shell: Shell) {
use std::io;
clap_complete::generate(shell, &mut Cli::command(), "sbox", &mut io::stdout());
}
#[derive(Debug, Clone, Args)]
pub struct ShimCommand {
#[arg(long)]
pub dir: Option<PathBuf>,
#[arg(long)]
pub force: bool,
#[arg(long)]
pub dry_run: bool,
#[arg(long)]
pub verify: bool,
}