@@ -26,9 +26,11 @@ const (
26
26
// PlanExecutor drives the execution of a plan's steps and
27
27
// uses the configured `executors` to execute those steps.
28
28
type PlanExecutor struct {
29
- executors []Executor
30
- plan Plan
31
- callback ExecutorCallback
29
+ executors []Executor
30
+ plan Plan
31
+ callback ExecutorCallback
32
+ LastSuccessfulStep int
33
+ StartIndex int
32
34
}
33
35
34
36
// Action represents an action to be taken by the PlanExecutor.
@@ -69,6 +71,12 @@ func WithExecutorCallback(cb ExecutorCallback) PlanExecutorOption {
69
71
}
70
72
}
71
73
74
+ func WithStartIndex (startIndex int ) PlanExecutorOption {
75
+ return func (pe * PlanExecutor ) {
76
+ pe .StartIndex = startIndex
77
+ }
78
+ }
79
+
72
80
// ExecutorCallback is the interface for the callback implementations
73
81
// to be notified while executing each Step of a migration Plan.
74
82
type ExecutorCallback interface {
@@ -103,14 +111,15 @@ func NewPlanExecutor(plan Plan, executors []Executor, opts ...PlanExecutorOption
103
111
104
112
func (pe * PlanExecutor ) Execute () error { //nolint:gocyclo // easier to follow this way
105
113
ctx := make (map [string ]any )
106
- for i := 0 ; i < len (pe .plan .Spec .Steps ); i ++ {
114
+ for i := pe . StartIndex ; i < len (pe .plan .Spec .Steps ); i ++ {
107
115
var r CallbackResult
108
116
if pe .callback != nil {
109
117
r = pe .callback .StepToExecute (pe .plan .Spec .Steps [i ], i )
110
118
switch r .Action {
111
119
case ActionCancel :
112
120
return nil
113
121
case ActionSkip :
122
+ pe .LastSuccessfulStep = i
114
123
continue
115
124
case ActionContinue , ActionRepeat :
116
125
}
@@ -124,6 +133,7 @@ func (pe *PlanExecutor) Execute() error { //nolint:gocyclo // easier to follow t
124
133
}
125
134
} else if pe .callback != nil {
126
135
r = pe .callback .StepSucceeded (pe .plan .Spec .Steps [i ], i , diag )
136
+ pe .LastSuccessfulStep = i
127
137
}
128
138
129
139
switch r .Action {
0 commit comments