github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/fmtcmd/fmt.go (about) 1 // Copyright 2011 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 fmtcmd implements the ``go fmt'' command. 6 package fmtcmd 7 8 import ( 9 "fmt" 10 "os" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "sync" 15 16 "github.com/gagliardetto/golang-go/cmd/go/not-internal/base" 17 "github.com/gagliardetto/golang-go/cmd/go/not-internal/cfg" 18 "github.com/gagliardetto/golang-go/cmd/go/not-internal/load" 19 "github.com/gagliardetto/golang-go/cmd/go/not-internal/modload" 20 "github.com/gagliardetto/golang-go/cmd/go/not-internal/str" 21 ) 22 23 func init() { 24 base.AddBuildFlagsNX(&CmdFmt.Flag) 25 base.AddLoadFlags(&CmdFmt.Flag) 26 } 27 28 var CmdFmt = &base.Command{ 29 Run: runFmt, 30 UsageLine: "go fmt [-n] [-x] [packages]", 31 Short: "gofmt (reformat) package sources", 32 Long: ` 33 Fmt runs the command 'gofmt -l -w' on the packages named 34 by the import paths. It prints the names of the files that are modified. 35 36 For more about gofmt, see 'go doc cmd/gofmt'. 37 For more about specifying packages, see 'go help packages'. 38 39 The -n flag prints commands that would be executed. 40 The -x flag prints commands as they are executed. 41 42 The -mod flag's value sets which module download mode 43 to use: readonly or vendor. See 'go help modules' for more. 44 45 To run gofmt with specific options, run gofmt itself. 46 47 See also: go fix, go vet. 48 `, 49 } 50 51 func runFmt(cmd *base.Command, args []string) { 52 printed := false 53 gofmt := gofmtPath() 54 procs := runtime.GOMAXPROCS(0) 55 var wg sync.WaitGroup 56 wg.Add(procs) 57 fileC := make(chan string, 2*procs) 58 for i := 0; i < procs; i++ { 59 go func() { 60 defer wg.Done() 61 for file := range fileC { 62 base.Run(str.StringList(gofmt, "-l", "-w", file)) 63 } 64 }() 65 } 66 for _, pkg := range load.PackagesAndErrors(args) { 67 if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main { 68 if !printed { 69 fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n") 70 printed = true 71 } 72 continue 73 } 74 if pkg.Error != nil { 75 if strings.HasPrefix(pkg.Error.Err.Error(), "build constraints exclude all Go files") { 76 // Skip this error, as we will format 77 // all files regardless. 78 } else { 79 base.Errorf("can't load package: %s", pkg.Error) 80 continue 81 } 82 } 83 // Use pkg.gofiles instead of pkg.Dir so that 84 // the command only applies to this package, 85 // not to packages in subdirectories. 86 files := base.RelPaths(pkg.InternalAllGoFiles()) 87 for _, file := range files { 88 fileC <- file 89 } 90 } 91 close(fileC) 92 wg.Wait() 93 } 94 95 func gofmtPath() string { 96 gofmt := "gofmt" 97 if base.ToolIsWindows { 98 gofmt += base.ToolWindowsExtension 99 } 100 101 gofmtPath := filepath.Join(cfg.GOBIN, gofmt) 102 if _, err := os.Stat(gofmtPath); err == nil { 103 return gofmtPath 104 } 105 106 gofmtPath = filepath.Join(cfg.GOROOT, "bin", gofmt) 107 if _, err := os.Stat(gofmtPath); err == nil { 108 return gofmtPath 109 } 110 111 // fallback to looking for gofmt in $PATH 112 return "gofmt" 113 }