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  }