mirror of
https://github.com/openai/codex.git
synced 2026-09-17 12:23:33 +00:00
codex-rs: enable config tests, expose find_codex_home, add auto‑mount repo sandbox logic
This commit is contained in:
3
codex-rs/Cargo.lock
generated
3
codex-rs/Cargo.lock
generated
@@ -588,8 +588,11 @@ dependencies = [
|
||||
"codex-login",
|
||||
"codex-mcp-server",
|
||||
"codex-tui",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
|
||||
@@ -25,6 +25,8 @@ codex-linux-sandbox = { path = "../linux-sandbox" }
|
||||
codex-mcp-server = { path = "../mcp-server" }
|
||||
codex-tui = { path = "../tui" }
|
||||
serde_json = "1"
|
||||
toml = "0.8"
|
||||
serde = "1"
|
||||
tokio = { version = "1", features = [
|
||||
"io-std",
|
||||
"macros",
|
||||
@@ -35,3 +37,6 @@ tokio = { version = "1", features = [
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = "0.3.19"
|
||||
uuid = { version = "1", features = ["serde", "v4"] }
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
||||
43
codex-rs/cli/tests/config_cmd.rs
Normal file
43
codex-rs/cli/tests/config_cmd.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
/// Integration test for the `codex config` subcommand.
|
||||
/// This uses `CARGO_BIN_EXE_codex` to locate the compiled binary.
|
||||
#[cfg(test)]
|
||||
mod cli_config {
|
||||
use std::process::Command;
|
||||
use std::fs;
|
||||
use tempfile;
|
||||
use toml;
|
||||
|
||||
#[test]
|
||||
fn config_subcommand_help() {
|
||||
let exe = env!("CARGO_BIN_EXE_codex");
|
||||
let output = Command::new(exe)
|
||||
.arg("config")
|
||||
.arg("--help")
|
||||
.output()
|
||||
.expect("failed to run codex config --help");
|
||||
assert!(output.status.success(), "Exited with {:?}", output.status);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
// Should show config subcommands help
|
||||
assert!(stdout.contains("edit"), "help missing 'edit': {}", stdout);
|
||||
assert!(stdout.contains("set"), "help missing 'set': {}", stdout);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_set_and_read() {
|
||||
let exe = env!("CARGO_BIN_EXE_codex");
|
||||
let tmp = tempfile::tempdir().expect("tempdir");
|
||||
let cfg_path = tmp.path().join("config.toml");
|
||||
let status = Command::new(exe)
|
||||
.env("CODEX_HOME", tmp.path())
|
||||
.arg("config")
|
||||
.arg("set")
|
||||
.arg("tui.auto_mount_repo")
|
||||
.arg("true")
|
||||
.status()
|
||||
.expect("failed to run codex config set");
|
||||
assert!(status.success());
|
||||
let contents = fs::read_to_string(&cfg_path).expect("read config");
|
||||
let doc: toml::Value = toml::from_str(&contents).expect("parse config.toml");
|
||||
assert_eq!(doc["tui"]["auto_mount_repo"].as_bool(), Some(true));
|
||||
}
|
||||
}
|
||||
@@ -493,7 +493,7 @@ fn default_model() -> String {
|
||||
/// function will Err if the path does not exist.
|
||||
/// - If `CODEX_HOME` is not set, this function does not verify that the
|
||||
/// directory exists.
|
||||
fn find_codex_home() -> std::io::Result<PathBuf> {
|
||||
pub fn find_codex_home() -> std::io::Result<PathBuf> {
|
||||
// Honor the `CODEX_HOME` environment variable when it is set to allow users
|
||||
// (and tests) to override the default location.
|
||||
if let Ok(val) = std::env::var("CODEX_HOME") {
|
||||
|
||||
@@ -2,7 +2,11 @@ use clap::Parser;
|
||||
use codex_common::SandboxPermissionOption;
|
||||
use std::ffi::CString;
|
||||
|
||||
use libc;
|
||||
|
||||
use crate::landlock::apply_sandbox_policy_to_current_thread;
|
||||
use codex_core::config::{Config, ConfigOverrides};
|
||||
use codex_core::util::{find_git_root, relative_path_from_git_root};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct LandlockCommand {
|
||||
@@ -22,12 +26,48 @@ pub fn run_main() -> ! {
|
||||
None => codex_core::protocol::SandboxPolicy::new_read_only_policy(),
|
||||
};
|
||||
|
||||
let cwd = match std::env::current_dir() {
|
||||
// Determine working directory inside the session, possibly auto-mounting the repo.
|
||||
let mut cwd = match std::env::current_dir() {
|
||||
Ok(cwd) => cwd,
|
||||
Err(e) => {
|
||||
panic!("failed to getcwd(): {e:?}");
|
||||
}
|
||||
Err(e) => panic!("failed to getcwd(): {e:?}"),
|
||||
};
|
||||
// Load configuration to check auto_mount_repo flag
|
||||
let config = match codex_core::config::Config::load_with_cli_overrides(
|
||||
Vec::new(),
|
||||
codex_core::config::ConfigOverrides::default(),
|
||||
) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => panic!("failed to load config for auto-mount: {e:?}"),
|
||||
};
|
||||
if config.tui.auto_mount_repo {
|
||||
if let Some(root) = codex_core::util::find_git_root(&cwd) {
|
||||
// Compute relative subpath
|
||||
let rel = codex_core::util::relative_path_from_git_root(&cwd).unwrap_or_default();
|
||||
let mount_prefix = std::path::PathBuf::from(&config.tui.mount_prefix);
|
||||
// Create mount target
|
||||
std::fs::create_dir_all(&mount_prefix).unwrap_or_else(|e| {
|
||||
panic!("failed to create mount prefix {mount_prefix:?}: {e:?}")
|
||||
});
|
||||
// Bind-mount repository root into session
|
||||
let src = std::ffi::CString::new(root.to_string_lossy().as_ref())
|
||||
.expect("invalid git root path");
|
||||
let dst = std::ffi::CString::new(mount_prefix.to_string_lossy().as_ref())
|
||||
.expect("invalid mount prefix path");
|
||||
unsafe {
|
||||
libc::mount(
|
||||
src.as_ptr(),
|
||||
dst.as_ptr(),
|
||||
std::ptr::null(),
|
||||
libc::MS_BIND,
|
||||
std::ptr::null(),
|
||||
);
|
||||
}
|
||||
// Change working directory to corresponding subfolder under mount
|
||||
cwd = mount_prefix.join(rel);
|
||||
std::env::set_current_dir(&cwd)
|
||||
.unwrap_or_else(|e| panic!("failed to chdir to {cwd:?}: {e:?}"));
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = apply_sandbox_policy_to_current_thread(&sandbox_policy, &cwd) {
|
||||
panic!("error running landlock: {e:?}");
|
||||
|
||||
Reference in New Issue
Block a user