Prefer the bundled resource for the code mode host (#36264)

## What changed

- Resolve the code mode host from the package or standalone `resources` directory before checking beside the Codex executable.
- Preserve the existing executable-adjacent fallback when the bundled resource is missing or is not a file.

## Testing

- Cover package and standalone layouts, resource precedence, missing legacy binaries, and resource paths that point to directories.

GitOrigin-RevId: c9e97c22f35a118377dea715d255899192d1b48a
This commit is contained in:
seanh-oai
2026-07-31 04:20:56 +00:00
committed by copyberry
parent 4642370542
commit 53d06e24ea
+102 -1
View File
@@ -153,7 +153,12 @@ impl InstallContext {
}
pub fn code_mode_host_program(&self) -> PathBuf {
self.code_mode_host_program_from_exe(std::env::current_exe().ok().as_deref())
// prefer the one packed under codex-resources
self.bundled_resource(CODE_MODE_HOST_EXECUTABLE_NAME)
.map_or_else(
|| self.code_mode_host_program_from_exe(std::env::current_exe().ok().as_deref()),
AbsolutePathBuf::into_path_buf,
)
}
fn code_mode_host_program_from_exe(&self, current_exe: Option<&Path>) -> PathBuf {
@@ -323,6 +328,86 @@ mod tests {
const TEST_RESOURCE_NAME: &str = "codex-test-helper";
#[test]
fn code_mode_host_program_prefers_package_resource_over_legacy_binary() -> std::io::Result<()> {
let package_dir = tempfile::tempdir()?;
let bin_dir = package_dir.path().join(BIN_DIRNAME);
let resources_dir = package_dir.path().join(RESOURCES_DIRNAME);
fs::create_dir_all(&bin_dir)?;
fs::create_dir_all(&resources_dir)?;
fs::write(package_dir.path().join(PACKAGE_METADATA_FILENAME), "{}")?;
let exe_path = bin_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
let resource_host = resources_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME);
fs::write(&exe_path, "")?;
fs::write(bin_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME), "legacy host")?;
fs::write(&resource_host, "managed host")?;
let context = InstallContext::from_exe(
/*is_macos*/ false,
/*current_exe*/ Some(&exe_path),
/*method_override*/ None,
);
assert_eq!(
context.code_mode_host_program(),
AbsolutePathBuf::from_absolute_path(resource_host.canonicalize()?)?.into_path_buf()
);
Ok(())
}
#[test]
fn code_mode_host_program_uses_package_resource_without_legacy_binary() -> std::io::Result<()> {
let package_dir = tempfile::tempdir()?;
let bin_dir = package_dir.path().join(BIN_DIRNAME);
let resources_dir = package_dir.path().join(RESOURCES_DIRNAME);
fs::create_dir_all(&bin_dir)?;
fs::create_dir_all(&resources_dir)?;
fs::write(package_dir.path().join(PACKAGE_METADATA_FILENAME), "{}")?;
let exe_path = bin_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
let resource_host = resources_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME);
fs::write(&exe_path, "")?;
fs::write(&resource_host, "managed host")?;
let context = InstallContext::from_exe(
/*is_macos*/ false,
/*current_exe*/ Some(&exe_path),
/*method_override*/ None,
);
assert_eq!(
context.code_mode_host_program(),
AbsolutePathBuf::from_absolute_path(resource_host.canonicalize()?)?.into_path_buf()
);
Ok(())
}
#[test]
fn code_mode_host_program_ignores_resource_directory_and_uses_legacy_binary()
-> std::io::Result<()> {
let package_dir = tempfile::tempdir()?;
let bin_dir = package_dir.path().join(BIN_DIRNAME);
let resources_dir = package_dir.path().join(RESOURCES_DIRNAME);
fs::create_dir_all(&bin_dir)?;
fs::create_dir_all(resources_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME))?;
fs::write(package_dir.path().join(PACKAGE_METADATA_FILENAME), "{}")?;
let exe_path = bin_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
let legacy_host = bin_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME);
fs::write(&exe_path, "")?;
fs::write(&legacy_host, "legacy host")?;
let context = InstallContext::from_exe(
/*is_macos*/ false,
/*current_exe*/ Some(&exe_path),
/*method_override*/ None,
);
assert_eq!(
context.code_mode_host_program(),
AbsolutePathBuf::from_absolute_path(legacy_host.canonicalize()?)?.into_path_buf()
);
Ok(())
}
#[test]
fn detects_standalone_install_from_release_layout() -> std::io::Result<()> {
let codex_home = tempfile::tempdir()?;
@@ -334,6 +419,10 @@ mod tests {
let exe_path = release_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
fs::write(&exe_path, "")?;
fs::write(release_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME), "")?;
fs::write(
resources_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME),
"managed host",
)?;
fs::write(resources_dir.join(default_rg_command()), "")?;
fs::write(resources_dir.join(TEST_RESOURCE_NAME), "")?;
let canonical_release_dir =
@@ -364,6 +453,12 @@ mod tests {
.join(CODE_MODE_HOST_EXECUTABLE_NAME)
.into_path_buf()
);
assert_eq!(
context.code_mode_host_program(),
canonical_resources_dir
.join(CODE_MODE_HOST_EXECUTABLE_NAME)
.into_path_buf()
);
assert_eq!(
context.bundled_resource(TEST_RESOURCE_NAME),
Some(canonical_resources_dir.join(TEST_RESOURCE_NAME))
@@ -443,6 +538,12 @@ mod tests {
.join(CODE_MODE_HOST_EXECUTABLE_NAME)
.into_path_buf()
);
assert_eq!(
context.code_mode_host_program(),
canonical_bin_dir
.join(CODE_MODE_HOST_EXECUTABLE_NAME)
.into_path_buf()
);
assert_eq!(
context.rg_command(),
canonical_path_dir