chore: remove issue ID references from comments and changelogs
Strip (bd-xxx), (gt-xxx) suffixes from code comments and changelog entries. The descriptions remain meaningful without the ephemeral issue IDs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,7 @@ func MatchGlob(pattern, stepID string) bool {
|
||||
// Returns a new steps slice with advice steps inserted.
|
||||
// The original steps slice is not modified.
|
||||
//
|
||||
// Self-matching prevention (gt-8tmz.16): Advice only matches steps that
|
||||
// Self-matching prevention: Advice only matches steps that
|
||||
// existed BEFORE this call. Steps inserted by advice (before/after/around)
|
||||
// are not matched, preventing infinite recursion.
|
||||
func ApplyAdvice(steps []*Step, advice []*AdviceRule) []*Step {
|
||||
@@ -64,7 +64,7 @@ func ApplyAdvice(steps []*Step, advice []*AdviceRule) []*Step {
|
||||
return steps
|
||||
}
|
||||
|
||||
// Collect original step IDs to prevent self-matching (gt-8tmz.16)
|
||||
// Collect original step IDs to prevent self-matching
|
||||
originalIDs := collectStepIDs(steps)
|
||||
|
||||
return applyAdviceWithGuard(steps, advice, originalIDs)
|
||||
@@ -77,7 +77,7 @@ func applyAdviceWithGuard(steps []*Step, advice []*AdviceRule, originalIDs map[s
|
||||
result := make([]*Step, 0, len(steps)*2) // Pre-allocate for insertions
|
||||
|
||||
for _, step := range steps {
|
||||
// Skip steps not in original set (gt-8tmz.16)
|
||||
// Skip steps not in original set
|
||||
if !originalIDs[step.ID] {
|
||||
result = append(result, step)
|
||||
continue
|
||||
@@ -170,7 +170,7 @@ func adviceStepToStep(as *AdviceStep, target *Step) *Step {
|
||||
Title: title,
|
||||
Description: desc,
|
||||
Type: as.Type,
|
||||
SourceFormula: target.SourceFormula, // Inherit source formula from target (gt-8tmz.18)
|
||||
SourceFormula: target.SourceFormula, // Inherit source formula from target
|
||||
// SourceLocation will be "advice" to indicate this came from advice transformation
|
||||
SourceLocation: "advice",
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func cloneStep(s *Step) *Step {
|
||||
clone.Labels = make([]string, len(s.Labels))
|
||||
copy(clone.Labels, s.Labels)
|
||||
}
|
||||
// Deep copy OnComplete if present (gt-8tmz.8)
|
||||
// Deep copy OnComplete if present
|
||||
if s.OnComplete != nil {
|
||||
clone.OnComplete = cloneOnComplete(s.OnComplete)
|
||||
}
|
||||
@@ -207,7 +207,7 @@ func cloneStep(s *Step) *Step {
|
||||
return &clone
|
||||
}
|
||||
|
||||
// cloneOnComplete creates a deep copy of an OnCompleteSpec (gt-8tmz.8).
|
||||
// cloneOnComplete creates a deep copy of an OnCompleteSpec.
|
||||
func cloneOnComplete(oc *OnCompleteSpec) *OnCompleteSpec {
|
||||
if oc == nil {
|
||||
return nil
|
||||
@@ -233,7 +233,7 @@ func appendUnique(slice []string, item string) []string {
|
||||
}
|
||||
|
||||
// collectStepIDs returns a set of all step IDs (including nested children).
|
||||
// Used by ApplyAdvice to prevent self-matching (gt-8tmz.16).
|
||||
// Used by ApplyAdvice to prevent self-matching.
|
||||
func collectStepIDs(steps []*Step) map[string]bool {
|
||||
ids := make(map[string]bool)
|
||||
var collect func([]*Step)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Package formula provides control flow operators for step transformation.
|
||||
//
|
||||
// Control flow operators (gt-8tmz.4) enable:
|
||||
// Control flow operators enable:
|
||||
// - loop: Repeat a body of steps (fixed count or conditional)
|
||||
// - branch: Fork-join parallel execution patterns
|
||||
// - gate: Conditional waits before steps proceed
|
||||
@@ -97,7 +97,7 @@ func validateLoopSpec(loop *LoopSpec, stepID string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate range syntax if present (gt-8tmz.27)
|
||||
// Validate range syntax if present
|
||||
if loop.Range != "" {
|
||||
if err := ValidateRange(loop.Range); err != nil {
|
||||
return fmt.Errorf("loop %q: invalid range %q: %w", stepID, loop.Range, err)
|
||||
@@ -127,7 +127,7 @@ func expandLoopWithVars(step *Step, vars map[string]string) ([]*Step, error) {
|
||||
result = append(result, iterSteps...)
|
||||
}
|
||||
|
||||
// Recursively expand any nested loops FIRST (gt-zn35j)
|
||||
// Recursively expand any nested loops FIRST
|
||||
var err error
|
||||
result, err = ApplyLoops(result)
|
||||
if err != nil {
|
||||
@@ -140,7 +140,7 @@ func expandLoopWithVars(step *Step, vars map[string]string) ([]*Step, error) {
|
||||
result = chainExpandedIterations(result, step.ID, step.Loop.Count)
|
||||
}
|
||||
} else if step.Loop.Range != "" {
|
||||
// Range loop (gt-8tmz.27): expand body for each value in the computed range
|
||||
// Range loop: expand body for each value in the computed range
|
||||
rangeSpec, err := ParseRange(step.Loop.Range, vars)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loop %q: %w", step.ID, err)
|
||||
@@ -169,7 +169,7 @@ func expandLoopWithVars(step *Step, vars map[string]string) ([]*Step, error) {
|
||||
result = append(result, iterSteps...)
|
||||
}
|
||||
|
||||
// Recursively expand any nested loops FIRST (gt-zn35j)
|
||||
// Recursively expand any nested loops FIRST
|
||||
result, err = ApplyLoops(result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -199,7 +199,7 @@ func expandLoopWithVars(step *Step, vars map[string]string) ([]*Step, error) {
|
||||
firstStep.Labels = append(firstStep.Labels, fmt.Sprintf("loop:%s", string(loopJSON)))
|
||||
}
|
||||
|
||||
// Recursively expand any nested loops (gt-zn35j)
|
||||
// Recursively expand any nested loops
|
||||
result, err = ApplyLoops(iterSteps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -211,7 +211,7 @@ func expandLoopWithVars(step *Step, vars map[string]string) ([]*Step, error) {
|
||||
|
||||
// expandLoopIteration expands a single iteration of a loop.
|
||||
// The iteration index is used to generate unique step IDs.
|
||||
// The iterVars map contains loop variable bindings for this iteration (gt-8tmz.27).
|
||||
// The iterVars map contains loop variable bindings for this iteration.
|
||||
//
|
||||
//nolint:unparam // error return kept for API consistency with future error handling
|
||||
func expandLoopIteration(step *Step, iteration int, iterVars map[string]string) ([]*Step, error) {
|
||||
@@ -224,7 +224,7 @@ func expandLoopIteration(step *Step, iteration int, iterVars map[string]string)
|
||||
// Create unique ID for this iteration
|
||||
iterID := fmt.Sprintf("%s.iter%d.%s", step.ID, iteration, bodyStep.ID)
|
||||
|
||||
// Substitute loop variables in title and description (gt-8tmz.27)
|
||||
// Substitute loop variables in title and description
|
||||
title := substituteLoopVars(bodyStep.Title, iterVars)
|
||||
description := substituteLoopVars(bodyStep.Description, iterVars)
|
||||
|
||||
@@ -239,13 +239,13 @@ func expandLoopIteration(step *Step, iteration int, iterVars map[string]string)
|
||||
WaitsFor: bodyStep.WaitsFor,
|
||||
Expand: bodyStep.Expand,
|
||||
Gate: bodyStep.Gate,
|
||||
Loop: cloneLoopSpec(bodyStep.Loop), // Support nested loops (gt-zn35j)
|
||||
Loop: cloneLoopSpec(bodyStep.Loop), // Support nested loops
|
||||
OnComplete: cloneOnComplete(bodyStep.OnComplete),
|
||||
SourceFormula: bodyStep.SourceFormula, // Preserve source (gt-8tmz.18)
|
||||
SourceFormula: bodyStep.SourceFormula, // Preserve source
|
||||
SourceLocation: fmt.Sprintf("%s.iter%d", bodyStep.SourceLocation, iteration), // Track iteration
|
||||
}
|
||||
|
||||
// Clone ExpandVars if present, adding loop vars (gt-8tmz.27)
|
||||
// Clone ExpandVars if present, adding loop vars
|
||||
if len(bodyStep.ExpandVars) > 0 || len(iterVars) > 0 {
|
||||
clone.ExpandVars = make(map[string]string)
|
||||
for k, v := range bodyStep.ExpandVars {
|
||||
@@ -369,7 +369,7 @@ func chainLoopIterations(steps []*Step, body []*Step, count int) []*Step {
|
||||
return steps
|
||||
}
|
||||
|
||||
// chainExpandedIterations chains iterations AFTER nested loop expansion (gt-zn35j).
|
||||
// chainExpandedIterations chains iterations AFTER nested loop expansion.
|
||||
// Unlike chainLoopIterations, this handles variable step counts per iteration
|
||||
// by finding iteration boundaries via ID prefix matching.
|
||||
func chainExpandedIterations(steps []*Step, loopID string, count int) []*Step {
|
||||
@@ -421,7 +421,7 @@ func ApplyBranches(steps []*Step, compose *ComposeRules) ([]*Step, error) {
|
||||
return steps, nil
|
||||
}
|
||||
|
||||
// Clone steps to avoid mutating input (gt-v1pcg)
|
||||
// Clone steps to avoid mutating input
|
||||
cloned := cloneStepsRecursive(steps)
|
||||
stepMap := buildStepMap(cloned)
|
||||
|
||||
@@ -493,7 +493,7 @@ func ApplyGates(steps []*Step, compose *ComposeRules) ([]*Step, error) {
|
||||
return steps, nil
|
||||
}
|
||||
|
||||
// Clone steps to avoid mutating input (gt-v1pcg)
|
||||
// Clone steps to avoid mutating input
|
||||
cloned := cloneStepsRecursive(steps)
|
||||
stepMap := buildStepMap(cloned)
|
||||
|
||||
@@ -558,7 +558,7 @@ func ApplyControlFlow(steps []*Step, compose *ComposeRules) ([]*Step, error) {
|
||||
return nil, fmt.Errorf("applying loops: %w", err)
|
||||
}
|
||||
|
||||
// Build stepMap once for branches and gates (gt-gpgdv optimization)
|
||||
// Build stepMap once for branches and gates
|
||||
// No need to clone here since ApplyLoops already returned a new slice
|
||||
stepMap := buildStepMap(steps)
|
||||
|
||||
@@ -589,7 +589,7 @@ func cloneStepDeep(s *Step) *Step {
|
||||
return clone
|
||||
}
|
||||
|
||||
// cloneStepsRecursive creates a deep copy of a slice of steps (gt-v1pcg).
|
||||
// cloneStepsRecursive creates a deep copy of a slice of steps.
|
||||
func cloneStepsRecursive(steps []*Step) []*Step {
|
||||
result := make([]*Step, len(steps))
|
||||
for i, step := range steps {
|
||||
@@ -598,7 +598,7 @@ func cloneStepsRecursive(steps []*Step) []*Step {
|
||||
return result
|
||||
}
|
||||
|
||||
// cloneLoopSpec creates a deep copy of a LoopSpec (gt-zn35j).
|
||||
// cloneLoopSpec creates a deep copy of a LoopSpec.
|
||||
func cloneLoopSpec(loop *LoopSpec) *LoopSpec {
|
||||
if loop == nil {
|
||||
return nil
|
||||
@@ -607,8 +607,8 @@ func cloneLoopSpec(loop *LoopSpec) *LoopSpec {
|
||||
Count: loop.Count,
|
||||
Until: loop.Until,
|
||||
Max: loop.Max,
|
||||
Range: loop.Range, // gt-8tmz.27
|
||||
Var: loop.Var, // gt-8tmz.27
|
||||
Range: loop.Range,
|
||||
Var: loop.Var,
|
||||
}
|
||||
if len(loop.Body) > 0 {
|
||||
clone.Body = make([]*Step, len(loop.Body))
|
||||
|
||||
@@ -72,7 +72,7 @@ func ApplyExpansions(steps []*Step, compose *ComposeRules, parser *Parser) ([]*S
|
||||
return nil, fmt.Errorf("expand: %q has no template steps", rule.With)
|
||||
}
|
||||
|
||||
// Merge formula default vars with rule overrides (gt-8tmz.34)
|
||||
// Merge formula default vars with rule overrides
|
||||
vars := mergeVars(expFormula, rule.Vars)
|
||||
|
||||
// Expand the target step (start at depth 0)
|
||||
@@ -115,10 +115,10 @@ func ApplyExpansions(steps []*Step, compose *ComposeRules, parser *Parser) ([]*S
|
||||
return nil, fmt.Errorf("map: %q has no template steps", rule.With)
|
||||
}
|
||||
|
||||
// Merge formula default vars with rule overrides (gt-8tmz.34)
|
||||
// Merge formula default vars with rule overrides
|
||||
vars := mergeVars(expFormula, rule.Vars)
|
||||
|
||||
// Find all matching steps (including nested children - gt-8tmz.33)
|
||||
// Find all matching steps (including nested children)
|
||||
// Rebuild stepMap to capture any changes from previous expansions
|
||||
stepMap = buildStepMap(result)
|
||||
var toExpand []*Step
|
||||
@@ -152,7 +152,7 @@ func ApplyExpansions(steps []*Step, compose *ComposeRules, parser *Parser) ([]*S
|
||||
}
|
||||
}
|
||||
|
||||
// Validate no duplicate step IDs after expansion (gt-8tmz.36)
|
||||
// Validate no duplicate step IDs after expansion
|
||||
if dups := findDuplicateStepIDs(result); len(dups) > 0 {
|
||||
return nil, fmt.Errorf("duplicate step IDs after expansion: %v", dups)
|
||||
}
|
||||
@@ -206,8 +206,8 @@ func expandStep(target *Step, template []*Step, depth int, vars map[string]strin
|
||||
Type: tmpl.Type,
|
||||
Priority: tmpl.Priority,
|
||||
Assignee: substituteVars(tmpl.Assignee, vars),
|
||||
SourceFormula: tmpl.SourceFormula, // Preserve source from template (gt-8tmz.18)
|
||||
SourceLocation: tmpl.SourceLocation, // Preserve source location (gt-8tmz.18)
|
||||
SourceFormula: tmpl.SourceFormula, // Preserve source from template
|
||||
SourceLocation: tmpl.SourceLocation, // Preserve source location
|
||||
}
|
||||
|
||||
// Substitute placeholders in labels
|
||||
@@ -361,7 +361,7 @@ func UpdateDependenciesForExpansion(steps []*Step, expandedID string, lastExpand
|
||||
return result
|
||||
}
|
||||
|
||||
// ApplyInlineExpansions applies Step.Expand fields to inline expansions (gt-8tmz.35).
|
||||
// ApplyInlineExpansions applies Step.Expand fields to inline expansions.
|
||||
// Steps with the Expand field set are replaced by the referenced expansion template.
|
||||
// The step's ExpandVars are passed as variable overrides to the expansion.
|
||||
//
|
||||
|
||||
@@ -186,15 +186,15 @@ type Step struct {
|
||||
// TODO(future): Not yet implemented in bd cook. Will integrate with bd-udsi gates.
|
||||
Gate *Gate `json:"gate,omitempty"`
|
||||
|
||||
// Loop defines iteration for this step (gt-8tmz.4).
|
||||
// Loop defines iteration for this step.
|
||||
// When set, the step becomes a container that expands its body.
|
||||
Loop *LoopSpec `json:"loop,omitempty"`
|
||||
|
||||
// OnComplete defines actions triggered when this step completes (gt-8tmz.8).
|
||||
// OnComplete defines actions triggered when this step completes.
|
||||
// Used for runtime expansion over step output (the for-each construct).
|
||||
OnComplete *OnCompleteSpec `json:"on_complete,omitempty"`
|
||||
|
||||
// Source tracing fields (gt-8tmz.18): track where this step came from.
|
||||
// Source tracing fields: track where this step came from.
|
||||
// These are set during parsing/transformation and copied to Issues during cooking.
|
||||
|
||||
// SourceFormula is the formula name where this step was defined.
|
||||
@@ -219,7 +219,7 @@ type Gate struct {
|
||||
Timeout string `json:"timeout,omitempty"`
|
||||
}
|
||||
|
||||
// LoopSpec defines iteration over a body of steps (gt-8tmz.4).
|
||||
// LoopSpec defines iteration over a body of steps.
|
||||
// One of Count, Until, or Range must be specified.
|
||||
type LoopSpec struct {
|
||||
// Count is the fixed number of iterations.
|
||||
@@ -234,7 +234,7 @@ type LoopSpec struct {
|
||||
// Required when Until is set, to prevent unbounded loops.
|
||||
Max int `json:"max,omitempty"`
|
||||
|
||||
// Range specifies a computed range for iteration (gt-8tmz.27).
|
||||
// Range specifies a computed range for iteration.
|
||||
// Format: "start..end" where start and end can be:
|
||||
// - Integers: "1..10"
|
||||
// - Expressions: "1..2^{disks}" (evaluated at cook time)
|
||||
@@ -242,7 +242,7 @@ type LoopSpec struct {
|
||||
// Supports: + - * / ^ (power) and parentheses.
|
||||
Range string `json:"range,omitempty"`
|
||||
|
||||
// Var is the variable name exposed to body steps (gt-8tmz.27).
|
||||
// Var is the variable name exposed to body steps.
|
||||
// For Range loops, this is set to the current iteration value.
|
||||
// Example: var: "move_num" with range: "1..7" exposes {move_num}=1,2,...,7
|
||||
Var string `json:"var,omitempty"`
|
||||
@@ -251,7 +251,7 @@ type LoopSpec struct {
|
||||
Body []*Step `json:"body"`
|
||||
}
|
||||
|
||||
// OnCompleteSpec defines actions triggered when a step completes (gt-8tmz.8).
|
||||
// OnCompleteSpec defines actions triggered when a step completes.
|
||||
// Used for runtime expansion over step output (the for-each construct).
|
||||
//
|
||||
// Example YAML:
|
||||
@@ -291,7 +291,7 @@ type OnCompleteSpec struct {
|
||||
Sequential bool `json:"sequential,omitempty"`
|
||||
}
|
||||
|
||||
// BranchRule defines parallel execution paths that rejoin (gt-8tmz.4).
|
||||
// BranchRule defines parallel execution paths that rejoin.
|
||||
// Creates a fork-join pattern: from -> [parallel steps] -> join.
|
||||
type BranchRule struct {
|
||||
// From is the step ID that precedes the parallel paths.
|
||||
@@ -307,7 +307,7 @@ type BranchRule struct {
|
||||
Join string `json:"join"`
|
||||
}
|
||||
|
||||
// GateRule defines a condition that must be satisfied before a step proceeds (gt-8tmz.4).
|
||||
// GateRule defines a condition that must be satisfied before a step proceeds.
|
||||
// Gates are evaluated at runtime by the patrol executor.
|
||||
type GateRule struct {
|
||||
// Before is the step ID that the gate applies to.
|
||||
@@ -335,11 +335,11 @@ type ComposeRules struct {
|
||||
// Each matching step is replaced by the expanded template steps.
|
||||
Map []*MapRule `json:"map,omitempty"`
|
||||
|
||||
// Branch defines fork-join parallel execution patterns (gt-8tmz.4).
|
||||
// Branch defines fork-join parallel execution patterns.
|
||||
// Each rule creates dependencies for parallel paths that rejoin.
|
||||
Branch []*BranchRule `json:"branch,omitempty"`
|
||||
|
||||
// Gate defines conditional waits before steps (gt-8tmz.4).
|
||||
// Gate defines conditional waits before steps.
|
||||
// Each rule adds a condition that must be satisfied at runtime.
|
||||
Gate []*GateRule `json:"gate,omitempty"`
|
||||
|
||||
@@ -534,20 +534,20 @@ func (f *Formula) Validate() error {
|
||||
errs = append(errs, fmt.Sprintf("steps[%d] (%s): depends_on references unknown step %q", i, step.ID, dep))
|
||||
}
|
||||
}
|
||||
// Validate needs field (bd-hr39) - same validation as depends_on
|
||||
// Validate needs field - same validation as depends_on
|
||||
for _, need := range step.Needs {
|
||||
if _, exists := stepIDLocations[need]; !exists {
|
||||
errs = append(errs, fmt.Sprintf("steps[%d] (%s): needs references unknown step %q", i, step.ID, need))
|
||||
}
|
||||
}
|
||||
// Validate waits_for field (bd-j4cr, gt-8tmz.38)
|
||||
// Validate waits_for field
|
||||
// Valid formats: "all-children", "any-children", "children-of(step-id)"
|
||||
if step.WaitsFor != "" {
|
||||
if err := validateWaitsFor(step.WaitsFor, stepIDLocations); err != nil {
|
||||
errs = append(errs, fmt.Sprintf("steps[%d] (%s): %s", i, step.ID, err.Error()))
|
||||
}
|
||||
}
|
||||
// Validate on_complete field (gt-8tmz.8) - runtime expansion
|
||||
// Validate on_complete field - runtime expansion
|
||||
if step.OnComplete != nil {
|
||||
validateOnComplete(step.OnComplete, &errs, fmt.Sprintf("steps[%d] (%s)", i, step.ID))
|
||||
}
|
||||
@@ -621,7 +621,7 @@ func collectChildIDs(children []*Step, idLocations map[string]string, errs *[]st
|
||||
}
|
||||
}
|
||||
|
||||
// WaitsForSpec holds the parsed waits_for field (gt-8tmz.38).
|
||||
// WaitsForSpec holds the parsed waits_for field.
|
||||
type WaitsForSpec struct {
|
||||
// Gate is the gate type: "all-children" or "any-children"
|
||||
Gate string
|
||||
@@ -630,7 +630,7 @@ type WaitsForSpec struct {
|
||||
SpawnerID string
|
||||
}
|
||||
|
||||
// ParseWaitsFor parses a waits_for value into its components (gt-8tmz.38).
|
||||
// ParseWaitsFor parses a waits_for value into its components.
|
||||
// Returns nil if the value is empty.
|
||||
func ParseWaitsFor(value string) *WaitsForSpec {
|
||||
if value == "" {
|
||||
@@ -655,7 +655,7 @@ func ParseWaitsFor(value string) *WaitsForSpec {
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateWaitsFor validates the waits_for field value (gt-8tmz.38).
|
||||
// validateWaitsFor validates the waits_for field value.
|
||||
// Valid formats:
|
||||
// - "all-children": wait for all dynamically-bonded children
|
||||
// - "any-children": wait for first child to complete
|
||||
@@ -690,19 +690,19 @@ func validateChildDependsOn(children []*Step, idLocations map[string]string, err
|
||||
*errs = append(*errs, fmt.Sprintf("%s (%s): depends_on references unknown step %q", childPrefix, child.ID, dep))
|
||||
}
|
||||
}
|
||||
// Validate needs field (bd-hr39)
|
||||
// Validate needs field
|
||||
for _, need := range child.Needs {
|
||||
if _, exists := idLocations[need]; !exists {
|
||||
*errs = append(*errs, fmt.Sprintf("%s (%s): needs references unknown step %q", childPrefix, child.ID, need))
|
||||
}
|
||||
}
|
||||
// Validate waits_for field (bd-j4cr, gt-8tmz.38)
|
||||
// Validate waits_for field
|
||||
if child.WaitsFor != "" {
|
||||
if err := validateWaitsFor(child.WaitsFor, idLocations); err != nil {
|
||||
*errs = append(*errs, fmt.Sprintf("%s (%s): %s", childPrefix, child.ID, err.Error()))
|
||||
}
|
||||
}
|
||||
// Validate on_complete field (gt-8tmz.8)
|
||||
// Validate on_complete field
|
||||
if child.OnComplete != nil {
|
||||
validateOnComplete(child.OnComplete, errs, fmt.Sprintf("%s (%s)", childPrefix, child.ID))
|
||||
}
|
||||
@@ -710,7 +710,7 @@ func validateChildDependsOn(children []*Step, idLocations map[string]string, err
|
||||
}
|
||||
}
|
||||
|
||||
// validateOnComplete validates an OnCompleteSpec (gt-8tmz.8).
|
||||
// validateOnComplete validates an OnCompleteSpec.
|
||||
func validateOnComplete(oc *OnCompleteSpec, errs *[]string, prefix string) {
|
||||
// Check that for_each and bond are both present or both absent
|
||||
if oc.ForEach != "" && oc.Bond == "" {
|
||||
|
||||
Reference in New Issue
Block a user