github.com/chainguard-dev/yam@v0.0.7/pkg/yam/diff.go (about) 1 package yam 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "os/exec" 8 ) 9 10 type DiffHandler func(want, got []byte) error 11 12 func ExecDiff(want, got []byte) error { 13 handlerOutput := os.Stderr 14 15 tempWant, err := os.CreateTemp("", "want-*") 16 if err != nil { 17 return err 18 } 19 defer os.Remove(tempWant.Name()) 20 21 tempGot, err := os.CreateTemp("", "got-*") 22 if err != nil { 23 return err 24 } 25 defer os.Remove(tempGot.Name()) 26 27 _, err = tempWant.Write(want) 28 if err != nil { 29 return err 30 } 31 32 _, err = tempGot.Write(got) 33 if err != nil { 34 return err 35 } 36 37 const command = "diff" 38 _, err = exec.LookPath(command) 39 if err != nil { 40 return fmt.Errorf("unable to execute diff command: %w", err) 41 } 42 43 cmd := exec.Command( 44 command, 45 "-U", 46 "5", 47 "--label", 48 "want", 49 "--label", 50 "got", 51 tempWant.Name(), 52 tempGot.Name(), 53 ) 54 cmd.Stdout = handlerOutput 55 cmd.Stderr = handlerOutput 56 57 err = cmd.Run() 58 if err != nil { 59 var exitError *exec.ExitError 60 if errors.As(err, &exitError) { 61 if exitError.ExitCode() == 1 { 62 // that's expected for `diff` when there's a diff! 63 64 fmt.Fprint(handlerOutput, "\n") // for gap between diffs; useful if diffing multiple files. 65 66 return nil 67 } 68 } 69 70 return fmt.Errorf("error executing diff command %q: %w", cmd, err) 71 } 72 73 return nil 74 }