Error out if no entrypoint or command is passed (drop claude default)
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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 --"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user