package edit import ( "bytes" "fmt" "os" "os/exec" "github.com/bazelbuild/buildtools/build" ) type defaultBuildifier struct{} // buildify formats the build file f. // Runs opts.Buildifier if it's non-empty, otherwise uses built-in formatter. // opts.Buildifier is useful to force consistency with other tools that call Buildifier. func (b *defaultBuildifier) Buildify(opts *Options, f *build.File) ([]byte, error) { if opts.Buildifier == "" { // Current AST may be not entirely correct, e.g. it may contain Ident which // value is a chunk of code, like "f(x)". The AST should be printed and // re-read to parse such expressions correctly. contents := build.Format(f) newF, err := build.Parse(f.Path, contents) if err != nil { return nil, err } return build.Format(newF), nil } cmd := exec.Command(opts.Buildifier, "--type=build") data := build.Format(f) cmd.Stdin = bytes.NewBuffer(data) stdout := bytes.NewBuffer(nil) stderr := bytes.NewBuffer(nil) cmd.Stdout = stdout cmd.Stderr = stderr cmd.Env = append( os.Environ(), // Custom environment variables ) err := cmd.Run() if stderr.Len() > 0 { return nil, fmt.Errorf("%s", stderr.Bytes()) } if err != nil { return nil, err } return stdout.Bytes(), nil }