mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add codex update command (#19933)
## 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`
This commit is contained in:
committed by
GitHub
Unverified
parent
0a32c8b396
commit
b985768dc1
@@ -134,6 +134,9 @@ enum Subcommand {
|
||||
/// Generate shell completion scripts.
|
||||
Completion(CompletionCommand),
|
||||
|
||||
/// Update Codex to the latest version.
|
||||
Update,
|
||||
|
||||
/// Run commands within a Codex-provided sandbox.
|
||||
Sandbox(SandboxArgs),
|
||||
|
||||
@@ -615,6 +618,25 @@ fn run_update_action(action: UpdateAction) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_update_command() -> anyhow::Result<()> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
anyhow::bail!(
|
||||
"`codex update` is not available in debug builds. Install a release build of Codex to use this command."
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
let Some(action) = codex_tui::get_update_action() else {
|
||||
anyhow::bail!(
|
||||
"Could not detect the Codex installation method. Please update manually: https://developers.openai.com/codex/cli/"
|
||||
);
|
||||
};
|
||||
run_update_action(action)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_execpolicycheck(cmd: ExecPolicyCheckCommand) -> anyhow::Result<()> {
|
||||
cmd.run()
|
||||
}
|
||||
@@ -998,6 +1020,14 @@ async fn cli_main(arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
|
||||
)?;
|
||||
print_completion(completion_cli);
|
||||
}
|
||||
Some(Subcommand::Update) => {
|
||||
reject_remote_mode_for_subcommand(
|
||||
root_remote.as_deref(),
|
||||
root_remote_auth_token_env.as_deref(),
|
||||
"update",
|
||||
)?;
|
||||
run_update_command()?;
|
||||
}
|
||||
Some(Subcommand::Cloud(mut cloud_cli)) => {
|
||||
reject_remote_mode_for_subcommand(
|
||||
root_remote.as_deref(),
|
||||
@@ -1890,6 +1920,12 @@ mod tests {
|
||||
assert!(matches!(cli.subcommand, Some(Subcommand::Plugin(_))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_parses_as_update_subcommand() {
|
||||
let cli = MultitoolCli::try_parse_from(["codex", "update"]).expect("parse");
|
||||
assert!(matches!(cli.subcommand, Some(Subcommand::Update)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_marketplace_remove_parses_under_plugin() {
|
||||
let cli =
|
||||
|
||||
@@ -30,7 +30,7 @@ async fn marketplace_upgrade_no_longer_runs_at_top_level() -> Result<()> {
|
||||
.args(["marketplace", "upgrade"])
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(contains("unexpected argument 'upgrade' found"));
|
||||
.stderr(contains("unrecognized subcommand 'upgrade'"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
use anyhow::Result;
|
||||
use predicates::str::contains;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
|
||||
fn codex_command(codex_home: &Path) -> Result<assert_cmd::Command> {
|
||||
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
|
||||
cmd.env("CODEX_HOME", codex_home);
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[tokio::test]
|
||||
async fn update_does_not_start_interactive_prompt() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
|
||||
codex_command(codex_home.path())?
|
||||
.arg("update")
|
||||
.assert()
|
||||
.failure()
|
||||
.stderr(contains("`codex update` is not available in debug builds"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -171,6 +171,8 @@ mod tui;
|
||||
mod ui_consts;
|
||||
pub(crate) mod update_action;
|
||||
pub use update_action::UpdateAction;
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub use update_action::get_update_action;
|
||||
mod update_prompt;
|
||||
#[cfg(any(not(debug_assertions), test))]
|
||||
mod update_versions;
|
||||
|
||||
@@ -59,7 +59,7 @@ impl UpdateAction {
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub(crate) fn get_update_action() -> Option<UpdateAction> {
|
||||
pub fn get_update_action() -> Option<UpdateAction> {
|
||||
UpdateAction::from_install_context(InstallContext::current())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user