mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
V2
This commit is contained in:
1
codex-rs/Cargo.lock
generated
1
codex-rs/Cargo.lock
generated
@@ -1460,6 +1460,7 @@ dependencies = [
|
||||
"codex-ansi-escape",
|
||||
"codex-app-server-protocol",
|
||||
"codex-arg0",
|
||||
"codex-auto-updater",
|
||||
"codex-common",
|
||||
"codex-core",
|
||||
"codex-feedback",
|
||||
|
||||
@@ -60,6 +60,7 @@ codex-app-server = { path = "app-server" }
|
||||
codex-app-server-protocol = { path = "app-server-protocol" }
|
||||
codex-apply-patch = { path = "apply-patch" }
|
||||
codex-arg0 = { path = "arg0" }
|
||||
codex-auto-updater = { path = "auto-updater" }
|
||||
codex-async-utils = { path = "async-utils" }
|
||||
codex-backend-client = { path = "backend-client" }
|
||||
codex-chatgpt = { path = "chatgpt" }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::Installer;
|
||||
use crate::UpdateStatus;
|
||||
use crate::errors::Error;
|
||||
use async_trait::async_trait;
|
||||
use semver::Version;
|
||||
@@ -23,14 +24,14 @@ impl BrewInstaller {
|
||||
};
|
||||
|
||||
let installer = Self { path };
|
||||
match installer.status() {
|
||||
match installer.install_status() {
|
||||
Ok(_) => Ok(Some(installer)),
|
||||
Err(Error::Unsupported) => Ok(None),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
fn status(&self) -> Result<InstallStatus, Error> {
|
||||
fn install_status(&self) -> Result<InstallStatus, Error> {
|
||||
if let Some(info) = self.formula_info()? {
|
||||
let current_version = self.formula_current_version()?;
|
||||
return Ok(InstallStatus {
|
||||
@@ -126,27 +127,39 @@ impl BrewInstaller {
|
||||
|
||||
#[async_trait]
|
||||
impl Installer for BrewInstaller {
|
||||
fn update_available(&self) -> Result<bool, Error> {
|
||||
let status = self.status()?;
|
||||
status.needs_update()
|
||||
fn version_status(&self) -> Result<UpdateStatus, Error> {
|
||||
let status = self.install_status()?;
|
||||
let update_available = status.needs_update()?;
|
||||
let InstallStatus {
|
||||
method: _,
|
||||
current_version,
|
||||
latest_version,
|
||||
} = status;
|
||||
Ok(UpdateStatus {
|
||||
current_version,
|
||||
latest_version,
|
||||
update_available,
|
||||
})
|
||||
}
|
||||
|
||||
async fn update(&self) -> Result<String, Error> {
|
||||
let initial_status = run_blocking({
|
||||
let brew = self.clone();
|
||||
move || brew.status()
|
||||
move || brew.install_status()
|
||||
})
|
||||
.await?;
|
||||
|
||||
if !initial_status.needs_update()? {
|
||||
let needs_update = initial_status.needs_update()?;
|
||||
let method = initial_status.method;
|
||||
if !needs_update {
|
||||
return Ok(initial_status.current_version);
|
||||
}
|
||||
|
||||
self.upgrade(initial_status.method).await?;
|
||||
self.upgrade(method).await?;
|
||||
|
||||
run_blocking({
|
||||
let brew = self.clone();
|
||||
move || brew.current_version(initial_status.method)
|
||||
move || brew.current_version(method)
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -482,6 +495,19 @@ esac
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_status_reports_versions() -> Result<(), Box<dyn StdError>> {
|
||||
let fake_brew = FakeBrew::formula("0.8.0", "0.9.0", "0.9.0")?;
|
||||
|
||||
let status = crate::update_status()?;
|
||||
|
||||
pretty_assertions::assert_eq!(status.update_available, true);
|
||||
pretty_assertions::assert_eq!(status.current_version, "0.8.0".to_string());
|
||||
pretty_assertions::assert_eq!(status.latest_version, "0.9.0".to_string());
|
||||
drop(fake_brew);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_executes_formula_upgrade() -> Result<(), Box<dyn StdError>> {
|
||||
let fake_brew = FakeBrew::formula("0.8.0", "0.9.0", "0.9.0")?;
|
||||
@@ -644,17 +670,15 @@ esac
|
||||
fs::write(&upgrade_log, Vec::new())?;
|
||||
|
||||
let env = EnvironmentGuard::new(tempdir.path());
|
||||
let mut vars = Vec::new();
|
||||
vars.push(VarGuard::new("BREW_FORMULA_INFO", &formula_info_path));
|
||||
vars.push(VarGuard::new("BREW_CASK_INFO", &cask_info_path));
|
||||
vars.push(VarGuard::new("BREW_FORMULA_LIST", &formula_list_path));
|
||||
vars.push(VarGuard::new("BREW_CASK_LIST", &cask_list_path));
|
||||
vars.push(VarGuard::new(
|
||||
"BREW_FORMULA_UPDATED_LIST",
|
||||
&formula_updated_path,
|
||||
));
|
||||
vars.push(VarGuard::new("BREW_CASK_UPDATED_LIST", &cask_updated_path));
|
||||
vars.push(VarGuard::new("BREW_UPGRADE_LOG", &upgrade_log));
|
||||
let vars = vec![
|
||||
VarGuard::new("BREW_FORMULA_INFO", &formula_info_path),
|
||||
VarGuard::new("BREW_CASK_INFO", &cask_info_path),
|
||||
VarGuard::new("BREW_FORMULA_LIST", &formula_list_path),
|
||||
VarGuard::new("BREW_CASK_LIST", &cask_list_path),
|
||||
VarGuard::new("BREW_FORMULA_UPDATED_LIST", &formula_updated_path),
|
||||
VarGuard::new("BREW_CASK_UPDATED_LIST", &cask_updated_path),
|
||||
VarGuard::new("BREW_UPGRADE_LOG", &upgrade_log),
|
||||
];
|
||||
|
||||
Ok(Self {
|
||||
_tempdir: tempdir,
|
||||
|
||||
@@ -6,9 +6,20 @@ pub use errors::Error;
|
||||
|
||||
use crate::brew::BrewInstaller;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UpdateStatus {
|
||||
pub current_version: String,
|
||||
pub latest_version: String,
|
||||
pub update_available: bool,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait Installer: Send + Sync {
|
||||
fn update_available(&self) -> Result<bool, Error>;
|
||||
fn version_status(&self) -> Result<UpdateStatus, Error>;
|
||||
|
||||
fn update_available(&self) -> Result<bool, Error> {
|
||||
self.version_status().map(|status| status.update_available)
|
||||
}
|
||||
|
||||
async fn update(&self) -> Result<String, Error>;
|
||||
}
|
||||
@@ -20,6 +31,10 @@ pub fn installer() -> Result<Box<dyn Installer>, Error> {
|
||||
Err(Error::Unsupported)
|
||||
}
|
||||
|
||||
pub fn update_status() -> Result<UpdateStatus, Error> {
|
||||
installer()?.version_status()
|
||||
}
|
||||
|
||||
pub fn update_available() -> Result<bool, Error> {
|
||||
installer()?.update_available()
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ codex-common = { workspace = true, features = [
|
||||
"elapsed",
|
||||
"sandbox_summary",
|
||||
] }
|
||||
codex-auto-updater = { workspace = true }
|
||||
codex-core = { workspace = true }
|
||||
codex-file-search = { workspace = true }
|
||||
codex-login = { workspace = true }
|
||||
|
||||
@@ -7,6 +7,8 @@ use additional_dirs::add_dir_warning_message;
|
||||
use app::App;
|
||||
pub use app::AppExitInfo;
|
||||
use codex_app_server_protocol::AuthMode;
|
||||
use codex_auto_updater::Error as AutoUpdateError;
|
||||
use codex_auto_updater::update_status;
|
||||
use codex_core::AuthManager;
|
||||
use codex_core::BUILT_IN_OSS_MODEL_PROVIDER_ID;
|
||||
use codex_core::CodexAuth;
|
||||
@@ -256,6 +258,22 @@ pub async fn run_main(
|
||||
.try_init();
|
||||
};
|
||||
|
||||
match update_status() {
|
||||
Ok(status) if status.update_available => {
|
||||
let current = status.current_version;
|
||||
let latest = status.latest_version;
|
||||
tracing::error!(
|
||||
current_version = current.as_str(),
|
||||
latest_version = latest.as_str(),
|
||||
"A newer Codex release is available. Update Codex from {current} to {latest} with `brew upgrade codex`."
|
||||
);
|
||||
}
|
||||
Ok(_) | Err(AutoUpdateError::Unsupported) => {}
|
||||
Err(err) => {
|
||||
tracing::debug!(error = ?err, "Failed to check for Codex updates");
|
||||
}
|
||||
}
|
||||
|
||||
run_ratatui_app(
|
||||
cli,
|
||||
config,
|
||||
|
||||
Reference in New Issue
Block a user