github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/ensure_step.go (about) 1 package exec 2 3 import ( 4 "context" 5 6 "github.com/hashicorp/go-multierror" 7 ) 8 9 // EnsureStep will run one step, and then a second step regardless of whether 10 // the first step fails or errors. 11 type EnsureStep struct { 12 step Step 13 hook Step 14 } 15 16 // Ensure constructs an EnsureStep. 17 func Ensure(step Step, hook Step) EnsureStep { 18 return EnsureStep{ 19 step: step, 20 hook: hook, 21 } 22 } 23 24 // Run will call Run on the first step, wait for it to complete, and then call 25 // Run on the second step, regardless of whether the first step failed or 26 // errored. 27 // 28 // If the first step or the second step errors, an aggregate of their errors is 29 // returned. 30 func (o EnsureStep) Run(ctx context.Context, state RunState) (bool, error) { 31 var errors error 32 33 originalOk, originalErr := o.step.Run(ctx, state) 34 if originalErr != nil { 35 errors = multierror.Append(errors, originalErr) 36 } 37 38 hookCtx := ctx 39 if ctx.Err() != nil { 40 // prevent hook from being immediately canceled 41 hookCtx = context.Background() 42 } 43 44 hookOk, hookErr := o.hook.Run(hookCtx, state) 45 if hookErr != nil { 46 errors = multierror.Append(errors, hookErr) 47 } 48 49 if ctx.Err() != nil { 50 return false, ctx.Err() 51 } 52 53 if errors != nil { 54 return false, errors 55 } 56 57 return originalOk && hookOk, nil 58 }