github.com/StingNevermore/go@v0.0.0-20180120041312-3810f5bfed72/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  	cfg.CmdName = args[0] // for error messages
    81  	if args[0] == "help" {
    82  		help.Help(args[1:])
    83  		return
    84  	}
    85  
    86  	// Diagnose common mistake: GOPATH==GOROOT.
    87  	// This setting is equivalent to not setting GOPATH at all,
    88  	// which is not what most people want when they do it.
    89  	if gopath := cfg.BuildContext.GOPATH; filepath.Clean(gopath) == filepath.Clean(runtime.GOROOT()) {
    90  		fmt.Fprintf(os.Stderr, "warning: GOPATH set to GOROOT (%s) has no effect\n", gopath)
    91  	} else {
    92  		for _, p := range filepath.SplitList(gopath) {
    93  			// Some GOPATHs have empty directory elements - ignore them.
    94  			// See issue 21928 for details.
    95  			if p == "" {
    96  				continue
    97  			}
    98  			// Note: using HasPrefix instead of Contains because a ~ can appear
    99  			// in the middle of directory elements, such as /tmp/git-1.8.2~rc3
   100  			// or C:\PROGRA~1. Only ~ as a path prefix has meaning to the shell.
   101  			if strings.HasPrefix(p, "~") {
   102  				fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
   103  				os.Exit(2)
   104  			}
   105  			if !filepath.IsAbs(p) {
   106  				fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nFor more details see: 'go help gopath'\n", p)
   107  				os.Exit(2)
   108  			}
   109  		}
   110  	}
   111  
   112  	if fi, err := os.Stat(cfg.GOROOT); err != nil || !fi.IsDir() {
   113  		fmt.Fprintf(os.Stderr, "go: cannot find GOROOT directory: %v\n", cfg.GOROOT)
   114  		os.Exit(2)
   115  	}
   116  
   117  	// Set environment (GOOS, GOARCH, etc) explicitly.
   118  	// In theory all the commands we invoke should have
   119  	// the same default computation of these as we do,
   120  	// but in practice there might be skew
   121  	// This makes sure we all agree.
   122  	cfg.OrigEnv = os.Environ()
   123  	cfg.CmdEnv = envcmd.MkEnv()
   124  	for _, env := range cfg.CmdEnv {
   125  		if os.Getenv(env.Name) != env.Value {
   126  			os.Setenv(env.Name, env.Value)
   127  		}
   128  	}
   129  
   130  	for _, cmd := range base.Commands {
   131  		if cmd.Name() == args[0] && cmd.Runnable() {
   132  			cmd.Flag.Usage = func() { cmd.Usage() }
   133  			if cmd.CustomFlags {
   134  				args = args[1:]
   135  			} else {
   136  				cmd.Flag.Parse(args[1:])
   137  				args = cmd.Flag.Args()
   138  			}
   139  			cmd.Run(cmd, args)
   140  			base.Exit()
   141  			return
   142  		}
   143  	}
   144  
   145  	fmt.Fprintf(os.Stderr, "go: unknown subcommand %q\nRun 'go help' for usage.\n", args[0])
   146  	base.SetExitStatus(2)
   147  	base.Exit()
   148  }
   149  
   150  func init() {
   151  	base.Usage = mainUsage
   152  }
   153  
   154  func mainUsage() {
   155  	// special case "go test -h"
   156  	if len(os.Args) > 1 && os.Args[1] == "test" {
   157  		test.Usage()
   158  	}
   159  	help.PrintUsage(os.Stderr)
   160  	os.Exit(2)
   161  }