Error out if no entrypoint or command is passed (drop claude default)

This commit is contained in:
2026-04-04 10:19:58 +02:00
parent 062ddab5f8
commit cab0eb74d7
2 changed files with 27 additions and 17 deletions

View File

@@ -21,7 +21,7 @@ pub fn build(args: Args, file_config: Option<FileConfig>) -> Result<SandboxConfi
globals.validate_paths()?; globals.validate_paths()?;
profile.validate_paths()?; profile.validate_paths()?;
let (command, command_args) = resolve_command(args.command_and_args, &profile, &globals); let (command, command_args) = resolve_command(args.command_and_args, &profile, &globals)?;
let command = resolve_binary(&command) let command = resolve_binary(&command)
.ok_or_else(|| SandboxError::CommandNotFound(PathBuf::from(&command)))?; .ok_or_else(|| SandboxError::CommandNotFound(PathBuf::from(&command)))?;
@@ -118,7 +118,7 @@ fn resolve_command(
mut passthrough_args: Vec<OsString>, mut passthrough_args: Vec<OsString>,
profile: &Options, profile: &Options,
globals: &Options, globals: &Options,
) -> (OsString, Vec<OsString>) { ) -> Result<(OsString, Vec<OsString>), SandboxError> {
let entrypoint = profile.entrypoint.clone().or(globals.entrypoint.clone()); let entrypoint = profile.entrypoint.clone().or(globals.entrypoint.clone());
let command = profile.command.clone().or(globals.command.clone()); let command = profile.command.clone().or(globals.command.clone());
@@ -131,22 +131,16 @@ fn resolve_command(
args.extend(default_cmd.into_vec().into_iter().map(OsString::from)); args.extend(default_cmd.into_vec().into_iter().map(OsString::from));
} }
return (cmd, args); return Ok((cmd, args));
} }
if !passthrough_args.is_empty() { if !passthrough_args.is_empty() {
return (passthrough_args.remove(0), passthrough_args); return Ok((passthrough_args.remove(0), passthrough_args));
} }
if let Some(config_cmd) = command { if let Some(config_cmd) = command {
return config_cmd.into_binary_and_args(); return Ok(config_cmd.into_binary_and_args());
} }
if let Ok(cmd) = std::env::var("SANDBOX_CMD") { Err(SandboxError::NoCommand)
return (OsString::from(cmd), vec![]);
}
(
OsString::from("claude"),
vec![OsString::from("--dangerously-skip-permissions")],
)
} }
fn resolve_binary(name: &OsString) -> Option<PathBuf> { fn resolve_binary(name: &OsString) -> Option<PathBuf> {
@@ -712,7 +706,8 @@ mod tests {
..Options::default() ..Options::default()
}, },
&Options::default(), &Options::default(),
); )
.unwrap();
assert_eq!(cmd, "claude"); assert_eq!(cmd, "claude");
assert_eq!( assert_eq!(
args, args,
@@ -741,7 +736,8 @@ mod tests {
..Options::default() ..Options::default()
}, },
&Options::default(), &Options::default(),
); )
.unwrap();
assert_eq!(cmd, "claude"); assert_eq!(cmd, "claude");
assert_eq!( assert_eq!(
args, args,
@@ -764,7 +760,8 @@ mod tests {
..Options::default() ..Options::default()
}, },
&Options::default(), &Options::default(),
); )
.unwrap();
assert_eq!(cmd, "claude"); assert_eq!(cmd, "claude");
assert_eq!(args, vec![OsString::from("--dangerously-skip-permissions")]); assert_eq!(args, vec![OsString::from("--dangerously-skip-permissions")]);
} }
@@ -781,7 +778,8 @@ mod tests {
entrypoint: Some(CommandValue::Simple("codex".into())), entrypoint: Some(CommandValue::Simple("codex".into())),
..Options::default() ..Options::default()
}, },
); )
.unwrap();
assert_eq!(cmd, "claude"); assert_eq!(cmd, "claude");
} }
@@ -800,7 +798,8 @@ mod tests {
entrypoint: Some(CommandValue::Simple("claude".into())), entrypoint: Some(CommandValue::Simple("claude".into())),
..Options::default() ..Options::default()
}, },
); )
.unwrap();
assert_eq!(cmd, "claude"); assert_eq!(cmd, "claude");
assert_eq!( assert_eq!(
args, args,
@@ -810,6 +809,12 @@ mod tests {
.collect::<Vec<_>>() .collect::<Vec<_>>()
); );
} }
#[test]
fn no_command_errors() {
let result = resolve_command(vec![], &Options::default(), &Options::default());
assert!(matches!(result, Err(SandboxError::NoCommand)));
}
fn assert_paths(actual: &[PathBuf], expected: &[&str]) { fn assert_paths(actual: &[PathBuf], expected: &[&str]) {
let expected: Vec<PathBuf> = expected.iter().map(PathBuf::from).collect(); let expected: Vec<PathBuf> = expected.iter().map(PathBuf::from).collect();
assert_eq!(actual, &expected); assert_eq!(actual, &expected);

View File

@@ -25,6 +25,7 @@ pub enum SandboxError {
UnknownConfigKey(String), UnknownConfigKey(String),
ConfigPathNotAbsolute(PathBuf), ConfigPathNotAbsolute(PathBuf),
InvalidBwrapArg(String), InvalidBwrapArg(String),
NoCommand,
} }
impl std::fmt::Display for SandboxError { impl std::fmt::Display for SandboxError {
@@ -69,6 +70,10 @@ impl std::fmt::Display for SandboxError {
Self::InvalidBwrapArg(s) => { Self::InvalidBwrapArg(s) => {
write!(f, "invalid quoting in --bwrap-arg: {s}") write!(f, "invalid quoting in --bwrap-arg: {s}")
} }
Self::NoCommand => write!(
f,
"no command to run; specify a command via config, entrypoint, or pass one after --"
),
} }
} }
} }