github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/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  			// Note: using HasPrefix instead of Contains because a ~ can appear
    93  			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
    94  			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
    95  			if strings.HasPrefix(p, "~") {
    96  				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
    97  				os.Exit(2)
    98  			}
    99  			if !filepath.IsAbs(p) {
   100  				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nFor more details see: 'go help gopath'\n", p)
   101  				os.Exit(2)
   102  			}
   103  		}
   104  	}
   105  
   106  	if fi, err := os.Stat(cfg.GOROOT); err != nil || !fi.IsDir() {
   107  		fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", cfg.GOROOT)
   108  		os.Exit(2)
   109  	}
   110  
   111  	// Set environment (GOOS, GOARCH, etc) explicitly.
   112  	// In theory all the commands we invoke should have
   113  	// the same default computation of these as we do,
   114  	// but in practice there might be skew
   115  	// This makes sure we all agree.
   116  	cfg.OrigEnv = os.Environ()
   117  	cfg.CmdEnv = envcmd.MkEnv()
   118  	for _, env := range cfg.CmdEnv {
   119  		if os.Getenv(env.Name) != env.Value {
   120  			os.Setenv(env.Name, env.Value)
   121  		}
   122  	}
   123  
   124  	for _, cmd := range base.Commands {
   125  		if cmd.Name() == args[0] && cmd.Runnable() {
   126  			cmd.Flag.Usage = func() { cmd.Usage() }
   127  			if cmd.CustomFlags {
   128  				args = args[1:]
   129  			} else {
   130  				cmd.Flag.Parse(args[1:])
   131  				args = cmd.Flag.Args()
   132  			}
   133  			cmd.Run(cmd, args)
   134  			base.Exit()
   135  			return
   136  		}
   137  	}
   138  
   139  	fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
   140  	base.SetExitStatus(2)
   141  	base.Exit()
   142  }
   143  
   144  func init() {
   145  	base.Usage = mainUsage
   146  }
   147  
   148  func mainUsage() {
   149  	// special case "go test -h"
   150  	if len(os.Args) > 1 && os.Args[1] == "test" {
   151  		test.Usage()
   152  	}
   153  	help.PrintUsage(os.Stderr)
   154  	os.Exit(2)
   155  }