github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/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  	"zdebug"
    18  
    19  	"cmd/go/internal/base"
    20  	"cmd/go/internal/bug"
    21  	"cmd/go/internal/cfg"
    22  	"cmd/go/internal/clean"
    23  	"cmd/go/internal/doc"
    24  	"cmd/go/internal/envcmd"
    25  	"cmd/go/internal/fix"
    26  	"cmd/go/internal/fmtcmd"
    27  	"cmd/go/internal/generate"
    28  	"cmd/go/internal/get"
    29  	"cmd/go/internal/help"
    30  	"cmd/go/internal/list"
    31  	"cmd/go/internal/modcmd"
    32  	"cmd/go/internal/modfetch"
    33  	"cmd/go/internal/modget"
    34  	"cmd/go/internal/modload"
    35  	"cmd/go/internal/run"
    36  	"cmd/go/internal/test"
    37  	"cmd/go/internal/tool"
    38  	"cmd/go/internal/version"
    39  	"cmd/go/internal/vet"
    40  	"cmd/go/internal/work"
    41  )
    42  
    43  func init() {
    44  	zdebug.T("%v", "-----go------")
    45  	base.Go.Commands = []*base.Command{
    46  		bug.CmdBug,
    47  		work.CmdBuild,
    48  		clean.CmdClean,
    49  		doc.CmdDoc,
    50  		envcmd.CmdEnv,
    51  		fix.CmdFix,
    52  		fmtcmd.CmdFmt,
    53  		generate.CmdGenerate,
    54  		get.CmdGet,
    55  		work.CmdInstall,
    56  		list.CmdList,
    57  		modcmd.CmdMod,
    58  		run.CmdRun,
    59  		test.CmdTest,
    60  		tool.CmdTool,
    61  		version.CmdVersion,
    62  		vet.CmdVet,
    63  
    64  		help.HelpBuildmode,
    65  		help.HelpC,
    66  		help.HelpCache,
    67  		help.HelpEnvironment,
    68  		help.HelpFileType,
    69  		modload.HelpGoMod,
    70  		help.HelpGopath,
    71  		get.HelpGopathGet,
    72  		modfetch.HelpGoproxy,
    73  		help.HelpImportPath,
    74  		modload.HelpModules,
    75  		modget.HelpModuleGet,
    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 modload.MustUseModules {
    94  		// If running with modules force-enabled, change get now to change help message.
    95  		*get.CmdGet = *modget.CmdGet
    96  	}
    97  
    98  	if args[0] == "get" || args[0] == "help" {
    99  		// Replace get with module-aware get if appropriate.
   100  		// Note that if MustUseModules is true, this happened already above,
   101  		// but no harm in doing it again.
   102  		if modload.Init(); modload.Enabled() {
   103  			*get.CmdGet = *modget.CmdGet
   104  		}
   105  	}
   106  
   107  	cfg.CmdName = args[0] // for error messages
   108  	if args[0] == "help" {
   109  		help.Help(os.Stdout, args[1:])
   110  		return
   111  	}
   112  
   113  	// Diagnose common mistake: GOPATH==GOROOT.
   114  	// This setting is equivalent to not setting GOPATH at all,
   115  	// which is not what most people want when they do it.
   116  	if gopath := cfg.BuildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) {
   117  		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
   118  	} else {
   119  		for _, p := range filepath.SplitList(gopath) {
   120  			// Some GOPATHs have empty directory elements - ignore them.
   121  			// See issue 21928 for details.
   122  			if p == "" {
   123  				continue
   124  			}
   125  			// Note: using HasPrefix instead of Contains because a ~ can appear
   126  			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
   127  			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
   128  			if strings.HasPrefix(p, "~") {
   129  				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
   130  				os.Exit(2)
   131  			}
   132  			if !filepath.IsAbs(p) {
   133  				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nFor more details see: 'go help gopath'\n", p)
   134  				os.Exit(2)
   135  			}
   136  		}
   137  	}
   138  
   139  	if fi, err := os.Stat(cfg.GOROOT); err != nil || !fi.IsDir() {
   140  		fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", cfg.GOROOT)
   141  		os.Exit(2)
   142  	}
   143  
   144  	// TODO(rsc): Remove all these helper prints in Go 1.12.
   145  	switch args[0] {
   146  	case "mod":
   147  		if len(args) >= 2 {
   148  			flag := args[1]
   149  			if strings.HasPrefix(flag, "--") {
   150  				flag = flag[1:]
   151  			}
   152  			if i := strings.Index(flag, "="); i >= 0 {
   153  				flag = flag[:i]
   154  			}
   155  			switch flag {
   156  			case "-sync", "-fix":
   157  				fmt.Fprintf(os.Stderr, "go: go mod %s is now go mod tidy\n", flag)
   158  				os.Exit(2)
   159  			case "-init", "-graph", "-vendor", "-verify":
   160  				fmt.Fprintf(os.Stderr, "go: go mod %s is now go mod %s\n", flag, flag[1:])
   161  				os.Exit(2)
   162  			case "-fmt", "-json", "-module", "-require", "-droprequire", "-replace", "-dropreplace", "-exclude", "-dropexclude":
   163  				fmt.Fprintf(os.Stderr, "go: go mod %s is now go mod edit %s\n", flag, flag)
   164  				os.Exit(2)
   165  			}
   166  		}
   167  	case "vendor":
   168  		fmt.Fprintf(os.Stderr, "go: vgo vendor is now go mod vendor\n")
   169  		os.Exit(2)
   170  	case "verify":
   171  		fmt.Fprintf(os.Stderr, "go: vgo verify is now go mod verify\n")
   172  		os.Exit(2)
   173  	}
   174  
   175  	// Set environment (GOOS, GOARCH, etc) explicitly.
   176  	// In theory all the commands we invoke should have
   177  	// the same default computation of these as we do,
   178  	// but in practice there might be skew
   179  	// This makes sure we all agree.
   180  	cfg.OrigEnv = os.Environ()
   181  	cfg.CmdEnv = envcmd.MkEnv()
   182  	for _, env := range cfg.CmdEnv {
   183  		if os.Getenv(env.Name) != env.Value {
   184  			os.Setenv(env.Name, env.Value)
   185  		}
   186  	}
   187  
   188  BigCmdLoop:
   189  	for bigCmd := base.Go; ; {
   190  		for _, cmd := range bigCmd.Commands {
   191  			if cmd.Name() != args[0] {
   192  				continue
   193  			}
   194  			if len(cmd.Commands) > 0 {
   195  				bigCmd = cmd
   196  				args = args[1:]
   197  				if len(args) == 0 {
   198  					help.PrintUsage(os.Stderr, bigCmd)
   199  					base.SetExitStatus(2)
   200  					base.Exit()
   201  				}
   202  				if args[0] == "help" {
   203  					// Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
   204  					help.Help(os.Stdout, append(strings.Split(cfg.CmdName, " "), args[1:]...))
   205  					return
   206  				}
   207  				cfg.CmdName += " " + args[0]
   208  				continue BigCmdLoop
   209  			}
   210  			if !cmd.Runnable() {
   211  				continue
   212  			}
   213  			cmd.Flag.Usage = func() { cmd.Usage() }
   214  			if cmd.CustomFlags {
   215  				args = args[1:]
   216  			} else {
   217  				base.SetFromGOFLAGS(cmd.Flag)
   218  				cmd.Flag.Parse(args[1:])
   219  				args = cmd.Flag.Args()
   220  			}
   221  			cmd.Run(cmd, args)
   222  			base.Exit()
   223  			return
   224  		}
   225  		helpArg := ""
   226  		if i := strings.LastIndex(cfg.CmdName, " "); i >= 0 {
   227  			helpArg = " " + cfg.CmdName[:i]
   228  		}
   229  		fmt.Fprintf(os.Stderr, "go %s: unknown command\nRun 'go help%s' for usage.\n", cfg.CmdName, helpArg)
   230  		base.SetExitStatus(2)
   231  		base.Exit()
   232  	}
   233  }
   234  
   235  func init() {
   236  	base.Usage = mainUsage
   237  }
   238  
   239  func mainUsage() {
   240  	help.PrintUsage(os.Stderr, base.Go)
   241  	os.Exit(2)
   242  }