func processFile()

in buildifier/buildifier.go [310:411]


func processFile(filename string, data []byte, inputType, lint string, warningsList *[]string, displayFileNames bool, tf *utils.TempFile) (*utils.FileDiagnostics, int) {
	var exitCode int

	displayFilename := filename
	if *filePath != "" {
		displayFilename = *filePath
	}

	parser := utils.GetParser(inputType)

	f, err := parser(displayFilename, 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 utils.InvalidFileDiagnostics(displayFilename), exitCode
	}

	if absoluteFilename, err := filepath.Abs(displayFilename); err == nil {
		f.WorkspaceRoot, f.Pkg, f.Label = wspace.SplitFilePath(absoluteFilename)
	}

	warnings := utils.Lint(f, lint, warningsList, *vflag)
	if len(warnings) > 0 {
		exitCode = 4
	}
	fileDiagnostics := utils.NewFileDiagnostics(f.DisplayPath(), warnings)

	ndata := build.Format(f)

	switch *mode {
	case "check":
		// check mode: print names of files that need formatting.
		if !bytes.Equal(data, ndata) {
			fileDiagnostics.Formatted = false
			return fileDiagnostics, 4
		}

	case "diff":
		// diff mode: run diff on old and new.
		if bytes.Equal(data, ndata) {
			return fileDiagnostics, exitCode
		}
		outfile, err := tf.WriteTemp(ndata)
		if err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: %v\n", err)
			return fileDiagnostics, 3
		}
		infile := filename
		if filename == "" {
			// data was read from standard filename.
			// Write it to a temporary file so diff can read it.
			infile, err = tf.WriteTemp(data)
			if err != nil {
				fmt.Fprintf(os.Stderr, "buildifier: %v\n", err)
				return fileDiagnostics, 3
			}
		}
		if displayFileNames {
			fmt.Fprintf(os.Stderr, "%v:\n", f.DisplayPath())
		}
		if err := diff.Show(infile, outfile); err != nil {
			fmt.Fprintf(os.Stderr, "%v\n", err)
			return fileDiagnostics, 4
		}

	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)

	case "fix":
		// fix mode: update files in place as needed.
		if bytes.Equal(data, ndata) {
			return fileDiagnostics, exitCode
		}

		err := ioutil.WriteFile(filename, ndata, 0666)
		if err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: %s\n", err)
			return fileDiagnostics, 3
		}

		if *vflag {
			fmt.Fprintf(os.Stderr, "fixed %s\n", f.DisplayPath())
		}
	case "print_if_changed":
		if bytes.Equal(data, ndata) {
			return fileDiagnostics, exitCode
		}

		if _, err := os.Stdout.Write(ndata); err != nil {
			fmt.Fprintf(os.Stderr, "buildifier: error writing output: %v\n", err)
			return fileDiagnostics, 3
		}
	}
	return fileDiagnostics, exitCode
}