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