recognize direct linux bundles in install context

This commit is contained in:
Channing Conger
2026-07-10 01:28:59 +00:00
parent 0e692097c4
commit 1277fa61a8
7 changed files with 104 additions and 7 deletions

View File

@@ -352,11 +352,13 @@ jobs:
rm -rf "$bundle_root"
mkdir -p "$bundle_root/codex-resources"
cp "$dest/codex-${{ matrix.target }}" "$bundle_root/codex"
cp "$dest/codex-code-mode-host-${{ matrix.target }}" "$bundle_root/codex-resources/codex-code-mode-host"
cp "$dest/bwrap-${{ matrix.target }}" "$bundle_root/codex-resources/bwrap"
chmod 0755 \
"$bundle_root/codex" \
"$bundle_root/codex-resources/codex-code-mode-host" \
"$bundle_root/codex-resources/bwrap"
tar -C "$bundle_root" -cf - codex codex-resources/bwrap |
tar -C "$bundle_root" -cf - codex codex-resources/codex-code-mode-host codex-resources/bwrap |
zstd -T0 -19 -o "$dest/codex-${{ matrix.target }}-bundle.tar.zst"
fi

View File

@@ -936,6 +936,14 @@ fn describe_install_context(context: &InstallContext) -> String {
}
}
}
InstallMethod::DirectBundle {
bundle_dir,
resources_dir,
} => format!(
"direct bundle (root {}, resources {})",
bundle_dir.display(),
resources_dir.display()
),
InstallMethod::Npm => {
describe_method_with_package_layout("npm", context.package_layout.as_ref())
}

View File

@@ -119,6 +119,7 @@ pub(super) fn search_check() -> DoctorCheck {
fn install_method_name(context: &InstallContext) -> &'static str {
match &context.method {
InstallMethod::Standalone { .. } => "standalone",
InstallMethod::DirectBundle { .. } => "direct bundle",
InstallMethod::Npm => "npm",
InstallMethod::Bun => "bun",
InstallMethod::Pnpm => "pnpm",

View File

@@ -136,6 +136,7 @@ fn update_action_label(context: &InstallContext) -> &'static str {
InstallMethod::Pnpm => "pnpm add -g @openai/codex",
InstallMethod::Brew => "brew upgrade --cask codex",
InstallMethod::Standalone { .. } => "standalone installer",
InstallMethod::DirectBundle { .. } => "manual direct bundle",
InstallMethod::Other => "manual or unknown",
}
}
@@ -147,6 +148,7 @@ fn fetch_latest_version(context: &InstallContext) -> Result<String, String> {
| InstallMethod::Bun
| InstallMethod::Pnpm
| InstallMethod::Standalone { .. }
| InstallMethod::DirectBundle { .. }
| InstallMethod::Other => fetch_latest_github_release_version(),
}
}

View File

