codex_chatgpt/
apply_command.rs1use std::path::PathBuf;
2
3use clap::Parser;
4use codex_core::config::Config;
5use codex_git_utils::ApplyGitRequest;
6use codex_git_utils::apply_git_patch;
7use codex_utils_cli::CliConfigOverrides;
8
9use crate::get_task::GetTaskResponse;
10use crate::get_task::OutputItem;
11use crate::get_task::PrOutputItem;
12use crate::get_task::get_task;
13
14#[derive(Debug, Parser)]
16pub struct ApplyCommand {
17 pub task_id: String,
18
19 #[clap(flatten)]
20 pub config_overrides: CliConfigOverrides,
21}
22pub async fn run_apply_command(
23 apply_cli: ApplyCommand,
24 cwd: Option<PathBuf>,
25) -> anyhow::Result<()> {
26 let config = Config::load_with_cli_overrides(
27 apply_cli
28 .config_overrides
29 .parse_overrides()
30 .map_err(anyhow::Error::msg)?,
31 )
32 .await?;
33
34 let task_response = get_task(&config, apply_cli.task_id).await?;
35 apply_diff_from_task(task_response, cwd).await
36}
37
38pub async fn apply_diff_from_task(
39 task_response: GetTaskResponse,
40 cwd: Option<PathBuf>,
41) -> anyhow::Result<()> {
42 let diff_turn = match task_response.current_diff_task_turn {
43 Some(turn) => turn,
44 None => anyhow::bail!("No diff turn found"),
45 };
46 let output_diff = diff_turn.output_items.iter().find_map(|item| match item {
47 OutputItem::Pr(PrOutputItem { output_diff }) => Some(output_diff),
48 _ => None,
49 });
50 match output_diff {
51 Some(output_diff) => apply_diff(&output_diff.diff, cwd).await,
52 None => anyhow::bail!("No PR output item found"),
53 }
54}
55
56async fn apply_diff(diff: &str, cwd: Option<PathBuf>) -> anyhow::Result<()> {
57 let cwd = cwd.unwrap_or(std::env::current_dir().unwrap_or_else(|_| std::env::temp_dir()));
58 let req = ApplyGitRequest {
59 cwd,
60 diff: diff.to_string(),
61 revert: false,
62 preflight: false,
63 };
64 let res = apply_git_patch(&req)?;
65 if res.exit_code != 0 {
66 anyhow::bail!(
67 "Git apply failed (applied={}, skipped={}, conflicts={})\nstdout:\n{}\nstderr:\n{}",
68 res.applied_paths.len(),
69 res.skipped_paths.len(),
70 res.conflicted_paths.len(),
71 res.stdout,
72 res.stderr
73 );
74 }
75 println!("Successfully applied diff");
76 Ok(())
77}