ralph_workflow/reducer/
migration.rs1use crate::checkpoint::PipelineCheckpoint;
6use crate::checkpoint::PipelinePhase as CheckpointPhase;
7use crate::checkpoint::RebaseState as CheckpointRebaseState;
8
9use super::event::PipelinePhase;
10use super::state::{PipelineState, RebaseState};
11
12impl From<PipelineCheckpoint> for PipelineState {
17 fn from(checkpoint: PipelineCheckpoint) -> Self {
18 let rebase_state = migrate_rebase_state(&checkpoint.rebase_state);
19
20 let agent_chain = super::state::AgentChainState::initial();
21
22 PipelineState {
23 phase: migrate_phase(checkpoint.phase),
24 previous_phase: None, iteration: checkpoint.iteration,
26 total_iterations: checkpoint.total_iterations,
27 reviewer_pass: checkpoint.reviewer_pass,
28 total_reviewer_passes: checkpoint.total_reviewer_passes,
29 review_issues_found: false, context_cleaned: false, agent_chain,
32 rebase: rebase_state,
33 commit: super::state::CommitState::NotStarted,
34 execution_history: checkpoint
35 .execution_history
36 .map(|h| h.steps)
37 .unwrap_or_default(),
38 }
39 }
40}
41
42fn migrate_phase(phase: CheckpointPhase) -> PipelinePhase {
44 match phase {
45 CheckpointPhase::Rebase => PipelinePhase::Planning,
46 CheckpointPhase::Planning => PipelinePhase::Planning,
47 CheckpointPhase::Development => PipelinePhase::Development,
48 CheckpointPhase::Review => PipelinePhase::Review,
49 CheckpointPhase::Fix => PipelinePhase::Review,
50 CheckpointPhase::ReviewAgain => PipelinePhase::Review,
51 CheckpointPhase::CommitMessage => PipelinePhase::CommitMessage,
52 CheckpointPhase::FinalValidation => PipelinePhase::FinalValidation,
53 CheckpointPhase::Complete => PipelinePhase::Complete,
54 CheckpointPhase::PreRebase => PipelinePhase::Planning,
55 CheckpointPhase::PreRebaseConflict => PipelinePhase::Planning,
56 CheckpointPhase::PostRebase => PipelinePhase::CommitMessage,
57 CheckpointPhase::PostRebaseConflict => PipelinePhase::CommitMessage,
58 CheckpointPhase::Interrupted => PipelinePhase::Interrupted,
59 }
60}
61
62fn migrate_rebase_state(rebase_state: &CheckpointRebaseState) -> RebaseState {
64 match rebase_state {
65 CheckpointRebaseState::NotStarted => RebaseState::NotStarted,
66 CheckpointRebaseState::PreRebaseInProgress { upstream_branch } => RebaseState::InProgress {
67 original_head: "HEAD".to_string(),
68 target_branch: upstream_branch.clone(),
69 },
70 CheckpointRebaseState::PreRebaseCompleted { commit_oid } => RebaseState::Completed {
71 new_head: commit_oid.clone(),
72 },
73 CheckpointRebaseState::PostRebaseInProgress { upstream_branch } => {
74 RebaseState::InProgress {
75 original_head: "HEAD".to_string(),
76 target_branch: upstream_branch.clone(),
77 }
78 }
79 CheckpointRebaseState::PostRebaseCompleted { commit_oid } => RebaseState::Completed {
80 new_head: commit_oid.clone(),
81 },
82 CheckpointRebaseState::HasConflicts { files } => RebaseState::Conflicted {
83 original_head: "HEAD".to_string(),
84 target_branch: "main".to_string(),
85 files: files
86 .iter()
87 .map(|s| std::path::PathBuf::from(s.clone()))
88 .collect(),
89 resolution_attempts: 0,
90 },
91 CheckpointRebaseState::Failed { .. } => RebaseState::Skipped,
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_migrate_phase_planning() {
101 let phase = migrate_phase(CheckpointPhase::Planning);
102 assert_eq!(phase, PipelinePhase::Planning);
103 }
104
105 #[test]
106 fn test_migrate_phase_development() {
107 let phase = migrate_phase(CheckpointPhase::Development);
108 assert_eq!(phase, PipelinePhase::Development);
109 }
110
111 #[test]
112 fn test_migrate_phase_review() {
113 let phase = migrate_phase(CheckpointPhase::Review);
114 assert_eq!(phase, PipelinePhase::Review);
115 }
116
117 #[test]
118 fn test_migrate_phase_commit_message() {
119 let phase = migrate_phase(CheckpointPhase::CommitMessage);
120 assert_eq!(phase, PipelinePhase::CommitMessage);
121 }
122
123 #[test]
124 fn test_migrate_phase_complete() {
125 let phase = migrate_phase(CheckpointPhase::Complete);
126 assert_eq!(phase, PipelinePhase::Complete);
127 }
128
129 #[test]
130 fn test_migrate_rebase_state_not_started() {
131 let state = migrate_rebase_state(&CheckpointRebaseState::NotStarted);
132 assert!(matches!(state, RebaseState::NotStarted));
133 }
134
135 #[test]
136 fn test_migrate_rebase_state_pre_in_progress() {
137 let state = migrate_rebase_state(&CheckpointRebaseState::PreRebaseInProgress {
138 upstream_branch: "main".to_string(),
139 });
140 assert!(matches!(state, RebaseState::InProgress { .. }));
141 }
142
143 #[test]
144 fn test_migrate_rebase_state_has_conflicts() {
145 let files = vec!["file1.rs".to_string(), "file2.rs".to_string()];
146 let state = migrate_rebase_state(&CheckpointRebaseState::HasConflicts {
147 files: files.clone(),
148 });
149 assert!(matches!(state, RebaseState::Conflicted { .. }));
150 }
151
152 #[test]
153 fn test_migrate_rebase_state_completed() {
154 let state = migrate_rebase_state(&CheckpointRebaseState::PreRebaseCompleted {
155 commit_oid: "abc123".to_string(),
156 });
157 assert!(matches!(state, RebaseState::Completed { .. }));
158 }
159}