func Buildozer()

in edit/buildozer.go [1215:1316]


func Buildozer(opts *Options, args []string) int {
	if opts.OutWriter == nil {
		opts.OutWriter = os.Stdout
	}
	if opts.ErrWriter == nil {
		opts.ErrWriter = os.Stderr
	}
	commandsByFile := make(map[string][]commandsForTarget)
	if len(opts.CommandsFiles) > 0 {
		if err := appendCommandsFromFiles(opts, commandsByFile, args); err != nil {
			fmt.Fprintf(opts.ErrWriter, "error: %s\n", err)
			return 1
		}
	} else {
		if len(args) == 0 {
			Usage()
		}
		if err := appendCommands(opts, commandsByFile, args); err != nil {
			fmt.Fprintf(opts.ErrWriter, "error: %s\n", err)
			return 1
		}
	}

	numFiles := len(commandsByFile)
	if opts.Parallelism > 0 {
		runtime.GOMAXPROCS(opts.Parallelism)
	}
	results := make(chan *rewriteResult, numFiles)
	data := make(chan commandsForFile)

	if opts.NumIO < 1 {
		fmt.Fprintf(opts.ErrWriter, "NumIO must be at least 1; got %d (are you using `NewOpts`?)\n", opts.NumIO)
		return 1
	}
	for i := 0; i < opts.NumIO; i++ {
		go func(results chan *rewriteResult, data chan commandsForFile) {
			for commandsForFile := range data {
				results <- rewrite(opts, commandsForFile)
			}
		}(results, data)
	}

	for file, commands := range commandsByFile {
		data <- commandsForFile{file, commands}
	}
	close(data)
	records := []*apipb.Output_Record{}
	var hasErrors bool
	var fileModified bool
	for i := 0; i < numFiles; i++ {
		fileResults := <-results
		if fileResults == nil {
			continue
		}
		hasErrors = hasErrors || len(fileResults.errs) > 0
		fileModified = fileModified || fileResults.modified
		for _, err := range fileResults.errs {
			fmt.Fprintf(opts.ErrWriter, "%s: %s\n", fileResults.file, err)
		}
		if fileResults.modified && !opts.Quiet {
			fmt.Fprintf(opts.ErrWriter, "fixed %s\n", fileResults.file)
		}
		if fileResults.records != nil {
			records = append(records, fileResults.records...)
		}
	}

	if opts.IsPrintingProto {
		data, err := proto.Marshal(&apipb.Output{Records: records})
		if err != nil {
			log.Fatal("marshaling error: ", err)
		}
		fmt.Fprintf(opts.OutWriter, "%s", data)
	} else {
		for _, record := range records {
			printRecord(opts.OutWriter, record)
		}
	}

	if hasErrors {
		return 2
	}
	if fileModified || opts.Stdout {
		return 0
	}
	// The file is not modified, check if there were any non-readonly commands
	nonReadonlyCommands := false
	for _, commandsByTarget := range commandsByFile {
		for _, commands := range commandsByTarget {
			for _, command := range commands.commands {
				if _, ok := readonlyCommands[command.tokens[0]]; !ok {
					nonReadonlyCommands = true
					break
				}
			}
		}
	}
	if nonReadonlyCommands {
		return 3
	}
	return 0
}