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 continuation: super::state::ContinuationState::new(),
40 }
41 }
42}
43
44fn migrate_phase(phase: CheckpointPhase) -> PipelinePhase {
46 match phase {
47 CheckpointPhase::Rebase => PipelinePhase::Planning,
48 CheckpointPhase::Planning => PipelinePhase::Planning,
49 CheckpointPhase::Development => PipelinePhase::Development,
50 CheckpointPhase::Review => PipelinePhase::Review,
51 CheckpointPhase::Fix => PipelinePhase::Review,
52 CheckpointPhase::ReviewAgain => PipelinePhase::Review,
53 CheckpointPhase::CommitMessage => PipelinePhase::CommitMessage,
54 CheckpointPhase::FinalValidation => PipelinePhase::FinalValidation,
55 CheckpointPhase::Complete => PipelinePhase::Complete,
56 CheckpointPhase::PreRebase => PipelinePhase::Planning,
57 CheckpointPhase::PreRebaseConflict => PipelinePhase::Planning,
58 CheckpointPhase::PostRebase => PipelinePhase::CommitMessage,
59 CheckpointPhase::PostRebaseConflict => PipelinePhase::CommitMessage,
60 CheckpointPhase::Interrupted => PipelinePhase::Interrupted,
61 }
62}
63
64fn migrate_rebase_state(rebase_state: &CheckpointRebaseState) -> RebaseState {
66 match rebase_state {
67 CheckpointRebaseState::NotStarted => RebaseState::NotStarted,
68 CheckpointRebaseState::PreRebaseInProgress { upstream_branch } => RebaseState::InProgress {
69 original_head: "HEAD".to_string(),
70 target_branch: upstream_branch.clone(),
71 },
72 CheckpointRebaseState::PreRebaseCompleted { commit_oid } => RebaseState::Completed {
73 new_head: commit_oid.clone(),
74 },
75 CheckpointRebaseState::PostRebaseInProgress { upstream_branch } => {
76 RebaseState::InProgress {
77 original_head: "HEAD".to_string(),
78 target_branch: upstream_branch.clone(),
79 }
80 }
81 CheckpointRebaseState::PostRebaseCompleted { commit_oid } => RebaseState::Completed {
82 new_head: commit_oid.clone(),
83 },
84 CheckpointRebaseState::HasConflicts { files } => RebaseState::Conflicted {
85 original_head: "HEAD".to_string(),
86 target_branch: "main".to_string(),
87 files: files
88 .iter()
89 .map(|s| std::path::PathBuf::from(s.clone()))
90 .collect(),
91 resolution_attempts: 0,
92 },
93 CheckpointRebaseState::Failed { .. } => RebaseState::Skipped,
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_migrate_phase_planning() {
103 let phase = migrate_phase(CheckpointPhase::Planning);
104 assert_eq!(phase, PipelinePhase::Planning);
105 }
106
107 #[test]
108 fn test_migrate_phase_development() {
109 let phase = migrate_phase(CheckpointPhase::Development);
110 assert_eq!(phase, PipelinePhase::Development);
111 }
112
113 #[test]
114 fn test_migrate_phase_review() {
115 let phase = migrate_phase(CheckpointPhase::Review);
116 assert_eq!(phase, PipelinePhase::Review);
117 }
118
119 #[test]
120 fn test_migrate_phase_commit_message() {
121 let phase = migrate_phase(CheckpointPhase::CommitMessage);
122 assert_eq!(phase, PipelinePhase::CommitMessage);
123 }
124
125 #[test]
126 fn test_migrate_phase_complete() {
127 let phase = migrate_phase(CheckpointPhase::Complete);
128 assert_eq!(phase, PipelinePhase::Complete);
129 }
130
131 #[test]
132 fn test_migrate_rebase_state_not_started() {
133 let state = migrate_rebase_state(&CheckpointRebaseState::NotStarted);
134 assert!(matches!(state, RebaseState::NotStarted));
135 }
136
137 #[test]
138 fn test_migrate_rebase_state_pre_in_progress() {
139 let state = migrate_rebase_state(&CheckpointRebaseState::PreRebaseInProgress {
140 upstream_branch: "main".to_string(),
141 });
142 assert!(matches!(state, RebaseState::InProgress { .. }));
143 }
144
145 #[test]
146 fn test_migrate_rebase_state_has_conflicts() {
147 let files = vec!["file1.rs".to_string(), "file2.rs".to_string()];
148 let state = migrate_rebase_state(&CheckpointRebaseState::HasConflicts {
149 files: files.clone(),
150 });
151 assert!(matches!(state, RebaseState::Conflicted { .. }));
152 }
153
154 #[test]
155 fn test_migrate_rebase_state_completed() {
156 let state = migrate_rebase_state(&CheckpointRebaseState::PreRebaseCompleted {
157 commit_oid: "abc123".to_string(),
158 });
159 assert!(matches!(state, RebaseState::Completed { .. }));
160 }
161}