diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 8e609eb6ac..5339d5d8b8 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -1193,6 +1193,7 @@ name = "codex-execpolicy2" version = "0.0.0" dependencies = [ "anyhow", + "clap", "multimap", "serde", "serde_json", diff --git a/codex-rs/execpolicy2/Cargo.toml b/codex-rs/execpolicy2/Cargo.toml index 3c659575a6..36c384225b 100644 --- a/codex-rs/execpolicy2/Cargo.toml +++ b/codex-rs/execpolicy2/Cargo.toml @@ -20,3 +20,4 @@ serde_json = { workspace = true } starlark = { workspace = true } thiserror = { workspace = true } multimap = { workspace = true } +clap = { workspace = true, features = ["derive"] } diff --git a/codex-rs/execpolicy2/src/main.rs b/codex-rs/execpolicy2/src/main.rs index 5238057f3e..071c7e0918 100644 --- a/codex-rs/execpolicy2/src/main.rs +++ b/codex-rs/execpolicy2/src/main.rs @@ -3,49 +3,38 @@ use std::path::Path; use anyhow::Context; use anyhow::Result; -use anyhow::bail; +use clap::Parser; use codex_execpolicy2::PolicyParser; use codex_execpolicy2::load_default_policy; -fn main() -> Result<()> { - let mut args = std::env::args().skip(1); - let mut policy_path: Option = None; +/// CLI for evaluating exec policies +#[derive(Parser)] +#[command(name = "codex-execpolicy2")] +enum Cli { + /// Evaluate a command against a policy. + Check { + #[arg(short, long, value_name = "PATH")] + policy: Option, - while let Some(arg) = args.next() { - if arg == "--policy" || arg == "-p" { - let path = args - .next() - .context("expected a policy path after --policy/-p")?; - policy_path = Some(path); - continue; - } - // First non-flag argument is the subcommand. - let subcommand = arg; - return run_subcommand(subcommand, policy_path, args.collect()); - } - - print_usage(); - bail!("missing subcommand") + /// Command tokens to evaluate. + #[arg( + value_name = "COMMAND", + required = true, + trailing_var_arg = true, + allow_hyphen_values = true + )] + command: Vec, + }, } -fn run_subcommand( - subcommand: String, - policy_path: Option, - args: Vec, -) -> Result<()> { - match subcommand.as_str() { - "check" => cmd_check(policy_path, args), - _ => { - print_usage(); - bail!("unknown subcommand: {subcommand}") - } +fn main() -> Result<()> { + let cli = Cli::parse(); + match cli { + Cli::Check { policy, command } => cmd_check(policy, command), } } fn cmd_check(policy_path: Option, args: Vec) -> Result<()> { - if args.is_empty() { - bail!("usage: codex-execpolicy2 check "); - } let policy = load_policy(policy_path)?; let eval = policy.evaluate(&args); @@ -63,10 +52,3 @@ fn load_policy(policy_path: Option) -> Result } Ok(load_default_policy()?) } - -fn print_usage() { - eprintln!( - "usage: - codex-execpolicy2 [--policy path] check " - ); -}