github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/modcmd/download.go (about)

     1  // Copyright 2018 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  package modcmd
     6  
     7  import (
     8  	"encoding/json"
     9  	"os"
    10  
    11  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/base"
    12  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/cfg"
    13  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/modfetch"
    14  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/modload"
    15  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/par"
    16  	"github.com/gagliardetto/golang-go/cmd/go/not-internal/work"
    17  
    18  	"golang.org/x/mod/module"
    19  )
    20  
    21  var cmdDownload = &base.Command{
    22  	UsageLine: "go mod download [-x] [-json] [modules]",
    23  	Short:     "download modules to local cache",
    24  	Long: `
    25  Download downloads the named modules, which can be module patterns selecting
    26  dependencies of the main module or module queries of the form path@version.
    27  With no arguments, download applies to all dependencies of the main module.
    28  
    29  The go command will automatically download modules as needed during ordinary
    30  execution. The "go mod download" command is useful mainly for pre-filling
    31  the local cache or to compute the answers for a Go module proxy.
    32  
    33  By default, download writes nothing to standard output. It may print progress
    34  messages and errors to standard error.
    35  
    36  The -json flag causes download to print a sequence of JSON objects
    37  to standard output, describing each downloaded module (or failure),
    38  corresponding to this Go struct:
    39  
    40      type Module struct {
    41          Path     string // module path
    42          Version  string // module version
    43          Error    string // error loading module
    44          Info     string // absolute path to cached .info file
    45          GoMod    string // absolute path to cached .mod file
    46          Zip      string // absolute path to cached .zip file
    47          Dir      string // absolute path to cached source root directory
    48          Sum      string // checksum for path, version (as in go.sum)
    49          GoModSum string // checksum for go.mod (as in go.sum)
    50      }
    51  
    52  The -x flag causes download to print the commands download executes.
    53  
    54  See 'go help modules' for more about module queries.
    55  	`,
    56  }
    57  
    58  var downloadJSON = cmdDownload.Flag.Bool("json", false, "")
    59  
    60  func init() {
    61  	cmdDownload.Run = runDownload // break init cycle
    62  
    63  	// TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands.
    64  	cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "")
    65  	work.AddModCommonFlags(cmdDownload)
    66  }
    67  
    68  type moduleJSON struct {
    69  	Path     string `json:",omitempty"`
    70  	Version  string `json:",omitempty"`
    71  	Error    string `json:",omitempty"`
    72  	Info     string `json:",omitempty"`
    73  	GoMod    string `json:",omitempty"`
    74  	Zip      string `json:",omitempty"`
    75  	Dir      string `json:",omitempty"`
    76  	Sum      string `json:",omitempty"`
    77  	GoModSum string `json:",omitempty"`
    78  }
    79  
    80  func runDownload(cmd *base.Command, args []string) {
    81  	// Check whether modules are enabled and whether we're in a module.
    82  	if cfg.Getenv("GO111MODULE") == "off" {
    83  		base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
    84  	}
    85  	if !modload.HasModRoot() && len(args) == 0 {
    86  		base.Fatalf("go mod download: no modules specified (see 'go help mod download')")
    87  	}
    88  	if len(args) == 0 {
    89  		args = []string{"all"}
    90  	} else if modload.HasModRoot() {
    91  		modload.InitMod() // to fill Target
    92  		targetAtLatest := modload.Target.Path + "@latest"
    93  		targetAtUpgrade := modload.Target.Path + "@upgrade"
    94  		targetAtPatch := modload.Target.Path + "@patch"
    95  		for _, arg := range args {
    96  			switch arg {
    97  			case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch:
    98  				os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n")
    99  			}
   100  		}
   101  	}
   102  
   103  	var mods []*moduleJSON
   104  	var work par.Work
   105  	listU := false
   106  	listVersions := false
   107  	for _, info := range modload.ListModules(args, listU, listVersions) {
   108  		if info.Replace != nil {
   109  			info = info.Replace
   110  		}
   111  		if info.Version == "" && info.Error == nil {
   112  			// main module or module replaced with file path.
   113  			// Nothing to download.
   114  			continue
   115  		}
   116  		m := &moduleJSON{
   117  			Path:    info.Path,
   118  			Version: info.Version,
   119  		}
   120  		mods = append(mods, m)
   121  		if info.Error != nil {
   122  			m.Error = info.Error.Err
   123  			continue
   124  		}
   125  		work.Add(m)
   126  	}
   127  
   128  	work.Do(10, func(item interface{}) {
   129  		m := item.(*moduleJSON)
   130  		var err error
   131  		m.Info, err = modfetch.InfoFile(m.Path, m.Version)
   132  		if err != nil {
   133  			m.Error = err.Error()
   134  			return
   135  		}
   136  		m.GoMod, err = modfetch.GoModFile(m.Path, m.Version)
   137  		if err != nil {
   138  			m.Error = err.Error()
   139  			return
   140  		}
   141  		m.GoModSum, err = modfetch.GoModSum(m.Path, m.Version)
   142  		if err != nil {
   143  			m.Error = err.Error()
   144  			return
   145  		}
   146  		mod := module.Version{Path: m.Path, Version: m.Version}
   147  		m.Zip, err = modfetch.DownloadZip(mod)
   148  		if err != nil {
   149  			m.Error = err.Error()
   150  			return
   151  		}
   152  		m.Sum = modfetch.Sum(mod)
   153  		m.Dir, err = modfetch.Download(mod)
   154  		if err != nil {
   155  			m.Error = err.Error()
   156  			return
   157  		}
   158  	})
   159  
   160  	if *downloadJSON {
   161  		for _, m := range mods {
   162  			b, err := json.MarshalIndent(m, "", "\t")
   163  			if err != nil {
   164  				base.Fatalf("%v", err)
   165  			}
   166  			os.Stdout.Write(append(b, '\n'))
   167  			if m.Error != "" {
   168  				base.SetExitStatus(1)
   169  			}
   170  		}
   171  	} else {
   172  		for _, m := range mods {
   173  			if m.Error != "" {
   174  				base.Errorf("%s", m.Error)
   175  			}
   176  		}
   177  		base.ExitIfErrors()
   178  	}
   179  }