github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/cmd/go/main.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 //go:generate ./mkalldocs.sh 6 7 package main 8 9 import ( 10 "flag" 11 "fmt" 12 "log" 13 "os" 14 "path/filepath" 15 "runtime" 16 "strings" 17 18 "cmd/go/internal/base" 19 "cmd/go/internal/bug" 20 "cmd/go/internal/cfg" 21 "cmd/go/internal/clean" 22 "cmd/go/internal/doc" 23 "cmd/go/internal/envcmd" 24 "cmd/go/internal/fix" 25 "cmd/go/internal/fmtcmd" 26 "cmd/go/internal/generate" 27 "cmd/go/internal/get" 28 "cmd/go/internal/help" 29 "cmd/go/internal/list" 30 "cmd/go/internal/run" 31 "cmd/go/internal/test" 32 "cmd/go/internal/tool" 33 "cmd/go/internal/version" 34 "cmd/go/internal/vet" 35 "cmd/go/internal/work" 36 ) 37 38 func init() { 39 base.Commands = []*base.Command{ 40 work.CmdBuild, 41 clean.CmdClean, 42 doc.CmdDoc, 43 envcmd.CmdEnv, 44 bug.CmdBug, 45 fix.CmdFix, 46 fmtcmd.CmdFmt, 47 generate.CmdGenerate, 48 get.CmdGet, 49 work.CmdInstall, 50 list.CmdList, 51 run.CmdRun, 52 test.CmdTest, 53 tool.CmdTool, 54 version.CmdVersion, 55 vet.CmdVet, 56 57 help.HelpC, 58 help.HelpBuildmode, 59 help.HelpFileType, 60 help.HelpGopath, 61 help.HelpEnvironment, 62 help.HelpImportPath, 63 help.HelpPackages, 64 test.HelpTestflag, 65 test.HelpTestfunc, 66 } 67 } 68 69 func main() { 70 _ = go11tag 71 flag.Usage = base.Usage 72 flag.Parse() 73 log.SetFlags(0) 74 75 args := flag.Args() 76 if len(args) < 1 { 77 base.Usage() 78 } 79 80 if args[0] == "help" { 81 help.Help(args[1:]) 82 return 83 } 84 85 // Diagnose common mistake: GOPATH==GOROOT. 86 // This setting is equivalent to not setting GOPATH at all, 87 // which is not what most people want when they do it. 88 if gopath := cfg.BuildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) { 89 fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath) 90 } else { 91 for _, p := range filepath.SplitList(gopath) { 92 // Some GOPATHs have empty directory elements - ignore them. 93 // See issue 21928 for details. 94 if p == "" { 95 continue 96 } 97 // Note: using HasPrefix instead of Contains because a ~ can appear 98 // in the middle of directory elements, such as /tmp/git-1.8.2~rc3 99 // or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell. 100 if strings.HasPrefix(p, "~") { 101 fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p) 102 os.Exit(2) 103 } 104 if !filepath.IsAbs(p) { 105 fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nFor more details see: 'go help gopath'\n", p) 106 os.Exit(2) 107 } 108 } 109 } 110 111 if fi, err := os.Stat(cfg.GOROOT); err != nil || !fi.IsDir() { 112 fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", cfg.GOROOT) 113 os.Exit(2) 114 } 115 116 // Set environment (GOOS, GOARCH, etc) explicitly. 117 // In theory all the commands we invoke should have 118 // the same default computation of these as we do, 119 // but in practice there might be skew 120 // This makes sure we all agree. 121 cfg.OrigEnv = os.Environ() 122 cfg.CmdEnv = envcmd.MkEnv() 123 for _, env := range cfg.CmdEnv { 124 if os.Getenv(env.Name) != env.Value { 125 os.Setenv(env.Name, env.Value) 126 } 127 } 128 129 for _, cmd := range base.Commands { 130 if cmd.Name() == args[0] && cmd.Runnable() { 131 cmd.Flag.Usage = func() { cmd.Usage() } 132 if cmd.CustomFlags { 133 args = args[1:] 134 } else { 135 cmd.Flag.Parse(args[1:]) 136 args = cmd.Flag.Args() 137 } 138 cmd.Run(cmd, args) 139 base.Exit() 140 return 141 } 142 } 143 144 fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0]) 145 base.SetExitStatus(2) 146 base.Exit() 147 } 148 149 func init() { 150 base.Usage = mainUsage 151 } 152 153 func mainUsage() { 154 // special case "go test -h" 155 if len(os.Args) > 1 && os.Args[1] == "test" { 156 test.Usage() 157 } 158 help.PrintUsage(os.Stderr) 159 os.Exit(2) 160 }