get.porter.sh/porter@v1.3.0/pkg/exec/builder/output_regex.go (about)

     1  package builder
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"get.porter.sh/porter/pkg/runtime"
    10  	"get.porter.sh/porter/pkg/tracing"
    11  )
    12  
    13  type OutputRegex interface {
    14  	Output
    15  	GetRegex() string
    16  }
    17  
    18  // ProcessRegexOutputs looks through the outputs for any that implement the OutputRegex,
    19  // applies the regular expression to the output buffer and extracts their output.
    20  func ProcessRegexOutputs(ctx context.Context, cfg runtime.RuntimeConfig, step StepWithOutputs, stdout string) error {
    21  	_, span := tracing.StartSpan(ctx)
    22  	defer span.EndSpan()
    23  
    24  	outputs := step.GetOutputs()
    25  
    26  	if len(outputs) == 0 {
    27  		return nil
    28  	}
    29  
    30  	for _, o := range outputs {
    31  		output, ok := o.(OutputRegex)
    32  		if !ok {
    33  			continue
    34  		}
    35  
    36  		outputName := output.GetName()
    37  		outputRegex := output.GetRegex()
    38  		if outputRegex == "" {
    39  			continue
    40  		}
    41  
    42  		span.Debugf("Processing regex output %s...", outputName)
    43  
    44  		r, err := regexp.Compile(outputRegex)
    45  		if err != nil {
    46  			return span.Error(fmt.Errorf("invalid regular expression %q for output %q: %w", outputRegex, outputName, err))
    47  		}
    48  
    49  		// Find every submatch / capture and put it on its own line in the output file
    50  		results := r.FindAllStringSubmatch(stdout, -1)
    51  		var matches []string
    52  		for _, result := range results {
    53  			if len(result) > 1 { // Skip the first element which is the full match, we only want the capture groups
    54  				matches = append(matches, result[1:]...)
    55  			}
    56  		}
    57  		value := strings.Join(matches, "\n")
    58  		err = cfg.WriteMixinOutputToFile(outputName, []byte(value))
    59  		if err != nil {
    60  			return span.Error(fmt.Errorf("error writing mixin output for %q: %w", outputName, err))
    61  		}
    62  	}
    63  
    64  	return nil
    65  }