ralph/commands/task/update/
mod.rs1mod preview;
19mod reporting;
20mod runner;
21mod state;
22#[cfg(test)]
23mod tests;
24
25use super::TaskUpdateSettings;
26use crate::{config, queue};
27use anyhow::{Context, Result, bail};
28
29pub fn update_task(
30 resolved: &config::Resolved,
31 task_id: &str,
32 settings: &TaskUpdateSettings,
33) -> Result<()> {
34 update_task_impl(resolved, task_id, settings, true)
35}
36
37pub fn update_task_without_lock(
38 resolved: &config::Resolved,
39 task_id: &str,
40 settings: &TaskUpdateSettings,
41) -> Result<()> {
42 update_task_impl(resolved, task_id, settings, false)
43}
44
45pub fn update_all_tasks(resolved: &config::Resolved, settings: &TaskUpdateSettings) -> Result<()> {
46 let _queue_lock =
47 queue::acquire_queue_lock(&resolved.repo_root, "task update", settings.force)?;
48
49 let queue_file = queue::load_queue(&resolved.queue_path)
50 .with_context(|| format!("read queue {}", resolved.queue_path.display()))?;
51
52 if queue_file.tasks.is_empty() {
53 bail!("No tasks in queue to update.");
54 }
55
56 let task_ids: Vec<String> = queue_file
57 .tasks
58 .iter()
59 .map(|task| task.id.clone())
60 .collect();
61 for task_id in task_ids {
62 update_task_impl(resolved, &task_id, settings, false)?;
63 }
64
65 Ok(())
66}
67
68fn update_task_impl(
69 resolved: &config::Resolved,
70 task_id: &str,
71 settings: &TaskUpdateSettings,
72 acquire_lock: bool,
73) -> Result<()> {
74 if settings.dry_run {
75 return preview::preview_task_update(resolved, task_id, settings);
76 }
77
78 let _queue_lock = if acquire_lock {
79 Some(queue::acquire_queue_lock(
80 &resolved.repo_root,
81 "task update",
82 settings.force,
83 )?)
84 } else {
85 None
86 };
87
88 let backup_path = state::backup_queue_for_update(resolved)?;
89 let prepared = state::prepare_task_update(resolved, task_id)?;
90 let prompt = runner::build_task_update_prompt(resolved, prepared.task_id.as_str(), settings)?;
91
92 runner::run_task_updater(resolved, settings, &prompt)?;
93
94 let after = state::load_validate_and_save_queue_after_update(
95 resolved,
96 &backup_path,
97 prepared.max_depth,
98 )?;
99 let done_after = state::load_done_queue(resolved)?;
100
101 if let Some(after_task) = state::find_task(&after, prepared.task_id.as_str()) {
102 return reporting::log_task_update_changes(
103 &prepared.before_json,
104 prepared.task_id.as_str(),
105 "updated",
106 Some(after_task),
107 );
108 }
109
110 reporting::log_task_update_changes(
111 &prepared.before_json,
112 prepared.task_id.as_str(),
113 "moved to done.jsonc",
114 state::find_task(&done_after, prepared.task_id.as_str()),
115 )
116}