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 }