Source file src/pkg/cmd/go/internal/modget/get.go
1
2
3
4
5
6 package modget
7
8 import (
9 "cmd/go/internal/base"
10 "cmd/go/internal/cfg"
11 "cmd/go/internal/get"
12 "cmd/go/internal/imports"
13 "cmd/go/internal/load"
14 "cmd/go/internal/modload"
15 "cmd/go/internal/module"
16 "cmd/go/internal/mvs"
17 "cmd/go/internal/par"
18 "cmd/go/internal/search"
19 "cmd/go/internal/semver"
20 "cmd/go/internal/work"
21 "errors"
22 "fmt"
23 "os"
24 "path/filepath"
25 "sort"
26 "strings"
27 "sync"
28 )
29
30 var CmdGet = &base.Command{
31
32
33 UsageLine: "go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]",
34 Short: "add dependencies to current module and install them",
35 Long: `
36 Get resolves and adds dependencies to the current development module
37 and then builds and installs them.
38
39 The first step is to resolve which dependencies to add.
40
41 For each named package or package pattern, get must decide which version of
42 the corresponding module to use. By default, get looks up the latest tagged
43 release version, such as v0.4.5 or v1.2.3. If there are no tagged release
44 versions, get looks up the latest tagged pre-release version, such as
45 v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest
46 known commit. If the module is not already required at a later version
47 (for example, a pre-release newer than the latest release), get will use
48 the version it looked up. Otherwise, get will use the currently
49 required version.
50
51 This default version selection can be overridden by adding an @version
52 suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
53 The version may be a prefix: @v1 denotes the latest available version starting
54 with v1. See 'go help modules' under the heading 'Module queries' for the
55 full query syntax.
56
57 For modules stored in source control repositories, the version suffix can
58 also be a commit hash, branch identifier, or other syntax known to the
59 source control system, as in 'go get golang.org/x/text@master'. Note that
60 branches with names that overlap with other module query syntax cannot be
61 selected explicitly. For example, the suffix @v2 means the latest version
62 starting with v2, not the branch named v2.
63
64 If a module under consideration is already a dependency of the current
65 development module, then get will update the required version.
66 Specifying a version earlier than the current required version is valid and
67 downgrades the dependency. The version suffix @none indicates that the
68 dependency should be removed entirely, downgrading or removing modules
69 depending on it as needed.
70
71 The version suffix @latest explicitly requests the latest minor release of the
72 module named by the given path. The suffix @upgrade is like @latest but
73 will not downgrade a module if it is already required at a revision or
74 pre-release version newer than the latest released version. The suffix
75 @patch requests the latest patch release: the latest released version
76 with the same major and minor version numbers as the currently required
77 version. Like @upgrade, @patch will not downgrade a module already required
78 at a newer version. If the path is not already required, @upgrade and @patch
79 are equivalent to @latest.
80
81 Although get defaults to using the latest version of the module containing
82 a named package, it does not use the latest version of that module's
83 dependencies. Instead it prefers to use the specific dependency versions
84 requested by that module. For example, if the latest A requires module
85 B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
86 will use the latest A but then use B v1.2.3, as requested by A. (If there
87 are competing requirements for a particular module, then 'go get' resolves
88 those requirements by taking the maximum requested version.)
89
90 The -t flag instructs get to consider modules needed to build tests of
91 packages specified on the command line.
92
93 The -u flag instructs get to update modules providing dependencies
94 of packages named on the command line to use newer minor or patch
95 releases when available. Continuing the previous example, 'go get -u A'
96 will use the latest A with B v1.3.1 (not B v1.2.3). If B requires module C,
97 but C does not provide any packages needed to build packages in A
98 (not including tests), then C will not be updated.
99
100 The -u=patch flag (not -u patch) also instructs get to update dependencies,
101 but changes the default to select patch releases.
102 Continuing the previous example,
103 'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3),
104 while 'go get -u=patch A' will use a patch release of A instead.
105
106 When the -t and -u flags are used together, get will update
107 test dependencies as well.
108
109 In general, adding a new dependency may require upgrading
110 existing dependencies to keep a working build, and 'go get' does
111 this automatically. Similarly, downgrading one dependency may
112 require downgrading other dependencies, and 'go get' does
113 this automatically as well.
114
115 The -insecure flag permits fetching from repositories and resolving
116 custom domains using insecure schemes such as HTTP. Use with caution.
117
118 The second step is to download (if needed), build, and install
119 the named packages.
120
121 If an argument names a module but not a package (because there is no
122 Go source code in the module's root directory), then the install step
123 is skipped for that argument, instead of causing a build failure.
124 For example 'go get golang.org/x/perf' succeeds even though there
125 is no code corresponding to that import path.
126
127 Note that package patterns are allowed and are expanded after resolving
128 the module versions. For example, 'go get golang.org/x/perf/cmd/...'
129 adds the latest golang.org/x/perf and then installs the commands in that
130 latest version.
131
132 The -d flag instructs get to download the source code needed to build
133 the named packages, including downloading necessary dependencies,
134 but not to build and install them.
135
136 With no package arguments, 'go get' applies to Go package in the
137 current directory, if any. In particular, 'go get -u' and
138 'go get -u=patch' update all the dependencies of that package.
139 With no package arguments and also without -u, 'go get' is not much more
140 than 'go install', and 'go get -d' not much more than 'go list'.
141
142 For more about modules, see 'go help modules'.
143
144 For more about specifying packages, see 'go help packages'.
145
146 This text describes the behavior of get using modules to manage source
147 code and dependencies. If instead the go command is running in GOPATH
148 mode, the details of get's flags and effects change, as does 'go help get'.
149 See 'go help modules' and 'go help gopath-get'.
150
151 See also: go build, go install, go clean, go mod.
152 `,
153 }
154
155
156
157
158
159 var HelpModuleGet = &base.Command{
160 UsageLine: "module-get",
161 Short: "module-aware go get",
162 Long: `
163 The 'go get' command changes behavior depending on whether the
164 go command is running in module-aware mode or legacy GOPATH mode.
165 This help text, accessible as 'go help module-get' even in legacy GOPATH mode,
166 describes 'go get' as it operates in module-aware mode.
167
168 Usage: ` + CmdGet.UsageLine + `
169 ` + CmdGet.Long,
170 }
171
172 var (
173 getD = CmdGet.Flag.Bool("d", false, "")
174 getF = CmdGet.Flag.Bool("f", false, "")
175 getFix = CmdGet.Flag.Bool("fix", false, "")
176 getM = CmdGet.Flag.Bool("m", false, "")
177 getT = CmdGet.Flag.Bool("t", false, "")
178 getU upgradeFlag
179
180
181 )
182
183
184 type upgradeFlag string
185
186 func (*upgradeFlag) IsBoolFlag() bool { return true }
187
188 func (v *upgradeFlag) Set(s string) error {
189 if s == "false" {
190 s = ""
191 }
192 if s == "true" {
193 s = "upgrade"
194 }
195 *v = upgradeFlag(s)
196 return nil
197 }
198
199 func (v *upgradeFlag) String() string { return "" }
200
201 func init() {
202 work.AddBuildFlags(CmdGet)
203 CmdGet.Run = runGet
204 CmdGet.Flag.BoolVar(&get.Insecure, "insecure", get.Insecure, "")
205 CmdGet.Flag.Var(&getU, "u", "")
206 }
207
208
209 type getArg struct {
210
211 raw string
212
213
214
215 path string
216
217
218
219
220 vers string
221 }
222
223
224
225
226 type querySpec struct {
227
228
229 path string
230
231
232 vers string
233
234
235
236 forceModulePath bool
237
238
239
240
241
242 prevM module.Version
243 }
244
245
246
247
248 type query struct {
249 querySpec
250
251
252 arg string
253
254
255 m module.Version
256 }
257
258 func runGet(cmd *base.Command, args []string) {
259
260 if cfg.BuildMod == "readonly" {
261 cfg.BuildMod = ""
262 }
263
264 switch getU {
265 case "", "upgrade", "patch":
266
267 default:
268 base.Fatalf("go get: unknown upgrade flag -u=%s", getU)
269 }
270 if *getF {
271 fmt.Fprintf(os.Stderr, "go get: -f flag is a no-op when using modules\n")
272 }
273 if *getFix {
274 fmt.Fprintf(os.Stderr, "go get: -fix flag is a no-op when using modules\n")
275 }
276 if *getM {
277 base.Fatalf("go get: -m flag is no longer supported; consider -d to skip building packages")
278 }
279 modload.LoadTests = *getT
280
281 if cfg.BuildMod == "vendor" {
282 base.Fatalf("go get: disabled by -mod=%s", cfg.BuildMod)
283 }
284
285 buildList := modload.LoadBuildList()
286 buildList = buildList[:len(buildList):len(buildList)]
287 versionByPath := make(map[string]string)
288 for _, m := range buildList {
289 versionByPath[m.Path] = m.Version
290 }
291
292
293
294
295 modload.DisallowWriteGoMod()
296
297
298
299
300 var gets []getArg
301 var queries []*query
302 for _, arg := range search.CleanPatterns(args) {
303
304 path := arg
305 vers := ""
306 if i := strings.Index(arg, "@"); i >= 0 {
307 path, vers = arg[:i], arg[i+1:]
308 }
309 if strings.Contains(vers, "@") || arg != path && vers == "" {
310 base.Errorf("go get %s: invalid module version syntax", arg)
311 continue
312 }
313
314
315
316 if vers == "" {
317 if getU != "" {
318 vers = string(getU)
319 } else {
320 vers = "upgrade"
321 }
322 }
323
324 gets = append(gets, getArg{raw: arg, path: path, vers: vers})
325
326
327
328
329
330
331
332 switch {
333 case search.IsRelativePath(path):
334
335
336
337
338
339 if !strings.Contains(path, "...") {
340 pkgPath := modload.DirImportPath(filepath.FromSlash(path))
341 if pkgs := modload.TargetPackages(pkgPath); len(pkgs) == 0 {
342 abs, err := filepath.Abs(path)
343 if err != nil {
344 abs = path
345 }
346 base.Errorf("go get %s: path %s is not a package in module rooted at %s", arg, abs, modload.ModRoot())
347 continue
348 }
349 }
350
351 if path != arg {
352 base.Errorf("go get %s: can't request explicit version of path in main module", arg)
353 continue
354 }
355
356 case strings.Contains(path, "..."):
357
358
359
360
361
362
363
364
365
366 case path == "all":
367
368
369
370 case search.IsMetaPackage(path):
371 base.Errorf("go get %s: explicit requirement on standard-library module %s not allowed", path, path)
372 continue
373
374 default:
375
376 if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
377
378 if vers != "upgrade" && vers != "patch" {
379 base.Errorf("go get %s: can't request explicit version of path in main module", arg)
380 }
381 continue
382 }
383
384 first := path
385 if i := strings.IndexByte(first, '/'); i >= 0 {
386 first = path
387 }
388 if !strings.Contains(first, ".") {
389
390
391
392
393 continue
394 }
395
396
397
398
399
400
401
402
403
404
405 q := &query{querySpec: querySpec{path: path, vers: vers}, arg: arg}
406 if v, ok := versionByPath[path]; ok && path != modload.Target.Path {
407 q.prevM = module.Version{Path: path, Version: v}
408 q.forceModulePath = true
409 }
410 queries = append(queries, q)
411 }
412 }
413 base.ExitIfErrors()
414
415
416
417
418
419 queryCache := make(map[querySpec]*query)
420 byPath := runQueries(queryCache, queries, nil)
421
422
423
424
425 for _, q := range queries {
426 if _, ok := versionByPath[q.m.Path]; !ok && q.m.Version != "none" {
427 buildList = append(buildList, q.m)
428 }
429 }
430 versionByPath = nil
431 modload.SetBuildList(buildList)
432
433
434
435
436
437 upgrade := make(map[string]*query)
438 for path, q := range byPath {
439 if q.path == q.m.Path && q.m.Version != "none" {
440 upgrade[path] = q
441 }
442 }
443 buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(upgrade, nil))
444 if err != nil {
445 base.Fatalf("go get: %v", err)
446 }
447 modload.SetBuildList(buildList)
448 base.ExitIfErrors()
449 prevBuildList := buildList
450
451
452
453
454 var wg sync.WaitGroup
455 var modOnlyMu sync.Mutex
456 modOnly := make(map[string]*query)
457 for _, q := range queries {
458 if q.m.Version == "none" {
459 modOnlyMu.Lock()
460 modOnly[q.m.Path] = q
461 modOnlyMu.Unlock()
462 continue
463 }
464 if q.path == q.m.Path {
465 wg.Add(1)
466 go func(q *query) {
467 if hasPkg, err := modload.ModuleHasRootPackage(q.m); err != nil {
468 base.Errorf("go get: %v", err)
469 } else if !hasPkg {
470 modOnlyMu.Lock()
471 modOnly[q.m.Path] = q
472 modOnlyMu.Unlock()
473 }
474 wg.Done()
475 }(q)
476 }
477 }
478 wg.Wait()
479 base.ExitIfErrors()
480
481
482 var pkgPatterns []string
483 var pkgGets []getArg
484 for _, arg := range gets {
485 if modOnly[arg.path] == nil && arg.vers != "none" {
486 pkgPatterns = append(pkgPatterns, arg.path)
487 pkgGets = append(pkgGets, arg)
488 }
489 }
490
491
492
493
494
495
496 var matches []*search.Match
497 for {
498 var seenPkgs map[string]bool
499 seenQuery := make(map[querySpec]bool)
500 var queries []*query
501 addQuery := func(q *query) {
502 if !seenQuery[q.querySpec] {
503 seenQuery[q.querySpec] = true
504 queries = append(queries, q)
505 }
506 }
507
508 if len(pkgPatterns) > 0 {
509
510
511
512 matches = modload.ImportPathsQuiet(pkgPatterns, imports.AnyTags())
513 seenPkgs = make(map[string]bool)
514 for i, match := range matches {
515 arg := pkgGets[i]
516
517 if len(match.Pkgs) == 0 {
518
519
520
521 if !search.IsRelativePath(arg.path) && !match.Literal && arg.path != "all" {
522 addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw})
523 }
524 continue
525 }
526
527 allStd := true
528 for _, pkg := range match.Pkgs {
529 if !seenPkgs[pkg] {
530 seenPkgs[pkg] = true
531 if _, _, err := modload.Lookup("", false, pkg); err != nil {
532 allStd = false
533 base.Errorf("go get %s: %v", arg.raw, err)
534 continue
535 }
536 }
537 m := modload.PackageModule(pkg)
538 if m.Path == "" {
539
540 continue
541 }
542 allStd = false
543 if m.Path == modload.Target.Path {
544
545 continue
546 }
547 addQuery(&query{querySpec: querySpec{path: m.Path, vers: arg.vers, forceModulePath: true, prevM: m}, arg: arg.raw})
548 }
549 if allStd && arg.path != arg.raw {
550 base.Errorf("go get %s: cannot use pattern %q with explicit version", arg.raw, arg.raw)
551 }
552 }
553 }
554 base.ExitIfErrors()
555
556
557
558 byPath = runQueries(queryCache, queries, modOnly)
559
560
561
562
563 buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(byPath, seenPkgs))
564 if err != nil {
565 base.Fatalf("go get: %v", err)
566 }
567 modload.SetBuildList(buildList)
568 base.ExitIfErrors()
569
570
571 buildList = modload.BuildList()
572 eq := len(buildList) == len(prevBuildList)
573 for i := 0; eq && i < len(buildList); i++ {
574 eq = buildList[i] == prevBuildList[i]
575 }
576 if eq {
577 break
578 }
579 prevBuildList = buildList
580 }
581 if !*getD {
582
583
584 search.WarnUnmatched(matches)
585 }
586
587
588 var down []module.Version
589 for _, m := range modload.BuildList() {
590 q := byPath[m.Path]
591 if q != nil && semver.Compare(m.Version, q.m.Version) > 0 {
592 down = append(down, module.Version{Path: m.Path, Version: q.m.Version})
593 }
594 }
595 if len(down) > 0 {
596 buildList, err := mvs.Downgrade(modload.Target, modload.Reqs(), down...)
597 if err != nil {
598 base.Fatalf("go: %v", err)
599 }
600 modload.SetBuildList(buildList)
601 modload.ReloadBuildList()
602 base.ExitIfErrors()
603 }
604
605
606 var lostUpgrades []*query
607 if len(down) > 0 {
608 versionByPath = make(map[string]string)
609 for _, m := range modload.BuildList() {
610 versionByPath[m.Path] = m.Version
611 }
612 for _, q := range byPath {
613 if v, ok := versionByPath[q.m.Path]; q.m.Version != "none" && (!ok || semver.Compare(v, q.m.Version) != 0) {
614 lostUpgrades = append(lostUpgrades, q)
615 }
616 }
617 sort.Slice(lostUpgrades, func(i, j int) bool {
618 return lostUpgrades[i].m.Path < lostUpgrades[j].m.Path
619 })
620 }
621 if len(lostUpgrades) > 0 {
622 desc := func(m module.Version) string {
623 s := m.Path + "@" + m.Version
624 t := byPath[m.Path]
625 if t != nil && t.arg != s {
626 s += " from " + t.arg
627 }
628 return s
629 }
630 downByPath := make(map[string]module.Version)
631 for _, d := range down {
632 downByPath[d.Path] = d
633 }
634
635 var buf strings.Builder
636 fmt.Fprintf(&buf, "go get: inconsistent versions:")
637 reqs := modload.Reqs()
638 for _, q := range lostUpgrades {
639
640
641
642
643
644 list, err := buildListForLostUpgrade(q.m, reqs)
645 if err != nil {
646 base.Fatalf("go: %v", err)
647 }
648
649 fmt.Fprintf(&buf, "\n\t%s", desc(q.m))
650 sep := " requires"
651 for _, m := range list {
652 if down, ok := downByPath[m.Path]; ok && semver.Compare(down.Version, m.Version) < 0 {
653 fmt.Fprintf(&buf, "%s %s@%s (not %s)", sep, m.Path, m.Version, desc(down))
654 sep = ","
655 }
656 }
657 if sep != "," {
658
659
660 if v := versionByPath[q.m.Path]; v == "" {
661 fmt.Fprintf(&buf, " removed unexpectedly")
662 } else {
663 fmt.Fprintf(&buf, " ended up at %s unexpectedly", v)
664 }
665 fmt.Fprintf(&buf, " (please report at golang.org/issue/new)")
666 }
667 }
668 base.Fatalf("%v", buf.String())
669 }
670
671
672 modload.AllowWriteGoMod()
673 modload.WriteGoMod()
674
675
676
677
678
679
680
681
682
683 if *getD || len(pkgPatterns) == 0 {
684 return
685 }
686 work.BuildInit()
687 pkgs := load.PackagesForBuild(pkgPatterns)
688 work.InstallPackages(pkgPatterns, pkgs)
689 }
690
691
692
693
694
695
696 func runQueries(cache map[querySpec]*query, queries []*query, modOnly map[string]*query) map[string]*query {
697 var lookup par.Work
698 for _, q := range queries {
699 if cached := cache[q.querySpec]; cached != nil {
700 *q = *cached
701 } else {
702 cache[q.querySpec] = q
703 lookup.Add(q)
704 }
705 }
706
707 lookup.Do(10, func(item interface{}) {
708 q := item.(*query)
709 if q.vers == "none" {
710
711 q.m = module.Version{Path: q.path, Version: "none"}
712 return
713 }
714 m, err := getQuery(q.path, q.vers, q.prevM, q.forceModulePath)
715 if err != nil {
716 base.Errorf("go get %s: %v", q.arg, err)
717 }
718 q.m = m
719 })
720 base.ExitIfErrors()
721
722 byPath := make(map[string]*query)
723 check := func(q *query) {
724 if prev, ok := byPath[q.m.Path]; prev != nil && prev.m != q.m {
725 base.Errorf("go get: conflicting versions for module %s: %s and %s", q.m.Path, prev.m.Version, q.m.Version)
726 byPath[q.m.Path] = nil
727 return
728 } else if !ok {
729 byPath[q.m.Path] = q
730 }
731 }
732 for _, q := range queries {
733 check(q)
734 }
735 for _, q := range modOnly {
736 check(q)
737 }
738 base.ExitIfErrors()
739
740 return byPath
741 }
742
743
744
745
746
747 func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (module.Version, error) {
748 if (prevM.Version != "") != forceModulePath {
749
750
751
752
753
754
755
756
757
758 base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set")
759 }
760
761
762 if forceModulePath {
763 if path == modload.Target.Path {
764 if vers != "latest" {
765 return module.Version{}, fmt.Errorf("can't get a specific version of the main module")
766 }
767 }
768
769 info, err := modload.Query(path, vers, prevM.Version, modload.Allowed)
770 if err == nil {
771 return module.Version{Path: path, Version: info.Version}, nil
772 }
773
774
775
776
777
778 if vers == "upgrade" || vers == "patch" {
779 var vErr *module.InvalidVersionError
780 if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" {
781 return prevM, nil
782 }
783 }
784
785 return module.Version{}, err
786 }
787
788
789
790
791
792 results, err := modload.QueryPattern(path, vers, modload.Allowed)
793 if err != nil {
794
795
796 if !strings.Contains(path, "...") {
797 var modErr *modload.PackageNotInModuleError
798 if errors.As(err, &modErr) && modErr.Mod.Path == path {
799 return modErr.Mod, nil
800 }
801 }
802
803 return module.Version{}, err
804 }
805
806 return results[0].Mod, nil
807 }
808
809
810
811 type upgrader struct {
812 mvs.Reqs
813
814
815
816
817 cmdline map[string]*query
818
819
820
821
822 upgrade map[string]bool
823 }
824
825
826
827
828
829 func newUpgrader(cmdline map[string]*query, pkgs map[string]bool) *upgrader {
830 u := &upgrader{
831 Reqs: modload.Reqs(),
832 cmdline: cmdline,
833 }
834 if getU != "" {
835 u.upgrade = make(map[string]bool)
836
837
838
839 seen := make(map[string]bool)
840 var work []string
841 add := func(path string) {
842 if !seen[path] {
843 seen[path] = true
844 work = append(work, path)
845 }
846 }
847 for pkg := range pkgs {
848 add(pkg)
849 }
850 for len(work) > 0 {
851 pkg := work[0]
852 work = work[1:]
853 m := modload.PackageModule(pkg)
854 u.upgrade[m.Path] = true
855
856
857
858 imports, testImports := modload.PackageImports(pkg)
859 for _, imp := range imports {
860 add(imp)
861 }
862 for _, imp := range testImports {
863 add(imp)
864 }
865 }
866 }
867 return u
868 }
869
870
871
872
873
874 func (u *upgrader) Required(m module.Version) ([]module.Version, error) {
875 rs, err := u.Reqs.Required(m)
876 if err != nil {
877 return nil, err
878 }
879 if m != modload.Target {
880 return rs, nil
881 }
882
883 overridden := make(map[string]bool)
884 for i, m := range rs {
885 if q := u.cmdline[m.Path]; q != nil && q.m.Version != "none" {
886 rs[i] = q.m
887 overridden[q.m.Path] = true
888 }
889 }
890 for _, q := range u.cmdline {
891 if !overridden[q.m.Path] && q.m.Path != modload.Target.Path && q.m.Version != "none" {
892 rs = append(rs, q.m)
893 }
894 }
895 return rs, nil
896 }
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913 func (u *upgrader) Upgrade(m module.Version) (module.Version, error) {
914
915
916
917
918
919
920
921 if q := u.cmdline[m.Path]; q != nil {
922 return q.m, nil
923 }
924
925 if !u.upgrade[m.Path] {
926
927 return m, nil
928 }
929
930
931
932
933
934
935
936
937
938
939 info, err := modload.Query(m.Path, string(getU), m.Version, modload.Allowed)
940 if err != nil {
941
942
943
944
945
946
947 var vErr *module.InvalidVersionError
948 if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" {
949 return m, nil
950 }
951
952
953
954
955
956 var noMatch *modload.NoMatchingVersionError
957 if !errors.As(err, &noMatch) {
958 base.Errorf("go get: upgrading %s@%s: %v", m.Path, m.Version, err)
959 }
960 return m, nil
961 }
962
963 return module.Version{Path: m.Path, Version: info.Version}, nil
964 }
965
966
967
968
969
970
971
972
973
974 func buildListForLostUpgrade(lost module.Version, reqs mvs.Reqs) ([]module.Version, error) {
975 return mvs.BuildList(lostUpgradeRoot, &lostUpgradeReqs{Reqs: reqs, lost: lost})
976 }
977
978 var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""}
979
980 type lostUpgradeReqs struct {
981 mvs.Reqs
982 lost module.Version
983 }
984
985 func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) {
986 if mod == lostUpgradeRoot {
987 return []module.Version{r.lost}, nil
988 }
989 return r.Reqs.Required(mod)
990 }
991
View as plain text