| use std::path::PathBuf; |
|
|
| use clap::Parser; |
| use codex_core::config::Config; |
| use codex_git_utils::ApplyGitRequest; |
| use codex_git_utils::apply_git_patch; |
| use codex_utils_cli::CliConfigOverrides; |
|
|
| use crate::get_task::GetTaskResponse; |
| use crate::get_task::OutputItem; |
| use crate::get_task::PrOutputItem; |
| use crate::get_task::get_task; |
|
|
| |
| #[derive(Debug, Parser)] |
| pub struct ApplyCommand { |
| pub task_id: String, |
|
|
| #[clap(flatten)] |
| pub config_overrides: CliConfigOverrides, |
| } |
| pub async fn run_apply_command( |
| apply_cli: ApplyCommand, |
| cwd: Option<PathBuf>, |
| ) -> anyhow::Result<()> { |
| let config = Config::load_with_cli_overrides( |
| apply_cli |
| .config_overrides |
| .parse_overrides() |
| .map_err(anyhow::Error::msg)?, |
| ) |
| .await?; |
|
|
| let task_response = get_task(&config, apply_cli.task_id).await?; |
| apply_diff_from_task(task_response, cwd).await |
| } |
|
|
| pub async fn apply_diff_from_task( |
| task_response: GetTaskResponse, |
| cwd: Option<PathBuf>, |
| ) -> anyhow::Result<()> { |
| let diff_turn = match task_response.current_diff_task_turn { |
| Some(turn) => turn, |
| None => anyhow::bail!("No diff turn found"), |
| }; |
| let output_diff = diff_turn.output_items.iter().find_map(|item| match item { |
| OutputItem::Pr(PrOutputItem { output_diff }) => Some(output_diff), |
| _ => None, |
| }); |
| match output_diff { |
| Some(output_diff) => apply_diff(&output_diff.diff, cwd).await, |
| None => anyhow::bail!("No PR output item found"), |
| } |
| } |
|
|
| async fn apply_diff(diff: &str, cwd: Option<PathBuf>) -> anyhow::Result<()> { |
| let cwd = cwd.unwrap_or(std::env::current_dir().unwrap_or_else(|_| std::env::temp_dir())); |
| let req = ApplyGitRequest { |
| cwd, |
| diff: diff.to_string(), |
| revert: false, |
| preflight: false, |
| }; |
| let res = apply_git_patch(&req)?; |
| if res.exit_code != 0 { |
| anyhow::bail!( |
| "Git apply failed (applied={}, skipped={}, conflicts={})\nstdout:\n{}\nstderr:\n{}", |
| res.applied_paths.len(), |
| res.skipped_paths.len(), |
| res.conflicted_paths.len(), |
| res.stdout, |
| res.stderr |
| ); |
| } |
| println!("Successfully applied diff"); |
| Ok(()) |
| } |
|
|