mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Resolve bundled Windows helpers through bin junctions (#39649)
## Why Installer `bin` directories can be junctions, so looking for bundled helpers relative to the apparent executable path can miss the package's `codex-resources` directory. ## What changed Retry bundled executable lookup from the canonical executable path when lookup from the original path fails. ## Testing Add a Windows regression test that creates a `bin` junction and verifies that the sandbox setup helper is resolved from the package resources directory. GitOrigin-RevId: f2f20ce1ccfa95ae65171a03a986d10e2560e696
This commit is contained in:
@@ -192,23 +192,28 @@ fn sibling_source_path(kind: HelperExecutable) -> Result<PathBuf> {
|
||||
}
|
||||
|
||||
pub(crate) fn bundled_executable_path_for_exe(exe: &Path, file_name: &str) -> Option<PathBuf> {
|
||||
let dir = exe.parent()?;
|
||||
let direct_candidate = dir.join(file_name);
|
||||
if direct_candidate.is_file() {
|
||||
return Some(direct_candidate);
|
||||
}
|
||||
|
||||
if dir.file_name() == Some(OsStr::new(BIN_DIRNAME))
|
||||
&& let Some(package_dir) = dir.parent()
|
||||
{
|
||||
let package_resource_candidate = package_dir.join(RESOURCES_DIRNAME).join(file_name);
|
||||
if package_resource_candidate.is_file() {
|
||||
return Some(package_resource_candidate);
|
||||
let find = |exe: &Path| {
|
||||
let dir = exe.parent()?;
|
||||
let direct_candidate = dir.join(file_name);
|
||||
if direct_candidate.is_file() {
|
||||
return Some(direct_candidate);
|
||||
}
|
||||
}
|
||||
|
||||
let resource_candidate = dir.join(RESOURCES_DIRNAME).join(file_name);
|
||||
resource_candidate.is_file().then_some(resource_candidate)
|
||||
if dir.file_name() == Some(OsStr::new(BIN_DIRNAME))
|
||||
&& let Some(package_dir) = dir.parent()
|
||||
{
|
||||
let package_resource_candidate = package_dir.join(RESOURCES_DIRNAME).join(file_name);
|
||||
if package_resource_candidate.is_file() {
|
||||
return Some(package_resource_candidate);
|
||||
}
|
||||
}
|
||||
|
||||
let resource_candidate = dir.join(RESOURCES_DIRNAME).join(file_name);
|
||||
resource_candidate.is_file().then_some(resource_candidate)
|
||||
};
|
||||
|
||||
// Installer bin directories can be junctions, so retry beside the real executable once.
|
||||
find(exe).or_else(|| find(&dunce::canonicalize(exe).ok()?))
|
||||
}
|
||||
|
||||
fn helper_destination_for_source(
|
||||
@@ -500,6 +505,38 @@ mod tests {
|
||||
assert_eq!(resolved, helper);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn helper_source_lookup_resolves_bin_junctions() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
let package_dir = tmp.path().join("package");
|
||||
let bin_dir = package_dir.join(BIN_DIRNAME);
|
||||
let resources_dir = package_dir.join(RESOURCES_DIRNAME);
|
||||
let install_dir = tmp.path().join("install");
|
||||
fs::create_dir_all(&bin_dir).expect("create bin dir");
|
||||
fs::create_dir_all(&resources_dir).expect("create resources dir");
|
||||
fs::create_dir_all(&install_dir).expect("create install dir");
|
||||
fs::write(bin_dir.join("codex.exe"), b"codex").expect("write exe");
|
||||
let helper = resources_dir.join("codex-windows-sandbox-setup.exe");
|
||||
fs::write(&helper, b"setup").expect("write helper");
|
||||
|
||||
let junction = install_dir.join(BIN_DIRNAME);
|
||||
let output = std::process::Command::new("cmd")
|
||||
.args(["/c", "mklink", "/J"])
|
||||
.arg(&junction)
|
||||
.arg(&bin_dir)
|
||||
.output()
|
||||
.expect("create bin junction");
|
||||
assert!(output.status.success());
|
||||
|
||||
assert_eq!(
|
||||
bundled_executable_path_for_exe(
|
||||
&junction.join("codex.exe"),
|
||||
/*file_name*/ "codex-windows-sandbox-setup.exe"
|
||||
),
|
||||
Some(dunce::canonicalize(&helper).expect("canonical helper"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn helper_source_lookup_prefers_package_resource_dir_over_bin_resource_dir() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
|
||||
Reference in New Issue
Block a user