mirror of
https://github.com/openai/codex.git
synced 2026-08-23 13:09:46 +00:00
Extend bundled package discovery and expose its version (#37886)
## What changed - Recognize executables under `codex-resources/` as part of a package layout by resolving the sibling `bin/` directory, while requiring that directory to exist. - Add `InstallContext::package_manifest()` to parse the semantic package version from `codex-package.json`. ## Testing - Extend the package-layout test fixture with a complete manifest and verify that version `1.2.3` is returned. GitOrigin-RevId: 034aad3e8b865c6c6ecdff47da7c12c969744404
This commit is contained in:
committed by
copyberry
parent
9558d830f6
commit
cc2f262033
7
codex-rs/Cargo.lock
generated
7
codex-rs/Cargo.lock
generated
@@ -3392,6 +3392,9 @@ dependencies = [
|
|||||||
"codex-utils-absolute-path",
|
"codex-utils-absolute-path",
|
||||||
"codex-utils-home-dir",
|
"codex-utils-home-dir",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -12256,6 +12259,10 @@ name = "semver"
|
|||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sentry"
|
name = "sentry"
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
codex-utils-absolute-path = { workspace = true }
|
codex-utils-absolute-path = { workspace = true }
|
||||||
codex-utils-home-dir = { workspace = true }
|
codex-utils-home-dir = { workspace = true }
|
||||||
|
semver = { workspace = true, features = ["serde"] }
|
||||||
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = { workspace = true }
|
pretty_assertions = { workspace = true }
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ use std::path::PathBuf;
|
|||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||||
|
use semver::Version;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
const BIN_DIRNAME: &str = "bin";
|
const BIN_DIRNAME: &str = "bin";
|
||||||
const CODE_MODE_HOST_EXECUTABLE_NAME: &str = if cfg!(windows) {
|
const CODE_MODE_HOST_EXECUTABLE_NAME: &str = if cfg!(windows) {
|
||||||
@@ -37,6 +39,12 @@ pub struct CodexPackageLayout {
|
|||||||
pub path_dir: Option<AbsolutePathBuf>,
|
pub path_dir: Option<AbsolutePathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Version metadata recorded in a bundled Codex runtime package.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||||
|
pub struct CodexPackageManifest {
|
||||||
|
pub version: Version,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct InstallContext {
|
pub struct InstallContext {
|
||||||
pub method: InstallMethod,
|
pub method: InstallMethod,
|
||||||
@@ -128,6 +136,15 @@ impl InstallContext {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the manifest for the package that contains the current executable.
|
||||||
|
pub fn package_manifest(&self) -> Option<CodexPackageManifest> {
|
||||||
|
let package_layout = self.package_layout.as_ref()?;
|
||||||
|
let manifest =
|
||||||
|
std::fs::read_to_string(package_layout.package_dir.join(PACKAGE_METADATA_FILENAME))
|
||||||
|
.ok()?;
|
||||||
|
serde_json::from_str(&manifest).ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rg_command(&self) -> PathBuf {
|
pub fn rg_command(&self) -> PathBuf {
|
||||||
if let Some(package_layout) = &self.package_layout
|
if let Some(package_layout) = &self.package_layout
|
||||||
&& let Some(path_dir) = &package_layout.path_dir
|
&& let Some(path_dir) = &package_layout.path_dir
|
||||||
@@ -227,11 +244,18 @@ impl CodexPackageLayout {
|
|||||||
let exe_dir = canonical_exe.parent()?;
|
let exe_dir = canonical_exe.parent()?;
|
||||||
match exe_dir.file_name() {
|
match exe_dir.file_name() {
|
||||||
Some(name) if name == OsStr::new(BIN_DIRNAME) => Self::from_package_bin_dir(exe_dir),
|
Some(name) if name == OsStr::new(BIN_DIRNAME) => Self::from_package_bin_dir(exe_dir),
|
||||||
|
Some(name) if name == OsStr::new(RESOURCES_DIRNAME) => {
|
||||||
|
let package_dir = exe_dir.parent()?;
|
||||||
|
Self::from_package_bin_dir(package_dir.join(BIN_DIRNAME))
|
||||||
|
}
|
||||||
Some(_) | None => None,
|
Some(_) | None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_package_bin_dir(bin_dir: AbsolutePathBuf) -> Option<Self> {
|
fn from_package_bin_dir(bin_dir: AbsolutePathBuf) -> Option<Self> {
|
||||||
|
if !bin_dir.is_dir() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let package_dir = bin_dir.parent()?;
|
let package_dir = bin_dir.parent()?;
|
||||||
if !package_dir.join(PACKAGE_METADATA_FILENAME).is_file() {
|
if !package_dir.join(PACKAGE_METADATA_FILENAME).is_file() {
|
||||||
return None;
|
return None;
|
||||||
@@ -495,7 +519,19 @@ mod tests {
|
|||||||
fs::create_dir_all(&bin_dir)?;
|
fs::create_dir_all(&bin_dir)?;
|
||||||
fs::create_dir_all(&resources_dir)?;
|
fs::create_dir_all(&resources_dir)?;
|
||||||
fs::create_dir_all(&path_dir)?;
|
fs::create_dir_all(&path_dir)?;
|
||||||
fs::write(package_dir.path().join(PACKAGE_METADATA_FILENAME), "{}")?;
|
fs::write(
|
||||||
|
package_dir.path().join(PACKAGE_METADATA_FILENAME),
|
||||||
|
r#"{
|
||||||
|
"layoutVersion": 1,
|
||||||
|
"version": "1.2.3",
|
||||||
|
"target": "x86_64-unknown-linux-musl",
|
||||||
|
"variant": "codex",
|
||||||
|
"entrypoint": "bin/codex",
|
||||||
|
"resourcesDir": "codex-resources",
|
||||||
|
"pathDir": "codex-path"
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
let exe_path = bin_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
|
let exe_path = bin_dir.join(if cfg!(windows) { "codex.exe" } else { "codex" });
|
||||||
fs::write(&exe_path, "")?;
|
fs::write(&exe_path, "")?;
|
||||||
fs::write(bin_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME), "")?;
|
fs::write(bin_dir.join(CODE_MODE_HOST_EXECUTABLE_NAME), "")?;
|
||||||
@@ -532,6 +568,12 @@ mod tests {
|
|||||||
package_layout: Some(package_layout),
|
package_layout: Some(package_layout),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
context.package_manifest(),
|
||||||
|
Some(CodexPackageManifest {
|
||||||
|
version: Version::new(1, 2, 3),
|
||||||
|
})
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
context.code_mode_host_program_from_exe(Some(&exe_path)),
|
context.code_mode_host_program_from_exe(Some(&exe_path)),
|
||||||
canonical_bin_dir
|
canonical_bin_dir
|
||||||
|
|||||||
Reference in New Issue
Block a user