func canonicalize(t *testing.T, filename, content string) string { f, err := bzl.Parse(filename, []byte(content)) if err != nil { t.Fatalf("bzl.Parse(%q, %q) failed with %v; want success", filename, content, err) } return string(bzl.Format(f)) }
func reconcile(fname string, rules []bzl.Expr) (*bzl.File, error) { buf, err := ioutil.ReadFile(fname) if err != nil && !os.IsNotExist(err) { return nil, err } orig := new(bzl.File) if len(buf) > 0 { orig, err = bzl.Parse(fname, buf) if err != nil { return nil, err } } newfile := *orig // TODO(yugui) Respect existing data, visibility and other attributes; // comments on rules; and their positions. newfile.DelRules("go_library", "") newfile.DelRules("go_binary", "") newfile.DelRules("go_test", "") newfile.Stmt = append(newfile.Stmt, rules...) return &newfile, nil }
// processFile processes a single file containing data. // It has been read from filename and should be written back if fixing. func processFile(filename string, data []byte) { defer func() { if err := recover(); err != nil { fmt.Fprintf(os.Stderr, "buildifier: %s: internal error: %v\n", filename, err) exitCode = 3 } }() f, err := build.Parse(filename, data) if err != nil { // Do not use buildifier: prefix on this error. // Since it is a parse error, it begins with file:line: // and we want that to be the first thing in the error. fmt.Fprintf(os.Stderr, "%v\n", err) if exitCode < 1 { exitCode = 1 } return } if *path != "" { f.Path = *path } beforeRewrite := build.Format(f) var info build.RewriteInfo build.Rewrite(f, &info) ndata := build.Format(f) switch *mode { case "check": // check mode: print names of files that need formatting. if !bytes.Equal(data, ndata) { // Print: // name # list of what changed reformat := "" if !bytes.Equal(data, beforeRewrite) { reformat = " reformat" } log := "" if len(info.Log) > 0 && *showlog { sort.Strings(info.Log) var uniq []string last := "" for _, s := range info.Log { if s != last { last = s uniq = append(uniq, s) } } log = " " + strings.Join(uniq, " ") } fmt.Printf("%s #%s %s%s\n", filename, reformat, &info, log) } return case "diff": // diff mode: run diff on old and new. if bytes.Equal(data, ndata) { return } outfile, err := writeTemp(ndata) if err != nil { fmt.Fprintf(os.Stderr, "buildifier: %v\n", err) exitCode = 3 return } infile := filename if filename == "" { // data was read from standard filename. // Write it to a temporary file so diff can read it. infile, err = writeTemp(data) if err != nil { fmt.Fprintf(os.Stderr, "buildifier: %v\n", err) exitCode = 3 return } } diff.Show(infile, outfile) case "pipe": // pipe mode - reading from stdin, writing to stdout. // ("pipe" is not from the command line; it is set above in main.) os.Stdout.Write(ndata) return case "fix": // fix mode: update files in place as needed. if bytes.Equal(data, ndata) { return } err := ioutil.WriteFile(filename, ndata, 0666) if err != nil { fmt.Fprintf(os.Stderr, "buildifier: %s\n", err) exitCode = 3 return } if *vflag { fmt.Fprintf(os.Stderr, "fixed %s\n", filename) } } }