in workflow.go [322:361]
func (w *Workflow) preflight() error {
// assert all dependency would not form a cycle
// start scanning, mark Step as Scanned only when its all dependencies are Scanned
for {
hasNewScanned := false // whether a new Step being marked as Scanned this turn
for step, state := range w.steps {
if state.GetStatus() == scanned {
continue
}
if isAllUpstreamScanned(w.UpstreamOf(step)) {
hasNewScanned = true
state.SetStatus(scanned)
}
}
if !hasNewScanned { // break when no new Step being Scanned
break
}
}
// check whether still have Steps not Scanned,
// not Scanned Steps are in a cycle.
stepsInCycle := make(ErrCycleDependency)
for step, state := range w.steps {
if state.GetStatus() == scanned {
continue
}
for up, statusErr := range w.UpstreamOf(step) {
if statusErr.Status != scanned {
stepsInCycle[step] = append(stepsInCycle[step], up)
}
}
}
if len(stepsInCycle) > 0 {
return stepsInCycle
}
// reset all Steps' status to Pending
for _, step := range w.steps {
step.SetStatus(Pending)
}
return nil
}