mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
## Why Addresses #9274 Running `codex update` currently starts an interactive Codex session with `update` as the prompt. That is a rough edge for users who expect a direct self-update command after seeing the existing update notice, and it forces them to copy the suggested package-manager command manually. ## What changed - Added a top-level `codex update` subcommand. - Reused the existing install-channel detection and update command runner that the TUI already uses for update prompts. - Exposed the update-action lookup from `codex-tui` so the CLI can invoke the same behavior. - Added CLI coverage to ensure `codex update` is parsed as a subcommand instead of becoming an interactive prompt. ## Verification - `cargo test -p codex-cli` - `cargo test -p codex-tui update_action::tests`
128 lines
4.7 KiB
Rust
128 lines
4.7 KiB
Rust
#[cfg(any(not(debug_assertions), test))]
|
|
use codex_install_context::InstallContext;
|
|
#[cfg(any(not(debug_assertions), test))]
|
|
use codex_install_context::StandalonePlatform;
|
|
|
|
/// Update action the CLI should perform after the TUI exits.
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum UpdateAction {
|
|
/// Update via `npm install -g @openai/codex@latest`.
|
|
NpmGlobalLatest,
|
|
/// Update via `bun install -g @openai/codex@latest`.
|
|
BunGlobalLatest,
|
|
/// Update via `brew upgrade codex`.
|
|
BrewUpgrade,
|
|
/// Update via `curl -fsSL https://chatgpt.com/codex/install.sh | sh`.
|
|
StandaloneUnix,
|
|
/// Update via `irm https://chatgpt.com/codex/install.ps1|iex`.
|
|
StandaloneWindows,
|
|
}
|
|
|
|
impl UpdateAction {
|
|
#[cfg(any(not(debug_assertions), test))]
|
|
pub(crate) fn from_install_context(context: &InstallContext) -> Option<Self> {
|
|
match context {
|
|
InstallContext::Npm => Some(UpdateAction::NpmGlobalLatest),
|
|
InstallContext::Bun => Some(UpdateAction::BunGlobalLatest),
|
|
InstallContext::Brew => Some(UpdateAction::BrewUpgrade),
|
|
InstallContext::Standalone { platform, .. } => Some(match platform {
|
|
StandalonePlatform::Unix => UpdateAction::StandaloneUnix,
|
|
StandalonePlatform::Windows => UpdateAction::StandaloneWindows,
|
|
}),
|
|
InstallContext::Other => None,
|
|
}
|
|
}
|
|
|
|
/// Returns the list of command-line arguments for invoking the update.
|
|
pub fn command_args(self) -> (&'static str, &'static [&'static str]) {
|
|
match self {
|
|
UpdateAction::NpmGlobalLatest => ("npm", &["install", "-g", "@openai/codex"]),
|
|
UpdateAction::BunGlobalLatest => ("bun", &["install", "-g", "@openai/codex"]),
|
|
UpdateAction::BrewUpgrade => ("brew", &["upgrade", "--cask", "codex"]),
|
|
UpdateAction::StandaloneUnix => (
|
|
"sh",
|
|
&["-c", "curl -fsSL https://chatgpt.com/codex/install.sh | sh"],
|
|
),
|
|
UpdateAction::StandaloneWindows => (
|
|
"powershell",
|
|
&["-c", "irm https://chatgpt.com/codex/install.ps1|iex"],
|
|
),
|
|
}
|
|
}
|
|
|
|
/// Returns string representation of the command-line arguments for invoking the update.
|
|
pub fn command_str(self) -> String {
|
|
let (command, args) = self.command_args();
|
|
shlex::try_join(std::iter::once(command).chain(args.iter().copied()))
|
|
.unwrap_or_else(|_| format!("{command} {}", args.join(" ")))
|
|
}
|
|
}
|
|
|
|
#[cfg(not(debug_assertions))]
|
|
pub fn get_update_action() -> Option<UpdateAction> {
|
|
UpdateAction::from_install_context(InstallContext::current())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
use std::path::PathBuf;
|
|
|
|
#[test]
|
|
fn maps_install_context_to_update_action() {
|
|
let native_release_dir = PathBuf::from("/tmp/native-release");
|
|
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Other),
|
|
None
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Npm),
|
|
Some(UpdateAction::NpmGlobalLatest)
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Bun),
|
|
Some(UpdateAction::BunGlobalLatest)
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Brew),
|
|
Some(UpdateAction::BrewUpgrade)
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Standalone {
|
|
platform: StandalonePlatform::Unix,
|
|
release_dir: native_release_dir.clone(),
|
|
resources_dir: Some(native_release_dir.join("codex-resources")),
|
|
}),
|
|
Some(UpdateAction::StandaloneUnix)
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::from_install_context(&InstallContext::Standalone {
|
|
platform: StandalonePlatform::Windows,
|
|
release_dir: native_release_dir.clone(),
|
|
resources_dir: Some(native_release_dir.join("codex-resources")),
|
|
}),
|
|
Some(UpdateAction::StandaloneWindows)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn standalone_update_commands_rerun_latest_installer() {
|
|
assert_eq!(
|
|
UpdateAction::StandaloneUnix.command_args(),
|
|
(
|
|
"sh",
|
|
&["-c", "curl -fsSL https://chatgpt.com/codex/install.sh | sh"][..],
|
|
)
|
|
);
|
|
assert_eq!(
|
|
UpdateAction::StandaloneWindows.command_args(),
|
|
(
|
|
"powershell",
|
|
&["-c", "irm https://chatgpt.com/codex/install.ps1|iex"][..],
|
|
)
|
|
);
|
|
}
|
|
}
|