github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/cmd/internal/diff/diff.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package diff implements a Diff function that compare two inputs
     6  // using the 'diff' tool.
     7  package diff
     8  
     9  import (
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"runtime"
    14  )
    15  
    16  // Returns diff of two arrays of bytes in diff tool format.
    17  func Diff(prefix string, b1, b2 []byte) ([]byte, error) {
    18  	f1, err := writeTempFile(prefix, b1)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	defer os.Remove(f1)
    23  
    24  	f2, err := writeTempFile(prefix, b2)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	defer os.Remove(f2)
    29  
    30  	cmd := "diff"
    31  	if runtime.GOOS == "plan9" {
    32  		cmd = "/bin/ape/diff"
    33  	}
    34  
    35  	data, err := exec.Command(cmd, "-u", f1, f2).CombinedOutput()
    36  	if len(data) > 0 {
    37  		// diff exits with a non-zero status when the files don't match.
    38  		// Ignore that failure as long as we get output.
    39  		err = nil
    40  	}
    41  	return data, err
    42  }
    43  
    44  func writeTempFile(prefix string, data []byte) (string, error) {
    45  	file, err := ioutil.TempFile("", prefix)
    46  	if err != nil {
    47  		return "", err
    48  	}
    49  	_, err = file.Write(data)
    50  	if err1 := file.Close(); err == nil {
    51  		err = err1
    52  	}
    53  	if err != nil {
    54  		os.Remove(file.Name())
    55  		return "", err
    56  	}
    57  	return file.Name(), nil
    58  }