@@ -52,6 +52,12 @@ pub enum InstallMethod {
/// The platform of the standalone release, either `Unix` or `Windows`.
platform: StandalonePlatform,
},
/// A directly extracted Linux bundle with `codex` at its root and managed
/// resources under `codex-resources/`.
DirectBundle {
bundle_dir: AbsolutePathBuf,
resources_dir: AbsolutePathBuf,
},
/// A Codex binary launched through the npm-managed `codex.js` shim.
Npm,
/// A Codex binary launched through the bun-managed `codex.js` shim.
@@ -136,7 +142,8 @@ impl InstallContext {
if let InstallMethod::Standalone {
resources_dir: Some(resources_dir),
..
} = &self.method
}
| InstallMethod::DirectBundle { resources_dir, .. } = &self.method
{
let bundled_rg = resources_dir.join(default_rg_command());
if bundled_rg.is_file() {
@@ -147,7 +154,7 @@ impl InstallContext {
default_rg_command()
}
/// Returns the code-mode host when it is part of the detected package layout.
/// Returns the code-mode host when it is part of the detected installation.
pub fn code_mode_host_program(&self) -> Option<PathBuf> {
self.bundled_resource(code_mode_host_executable_name())
.map(AbsolutePathBuf::into_path_buf)
@@ -166,7 +173,8 @@ impl InstallContext {
if let InstallMethod::Standalone {
resources_dir: Some(resources_dir),
..
} = &self.method
}
| InstallMethod::DirectBundle { resources_dir, .. } = &self.method
{
let resource = resources_dir.join(file_name);
if resource.is_file() {
@@ -225,6 +233,9 @@ fn install_method_from_exe(
{
return standalone_method;
}
if let Some(direct_bundle_method) = direct_bundle_install_method(exe_path, package_layout) {
return direct_bundle_method;
}
if is_macos && (exe_path.starts_with("/opt/homebrew") || exe_path.starts_with("/usr/local")) {
InstallMethod::Brew
@@ -233,6 +244,31 @@ fn install_method_from_exe(
}
}
fn direct_bundle_install_method(
exe_path: &Path,
package_layout: Option<&CodexPackageLayout>,
) -> Option<InstallMethod> {
if !cfg!(target_os = "linux") || package_layout.is_some() {
return None;
}
let canonical_exe = canonical_absolute_path(exe_path)?;
if canonical_exe.file_name() != Some(OsStr::new("codex")) {
return None;
}
let bundle_dir = canonical_exe.parent()?;
let resources_dir = bundle_dir.join(RESOURCES_DIRNAME);
if !resources_dir.is_dir() {
return None;
}
Some(InstallMethod::DirectBundle {
bundle_dir,
resources_dir,
})
}
fn standalone_install_method(
exe_path: &Path,
codex_home: Option<&Path>,
@@ -338,6 +374,49 @@ mod tests {
assert_eq!(context.code_mode_host_program(), None);
}
#[cfg(target_os = "linux")]
#[test]
fn detects_direct_bundle_and_resolves_resources() -> std::io::Result<()> {
let bundle_dir = tempfile::tempdir()?;
let resources_dir = bundle_dir.path().join(RESOURCES_DIRNAME);
fs::create_dir_all(&resources_dir)?;
let exe_path = bundle_dir.path().join("codex");
let host_path = resources_dir.join(code_mode_host_executable_name());
fs::write(&exe_path, "")?;
fs::write(&host_path, "")?;
let canonical_bundle_dir =
AbsolutePathBuf::from_absolute_path(bundle_dir.path().canonicalize()?)?;
let canonical_resources_dir =
AbsolutePathBuf::from_absolute_path(resources_dir.canonicalize()?)?;
let context = InstallContext::from_exe_with_codex_home(
/*is_macos*/ false,
/*current_exe*/ Some(&exe_path),
/*method_override*/ None,
/*codex_home*/ None,
);
assert_eq!(
context,
InstallContext {
method: InstallMethod::DirectBundle {
bundle_dir: canonical_bundle_dir,
resources_dir: canonical_resources_dir.clone(),
},
package_layout: None,
}
);
assert_eq!(
context.code_mode_host_program(),
Some(
canonical_resources_dir
.join(code_mode_host_executable_name())
.into_path_buf()
)
);
Ok(())
}
#[test]
fn detects_standalone_install_from_release_layout() -> std::io::Result<()> {
let codex_home = tempfile::tempdir()?;

View File

@@ -226,15 +226,20 @@ mod tests {
}
#[test]
fn finds_legacy_standalone_bundled_bwrap_next_to_exe_resources() {
fn finds_direct_bundle_bwrap_from_install_context() {
let temp_dir = tempdir().expect("temp dir");
let exe = temp_dir.path().join("codex");
let expected_bwrap = temp_dir.path().join("codex-resources").join("bwrap");
write_executable(&exe);
write_executable(&expected_bwrap);
let context = InstallContext::from_exe(
/*is_macos*/ false,
/*current_exe*/ Some(&exe),
/*method_override*/ None,
);
assert_eq!(
find_legacy_for_exe(&exe),
find_for_install_context(&context),
Some(AbsolutePathBuf::from_absolute_path(&expected_bwrap).expect("absolute"))
);
}

View File

@@ -34,7 +34,7 @@ impl UpdateAction {
StandalonePlatform::Unix => UpdateAction::StandaloneUnix,
StandalonePlatform::Windows => UpdateAction::StandaloneWindows,
}),
InstallMethod::Other => None,
InstallMethod::DirectBundle { .. } | InstallMethod::Other => None,
}
}