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