Skip to main content

codex_wrapper/command/
update.rs

1//! Update Codex to the latest version (`codex update`).
2
3use crate::Codex;
4use crate::command::CodexCommand;
5use crate::error::Result;
6use crate::exec::{self, CommandOutput};
7
8/// Update Codex to the latest version.
9///
10/// Wraps `codex update`.
11#[derive(Debug, Clone)]
12pub struct UpdateCommand {
13    config_overrides: Vec<String>,
14    enabled_features: Vec<String>,
15    disabled_features: Vec<String>,
16    retry_policy: Option<crate::retry::RetryPolicy>,
17}
18
19impl UpdateCommand {
20    /// Create a new update command.
21    #[must_use]
22    pub fn new() -> Self {
23        Self {
24            config_overrides: Vec::new(),
25            enabled_features: Vec::new(),
26            disabled_features: Vec::new(),
27            retry_policy: None,
28        }
29    }
30
31    /// Override a config key (`-c key=value`). May be called multiple times.
32    #[must_use]
33    pub fn config(mut self, key_value: impl Into<String>) -> Self {
34        self.config_overrides.push(key_value.into());
35        self
36    }
37
38    /// Enable an optional feature flag (`--enable <feature>`).
39    #[must_use]
40    pub fn enable(mut self, feature: impl Into<String>) -> Self {
41        self.enabled_features.push(feature.into());
42        self
43    }
44
45    /// Disable an optional feature flag (`--disable <feature>`).
46    #[must_use]
47    pub fn disable(mut self, feature: impl Into<String>) -> Self {
48        self.disabled_features.push(feature.into());
49        self
50    }
51
52    /// Override the retry policy for this command.
53    #[must_use]
54    pub fn retry(mut self, policy: crate::retry::RetryPolicy) -> Self {
55        self.retry_policy = Some(policy);
56        self
57    }
58}
59
60impl Default for UpdateCommand {
61    fn default() -> Self {
62        Self::new()
63    }
64}
65
66impl CodexCommand for UpdateCommand {
67    type Output = CommandOutput;
68
69    fn args(&self) -> Vec<String> {
70        let mut args = vec!["update".to_string()];
71        for value in &self.config_overrides {
72            args.push("-c".into());
73            args.push(value.clone());
74        }
75        for value in &self.enabled_features {
76            args.push("--enable".into());
77            args.push(value.clone());
78        }
79        for value in &self.disabled_features {
80            args.push("--disable".into());
81            args.push(value.clone());
82        }
83        args
84    }
85
86    async fn execute(&self, codex: &Codex) -> Result<CommandOutput> {
87        exec::run_codex_with_retry(codex, self.args(), self.retry_policy.as_ref()).await
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94
95    #[test]
96    fn update_args_default() {
97        let args = UpdateCommand::new().args();
98        assert_eq!(args, vec!["update"]);
99    }
100
101    #[test]
102    fn update_args_config() {
103        let args = UpdateCommand::new().config("foo=bar").enable("beta").args();
104        assert_eq!(args, vec!["update", "-c", "foo=bar", "--enable", "beta"]);
105    }
106}