]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/cmd/go/main.go
libgo: update to Go1.14beta1
[thirdparty/gcc.git] / libgo / go / cmd / go / main.go
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/modcmd"
31 "cmd/go/internal/modfetch"
32 "cmd/go/internal/modget"
33 "cmd/go/internal/modload"
34 "cmd/go/internal/run"
35 "cmd/go/internal/test"
36 "cmd/go/internal/tool"
37 "cmd/go/internal/version"
38 "cmd/go/internal/vet"
39 "cmd/go/internal/work"
40 )
41
42 func init() {
43 base.Go.Commands = []*base.Command{
44 bug.CmdBug,
45 work.CmdBuild,
46 clean.CmdClean,
47 doc.CmdDoc,
48 envcmd.CmdEnv,
49 fix.CmdFix,
50 fmtcmd.CmdFmt,
51 generate.CmdGenerate,
52 modget.CmdGet,
53 work.CmdInstall,
54 list.CmdList,
55 modcmd.CmdMod,
56 run.CmdRun,
57 test.CmdTest,
58 tool.CmdTool,
59 version.CmdVersion,
60 vet.CmdVet,
61
62 help.HelpBuildmode,
63 help.HelpC,
64 help.HelpCache,
65 help.HelpEnvironment,
66 help.HelpFileType,
67 modload.HelpGoMod,
68 help.HelpGopath,
69 get.HelpGopathGet,
70 modfetch.HelpGoproxy,
71 help.HelpImportPath,
72 modload.HelpModules,
73 modget.HelpModuleGet,
74 modfetch.HelpModuleAuth,
75 modfetch.HelpModulePrivate,
76 help.HelpPackages,
77 test.HelpTestflag,
78 test.HelpTestfunc,
79 }
80 }
81
82 func main() {
83 _ = go11tag
84 flag.Usage = base.Usage
85 flag.Parse()
86 log.SetFlags(0)
87
88 args := flag.Args()
89 if len(args) < 1 {
90 base.Usage()
91 }
92
93 if args[0] == "get" || args[0] == "help" {
94 if !modload.WillBeEnabled() {
95 // Replace module-aware get with GOPATH get if appropriate.
96 *modget.CmdGet = *get.CmdGet
97 }
98 }
99
100 cfg.CmdName = args[0] // for error messages
101 if args[0] == "help" {
102 help.Help(os.Stdout, args[1:])
103 return
104 }
105
106 // Diagnose common mistake: GOPATH==GOROOT.
107 // This setting is equivalent to not setting GOPATH at all,
108 // which is not what most people want when they do it.
109 if gopath := cfg.BuildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) {
110 fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
111 } else {
112 for _, p := range filepath.SplitList(gopath) {
113 // Some GOPATHs have empty directory elements - ignore them.
114 // See issue 21928 for details.
115 if p == "" {
116 continue
117 }
118 // Note: using HasPrefix instead of Contains because a ~ can appear
119 // in the middle of directory elements, such as /tmp/git-1.8.2~rc3
120 // or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
121 if strings.HasPrefix(p, "~") {
122 fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
123 os.Exit(2)
124 }
125 if !filepath.IsAbs(p) {
126 if cfg.Getenv("GOPATH") == "" {
127 // We inferred $GOPATH from $HOME and did a bad job at it.
128 // Instead of dying, uninfer it.
129 cfg.BuildContext.GOPATH = ""
130 } else {
131 fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nFor more details see: 'go help gopath'\n", p)
132 os.Exit(2)
133 }
134 }
135 }
136 }
137
138 // For gccgo this is fine, carry on.
139 // Note that this check is imperfect as we have not yet parsed
140 // the -compiler flag.
141 if fi, err := os.Stat(cfg.GOROOT); err != nil || !fi.IsDir() && runtime.Compiler != "gccgo" {
142 fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", cfg.GOROOT)
143 os.Exit(2)
144 }
145
146 // Set environment (GOOS, GOARCH, etc) explicitly.
147 // In theory all the commands we invoke should have
148 // the same default computation of these as we do,
149 // but in practice there might be skew
150 // This makes sure we all agree.
151 cfg.OrigEnv = os.Environ()
152 cfg.CmdEnv = envcmd.MkEnv()
153 for _, env := range cfg.CmdEnv {
154 if os.Getenv(env.Name) != env.Value {
155 os.Setenv(env.Name, env.Value)
156 }
157 }
158
159 BigCmdLoop:
160 for bigCmd := base.Go; ; {
161 for _, cmd := range bigCmd.Commands {
162 if cmd.Name() != args[0] {
163 continue
164 }
165 if len(cmd.Commands) > 0 {
166 bigCmd = cmd
167 args = args[1:]
168 if len(args) == 0 {
169 help.PrintUsage(os.Stderr, bigCmd)
170 base.SetExitStatus(2)
171 base.Exit()
172 }
173 if args[0] == "help" {
174 // Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
175 help.Help(os.Stdout, append(strings.Split(cfg.CmdName, " "), args[1:]...))
176 return
177 }
178 cfg.CmdName += " " + args[0]
179 continue BigCmdLoop
180 }
181 if !cmd.Runnable() {
182 continue
183 }
184 cmd.Flag.Usage = func() { cmd.Usage() }
185 if cmd.CustomFlags {
186 args = args[1:]
187 } else {
188 base.SetFromGOFLAGS(cmd.Flag)
189 cmd.Flag.Parse(args[1:])
190 args = cmd.Flag.Args()
191 }
192 cmd.Run(cmd, args)
193 base.Exit()
194 return
195 }
196 helpArg := ""
197 if i := strings.LastIndex(cfg.CmdName, " "); i >= 0 {
198 helpArg = " " + cfg.CmdName[:i]
199 }
200 fmt.Fprintf(os.Stderr, "go %s: unknown command\nRun 'go help%s' for usage.\n", cfg.CmdName, helpArg)
201 base.SetExitStatus(2)
202 base.Exit()
203 }
204 }
205
206 func init() {
207 base.Usage = mainUsage
208 }
209
210 func mainUsage() {
211 help.PrintUsage(os.Stderr, base.Go)
212 os.Exit(2)
213 }