diff --git a/lifecycle/dynamic_step.go b/lifecycle/dynamic_step.go index b3e3775..ef96306 100644 --- a/lifecycle/dynamic_step.go +++ b/lifecycle/dynamic_step.go @@ -76,6 +76,10 @@ func (s *DynamicStep) GetPredicates() []PredicateFunc { return s.Predicates } +func (s *DynamicStep) AppendPredicate(predicate PredicateFunc) { + s.Predicates = append(s.Predicates, predicate) +} + func (s *DynamicStep) HasState() bool { return s.State != nil } @@ -129,6 +133,13 @@ func (s *DynamicStep) HasNestedSteps() bool { return true } +func (s *DynamicStep) GetNestedSteps() []Step { + // DynamicStep wraps a single step that's generated at runtime + // Return nil to avoid eager generation (which may depend on runtime state) + // Selection logic should check the DynamicStep's name directly, not its nested steps + return nil +} + func (s *DynamicStep) SetStateKeeperAndThrottler(stateKeeper StateKeeper, throttler throttling.Throttler) { s.StateKeeper = stateKeeper s.Throttler = throttler diff --git a/lifecycle/grouped_steps.go b/lifecycle/grouped_steps.go index f21634a..147c1d5 100644 --- a/lifecycle/grouped_steps.go +++ b/lifecycle/grouped_steps.go @@ -62,6 +62,10 @@ func (s *GroupedSteps) GetPredicates() []PredicateFunc { return s.Predicates } +func (s *GroupedSteps) AppendPredicate(predicate PredicateFunc) { + s.Predicates = append(s.Predicates, predicate) +} + func (s *GroupedSteps) HasState() bool { return s.State != nil } @@ -115,6 +119,10 @@ func (s *GroupedSteps) HasNestedSteps() bool { return true } +func (s *GroupedSteps) GetNestedSteps() []Step { + return s.Steps +} + func (s *GroupedSteps) SetStateKeeperAndThrottler(stateKeeper StateKeeper, throttler throttling.Throttler) { s.StateKeeper = stateKeeper s.Throttler = throttler diff --git a/lifecycle/parallel_steps.go b/lifecycle/parallel_steps.go index 71845b3..55ed66e 100644 --- a/lifecycle/parallel_steps.go +++ b/lifecycle/parallel_steps.go @@ -57,6 +57,10 @@ func (s *ParallelSteps) GetPredicates() []PredicateFunc { return s.Predicates } +func (s *ParallelSteps) AppendPredicate(predicate PredicateFunc) { + s.Predicates = append(s.Predicates, predicate) +} + func (s *ParallelSteps) HasState() bool { return false } @@ -89,6 +93,10 @@ func (s *ParallelSteps) HasNestedSteps() bool { return true } +func (s *ParallelSteps) GetNestedSteps() []Step { + return s.Steps +} + func (s *ParallelSteps) SetStateKeeperAndThrottler(stateKeeper StateKeeper, throttler throttling.Throttler) { s.StateKeeper = stateKeeper s.Throttler = throttler diff --git a/lifecycle/step.go b/lifecycle/step.go index 8866887..ee7b178 100644 --- a/lifecycle/step.go +++ b/lifecycle/step.go @@ -112,6 +112,10 @@ func (s *SimpleStep) GetPredicates() []PredicateFunc { return s.Predicates } +func (s *SimpleStep) AppendPredicate(predicate PredicateFunc) { + s.Predicates = append(s.Predicates, predicate) +} + func (s *SimpleStep) ShouldSkip(ctx context.Context, stateKeeper StateKeeper) bool { // Check if step is already done or if it should be able to run again if stateKeeper != nil && s.HasState() && !s.SkipStepStateCheck { @@ -137,6 +141,10 @@ func (s *SimpleStep) HasNestedSteps() bool { return false } +func (s *SimpleStep) GetNestedSteps() []Step { + return nil +} + func (s *SimpleStep) SetStateKeeperAndThrottler(stateKeeper StateKeeper, throttler throttling.Throttler) { panic("SimpleStep does not support SetStateKeeperAndThrottler") } diff --git a/lifecycle/step_engine.go b/lifecycle/step_engine.go index 48bcfd9..aa393ca 100644 --- a/lifecycle/step_engine.go +++ b/lifecycle/step_engine.go @@ -67,6 +67,8 @@ type Step interface { ShouldFinishOnSuccess() bool // Get predicates that must be true for the step to be executed GetPredicates() []PredicateFunc + // Append a predicate to the step's predicate list + AppendPredicate(predicate PredicateFunc) // Should the whole flow be aborted if one of the predicates is false ShouldAbortOnFalsePredicates() bool // Should the whole flow proceed if the step fails @@ -81,6 +83,8 @@ type Step interface { GetName() string // If the step has nested steps, return true HasNestedSteps() bool + // Get nested steps (returns nil if HasNestedSteps() is false) + GetNestedSteps() []Step // Should the step be skipped if the state is already true ShouldSkip(ctx context.Context, stateKeeper StateKeeper) bool // Does the step have a state to track