github.com/hlts2/go@v0.0.0-20170904000733-812b34efaed8/src/cmd/go/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 "os" 10 "path/filepath" 11 "runtime" 12 "sync" 13 14 "cmd/go/internal/base" 15 "cmd/go/internal/cfg" 16 "cmd/go/internal/load" 17 "cmd/go/internal/str" 18 ) 19 20 func init() { 21 base.AddBuildFlagsNX(&CmdFmt.Flag) 22 } 23 24 var CmdFmt = &base.Command{ 25 Run: runFmt, 26 UsageLine: "fmt [-n] [-x] [packages]", 27 Short: "run gofmt on package sources", 28 Long: ` 29 Fmt runs the command 'gofmt -l -w' on the packages named 30 by the import paths. It prints the names of the files that are modified. 31 32 For more about gofmt, see 'go doc cmd/gofmt'. 33 For more about specifying packages, see 'go help packages'. 34 35 The -n flag prints commands that would be executed. 36 The -x flag prints commands as they are executed. 37 38 To run gofmt with specific options, run gofmt itself. 39 40 See also: go fix, go vet. 41 `, 42 } 43 44 func runFmt(cmd *base.Command, args []string) { 45 gofmt := gofmtPath() 46 procs := runtime.GOMAXPROCS(0) 47 var wg sync.WaitGroup 48 wg.Add(procs) 49 fileC := make(chan string, 2*procs) 50 for i := 0; i < procs; i++ { 51 go func() { 52 defer wg.Done() 53 for file := range fileC { 54 base.Run(str.StringList(gofmt, "-l", "-w", file)) 55 } 56 }() 57 } 58 for _, pkg := range load.Packages(args) { 59 // Use pkg.gofiles instead of pkg.Dir so that 60 // the command only applies to this package, 61 // not to packages in subdirectories. 62 files := base.FilterDotUnderscoreFiles(base.RelPaths(pkg.Internal.AllGoFiles)) 63 for _, file := range files { 64 fileC <- file 65 } 66 } 67 close(fileC) 68 wg.Wait() 69 } 70 71 func gofmtPath() string { 72 gofmt := "gofmt" 73 if base.ToolIsWindows { 74 gofmt += base.ToolWindowsExtension 75 } 76 77 gofmtPath := filepath.Join(cfg.GOBIN, gofmt) 78 if _, err := os.Stat(gofmtPath); err == nil { 79 return gofmtPath 80 } 81 82 gofmtPath = filepath.Join(cfg.GOROOT, "bin", gofmt) 83 if _, err := os.Stat(gofmtPath); err == nil { 84 return gofmtPath 85 } 86 87 // fallback to looking for gofmt in $PATH 88 return "gofmt" 89 }