1
2
3
4
5 package modload
6
7 import (
8 "bytes"
9 "context"
10 "encoding/json"
11 "errors"
12 "fmt"
13 "go/build"
14 "internal/lazyregexp"
15 "os"
16 "path"
17 "path/filepath"
18 "sort"
19 "strconv"
20 "strings"
21 "sync"
22
23 "cmd/go/internal/base"
24 "cmd/go/internal/cfg"
25 "cmd/go/internal/fsys"
26 "cmd/go/internal/lockedfile"
27 "cmd/go/internal/modconv"
28 "cmd/go/internal/modfetch"
29 "cmd/go/internal/mvs"
30 "cmd/go/internal/search"
31 "cmd/go/internal/str"
32
33 "golang.org/x/mod/modfile"
34 "golang.org/x/mod/module"
35 "golang.org/x/mod/semver"
36 )
37
38 var (
39 initialized bool
40
41 modRoot string
42 Target module.Version
43
44
45
46
47 targetPrefix string
48
49
50
51 targetInGorootSrc bool
52
53 gopath string
54
55
56 RootMode Root
57
58
59
60 ForceUseModules bool
61
62 allowMissingModuleImports bool
63 )
64
65 type Root int
66
67 const (
68
69
70
71
72 AutoRoot Root = iota
73
74
75
76 NoRoot
77
78
79
80 NeedRoot
81 )
82
83
84
85
86
87
88
89
90
91 func ModFile() *modfile.File {
92 Init()
93 if modFile == nil {
94 die()
95 }
96 return modFile
97 }
98
99 func BinDir() string {
100 Init()
101 return filepath.Join(gopath, "bin")
102 }
103
104
105
106
107
108 func Init() {
109 if initialized {
110 return
111 }
112 initialized = true
113
114
115
116
117 var mustUseModules bool
118 env := cfg.Getenv("GO111MODULE")
119 switch env {
120 default:
121 base.Fatalf("go: unknown environment setting GO111MODULE=%s", env)
122 case "auto":
123 mustUseModules = ForceUseModules
124 case "on", "":
125 mustUseModules = true
126 case "off":
127 if ForceUseModules {
128 base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
129 }
130 mustUseModules = false
131 return
132 }
133
134 if err := fsys.Init(base.Cwd); err != nil {
135 base.Fatalf("go: %v", err)
136 }
137
138
139
140
141
142
143
144 if os.Getenv("GIT_TERMINAL_PROMPT") == "" {
145 os.Setenv("GIT_TERMINAL_PROMPT", "0")
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 if os.Getenv("GIT_SSH") == "" && os.Getenv("GIT_SSH_COMMAND") == "" {
162 os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no")
163 }
164
165 if modRoot != "" {
166
167
168 } else if RootMode == NoRoot {
169 if cfg.ModFile != "" && !base.InGOFLAGS("-modfile") {
170 base.Fatalf("go: -modfile cannot be used with commands that ignore the current module")
171 }
172 modRoot = ""
173 } else {
174 modRoot = findModuleRoot(base.Cwd)
175 if modRoot == "" {
176 if cfg.ModFile != "" {
177 base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.")
178 }
179 if RootMode == NeedRoot {
180 base.Fatalf("go: cannot find main module; see 'go help modules'")
181 }
182 if !mustUseModules {
183
184
185 return
186 }
187 } else if search.InDir(modRoot, os.TempDir()) == "." {
188
189
190
191
192
193 modRoot = ""
194 fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir())
195 if !mustUseModules {
196 return
197 }
198 }
199 }
200 if cfg.ModFile != "" && !strings.HasSuffix(cfg.ModFile, ".mod") {
201 base.Fatalf("go: -modfile=%s: file does not have .mod extension", cfg.ModFile)
202 }
203
204
205 cfg.ModulesEnabled = true
206 setDefaultBuildMod()
207 list := filepath.SplitList(cfg.BuildContext.GOPATH)
208 if len(list) == 0 || list[0] == "" {
209 base.Fatalf("missing $GOPATH")
210 }
211 gopath = list[0]
212 if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil {
213 base.Fatalf("$GOPATH/go.mod exists but should not")
214 }
215
216 if modRoot == "" {
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 } else {
235 modfetch.GoSumFile = strings.TrimSuffix(ModFilePath(), ".mod") + ".sum"
236 search.SetModRoot(modRoot)
237 }
238 }
239
240
241
242
243
244
245
246
247
248
249 func WillBeEnabled() bool {
250 if modRoot != "" || cfg.ModulesEnabled {
251
252 return true
253 }
254 if initialized {
255
256 return false
257 }
258
259
260
261 env := cfg.Getenv("GO111MODULE")
262 switch env {
263 case "on", "":
264 return true
265 case "auto":
266 break
267 default:
268 return false
269 }
270
271 if modRoot := findModuleRoot(base.Cwd); modRoot == "" {
272
273
274 return false
275 } else if search.InDir(modRoot, os.TempDir()) == "." {
276
277
278
279
280
281 return false
282 }
283 return true
284 }
285
286
287
288
289
290 func Enabled() bool {
291 Init()
292 return modRoot != "" || cfg.ModulesEnabled
293 }
294
295
296
297 func ModRoot() string {
298 if !HasModRoot() {
299 die()
300 }
301 return modRoot
302 }
303
304
305
306
307 func HasModRoot() bool {
308 Init()
309 return modRoot != ""
310 }
311
312
313
314
315
316 func ModFilePath() string {
317 if !HasModRoot() {
318 die()
319 }
320 if cfg.ModFile != "" {
321 return cfg.ModFile
322 }
323 return filepath.Join(modRoot, "go.mod")
324 }
325
326 func die() {
327 if cfg.Getenv("GO111MODULE") == "off" {
328 base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'")
329 }
330 if dir, name := findAltConfig(base.Cwd); dir != "" {
331 rel, err := filepath.Rel(base.Cwd, dir)
332 if err != nil {
333 rel = dir
334 }
335 cdCmd := ""
336 if rel != "." {
337 cdCmd = fmt.Sprintf("cd %s && ", rel)
338 }
339 base.Fatalf("go: cannot find main module, but found %s in %s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd)
340 }
341 base.Fatalf("go: cannot find main module; see 'go help modules'")
342 }
343
344
345
346
347
348
349
350
351
352
353 func LoadModFile(ctx context.Context) {
354 if len(buildList) > 0 {
355 return
356 }
357
358 Init()
359 if modRoot == "" {
360 Target = module.Version{Path: "command-line-arguments"}
361 targetPrefix = "command-line-arguments"
362 buildList = []module.Version{Target}
363 return
364 }
365
366 gomod := ModFilePath()
367 data, err := lockedfile.Read(gomod)
368 if err != nil {
369 base.Fatalf("go: %v", err)
370 }
371
372 var fixed bool
373 f, err := modfile.Parse(gomod, data, fixVersion(ctx, &fixed))
374 if err != nil {
375
376 base.Fatalf("go: errors parsing go.mod:\n%s\n", err)
377 }
378 modFile = f
379 index = indexModFile(data, f, fixed)
380
381 if f.Module == nil {
382
383 base.Fatalf("go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod")
384 }
385
386 if err := checkModulePathLax(f.Module.Mod.Path); err != nil {
387 base.Fatalf("go: %v", err)
388 }
389
390 setDefaultBuildMod()
391 modFileToBuildList()
392 if cfg.BuildMod == "vendor" {
393 readVendorList()
394 checkVendorConsistency()
395 }
396 }
397
398
399
400
401
402
403
404
405
406
407 func CreateModFile(ctx context.Context, modPath string) {
408 modRoot = base.Cwd
409 Init()
410 modFilePath := ModFilePath()
411 if _, err := fsys.Stat(modFilePath); err == nil {
412 base.Fatalf("go: %s already exists", modFilePath)
413 }
414
415 if modPath == "" {
416 var err error
417 modPath, err = findModulePath(modRoot)
418 if err != nil {
419 base.Fatalf("go: %v", err)
420 }
421 } else if err := checkModulePathLax(modPath); err != nil {
422 base.Fatalf("go: %v", err)
423 }
424
425 fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath)
426 modFile = new(modfile.File)
427 modFile.AddModuleStmt(modPath)
428 addGoStmt()
429
430 convertedFrom, err := convertLegacyConfig(modPath)
431 if convertedFrom != "" {
432 fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(convertedFrom))
433 }
434 if err != nil {
435 base.Fatalf("go: %v", err)
436 }
437
438 modFileToBuildList()
439 WriteGoMod()
440
441
442
443
444
445
446
447
448 empty := true
449 files, _ := os.ReadDir(modRoot)
450 for _, f := range files {
451 name := f.Name()
452 if strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") {
453 continue
454 }
455 if strings.HasSuffix(name, ".go") || f.IsDir() {
456 empty = false
457 break
458 }
459 }
460 if !empty {
461 fmt.Fprintf(os.Stderr, "go: to add module requirements and sums:\n\tgo mod tidy\n")
462 }
463 }
464
465
466
467
468
469
470 func checkModulePathLax(p string) error {
471
472
473
474
475
476 errorf := func(format string, args ...interface{}) error {
477 return fmt.Errorf("invalid module path %q: %s", p, fmt.Sprintf(format, args...))
478 }
479
480
481
482
483
484 shellChars := "`" + `\"'*<>?|`
485 fsChars := `\:`
486 if i := strings.IndexAny(p, shellChars); i >= 0 {
487 return errorf("contains disallowed shell character %q", p[i])
488 }
489 if i := strings.IndexAny(p, fsChars); i >= 0 {
490 return errorf("contains disallowed path separator character %q", p[i])
491 }
492
493
494
495 if path.IsAbs(p) {
496 return errorf("is an absolute path")
497 }
498 if build.IsLocalImport(p) {
499 return errorf("is a local import path")
500 }
501 if path.Clean(p) != p {
502 return errorf("is not clean")
503 }
504
505 return nil
506 }
507
508
509
510
511
512
513
514
515 func fixVersion(ctx context.Context, fixed *bool) modfile.VersionFixer {
516 return func(path, vers string) (resolved string, err error) {
517 defer func() {
518 if err == nil && resolved != vers {
519 *fixed = true
520 }
521 }()
522
523
524 if strings.HasPrefix(path, "gopkg.in/") && strings.Contains(vers, "-gopkgin-") {
525 vers = vers[strings.Index(vers, "-gopkgin-")+len("-gopkgin-"):]
526 }
527
528
529
530
531 _, pathMajor, ok := module.SplitPathVersion(path)
532 if !ok {
533 return "", &module.ModuleError{
534 Path: path,
535 Err: &module.InvalidVersionError{
536 Version: vers,
537 Err: fmt.Errorf("malformed module path %q", path),
538 },
539 }
540 }
541 if vers != "" && module.CanonicalVersion(vers) == vers {
542 if err := module.CheckPathMajor(vers, pathMajor); err == nil {
543 return vers, nil
544 }
545 }
546
547 info, err := Query(ctx, path, vers, "", nil)
548 if err != nil {
549 return "", err
550 }
551 return info.Version, nil
552 }
553 }
554
555
556
557
558
559 func AllowMissingModuleImports() {
560 allowMissingModuleImports = true
561 }
562
563
564 func modFileToBuildList() {
565 Target = modFile.Module.Mod
566 targetPrefix = Target.Path
567 if rel := search.InDir(base.Cwd, cfg.GOROOTsrc); rel != "" {
568 targetInGorootSrc = true
569 if Target.Path == "std" {
570 targetPrefix = ""
571 }
572 }
573
574 list := []module.Version{Target}
575 for _, r := range modFile.Require {
576 if index != nil && index.exclude[r.Mod] {
577 if cfg.BuildMod == "mod" {
578 fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
579 } else {
580 fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version)
581 }
582 } else {
583 list = append(list, r.Mod)
584 }
585 }
586 buildList = list
587 }
588
589
590
591 func setDefaultBuildMod() {
592 if cfg.BuildModExplicit {
593
594 return
595 }
596
597 if cfg.CmdName == "get" || strings.HasPrefix(cfg.CmdName, "mod ") {
598
599
600
601 cfg.BuildMod = "mod"
602 return
603 }
604 if modRoot == "" {
605 cfg.BuildMod = "readonly"
606 return
607 }
608
609 if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
610 modGo := "unspecified"
611 if index != nil && index.goVersionV != "" {
612 if semver.Compare(index.goVersionV, "v1.14") >= 0 {
613
614
615 cfg.BuildMod = "vendor"
616 cfg.BuildModReason = "Go version in go.mod is at least 1.14 and vendor directory exists."
617 return
618 } else {
619 modGo = index.goVersionV[1:]
620 }
621 }
622
623
624
625 cfg.BuildModReason = fmt.Sprintf("Go version in go.mod is %s, so vendor directory was not used.", modGo)
626 }
627
628 cfg.BuildMod = "readonly"
629 }
630
631
632
633 func convertLegacyConfig(modPath string) (from string, err error) {
634 for _, name := range altConfigs {
635 cfg := filepath.Join(modRoot, name)
636 data, err := os.ReadFile(cfg)
637 if err == nil {
638 convert := modconv.Converters[name]
639 if convert == nil {
640 return "", nil
641 }
642 cfg = filepath.ToSlash(cfg)
643 err := modconv.ConvertLegacyConfig(modFile, cfg, data)
644 return name, err
645 }
646 }
647 return "", nil
648 }
649
650
651
652 func addGoStmt() {
653 if modFile.Go != nil && modFile.Go.Version != "" {
654 return
655 }
656 tags := build.Default.ReleaseTags
657 version := tags[len(tags)-1]
658 if !strings.HasPrefix(version, "go") || !modfile.GoVersionRE.MatchString(version[2:]) {
659 base.Fatalf("go: unrecognized default version %q", version)
660 }
661 if err := modFile.AddGoStmt(version[2:]); err != nil {
662 base.Fatalf("go: internal error: %v", err)
663 }
664 }
665
666 var altConfigs = []string{
667 "Gopkg.lock",
668
669 "GLOCKFILE",
670 "Godeps/Godeps.json",
671 "dependencies.tsv",
672 "glide.lock",
673 "vendor.conf",
674 "vendor.yml",
675 "vendor/manifest",
676 "vendor/vendor.json",
677
678 ".git/config",
679 }
680
681 func findModuleRoot(dir string) (root string) {
682 if dir == "" {
683 panic("dir not set")
684 }
685 dir = filepath.Clean(dir)
686
687
688 for {
689 if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
690 return dir
691 }
692 d := filepath.Dir(dir)
693 if d == dir {
694 break
695 }
696 dir = d
697 }
698 return ""
699 }
700
701 func findAltConfig(dir string) (root, name string) {
702 if dir == "" {
703 panic("dir not set")
704 }
705 dir = filepath.Clean(dir)
706 if rel := search.InDir(dir, cfg.BuildContext.GOROOT); rel != "" {
707
708
709 return "", ""
710 }
711 for {
712 for _, name := range altConfigs {
713 if fi, err := fsys.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() {
714 return dir, name
715 }
716 }
717 d := filepath.Dir(dir)
718 if d == dir {
719 break
720 }
721 dir = d
722 }
723 return "", ""
724 }
725
726 func findModulePath(dir string) (string, error) {
727
728
729
730
731
732
733
734
735 list, _ := os.ReadDir(dir)
736 for _, info := range list {
737 if info.Type().IsRegular() && strings.HasSuffix(info.Name(), ".go") {
738 if com := findImportComment(filepath.Join(dir, info.Name())); com != "" {
739 return com, nil
740 }
741 }
742 }
743 for _, info1 := range list {
744 if info1.IsDir() {
745 files, _ := os.ReadDir(filepath.Join(dir, info1.Name()))
746 for _, info2 := range files {
747 if info2.Type().IsRegular() && strings.HasSuffix(info2.Name(), ".go") {
748 if com := findImportComment(filepath.Join(dir, info1.Name(), info2.Name())); com != "" {
749 return path.Dir(com), nil
750 }
751 }
752 }
753 }
754 }
755
756
757 data, _ := os.ReadFile(filepath.Join(dir, "Godeps/Godeps.json"))
758 var cfg1 struct{ ImportPath string }
759 json.Unmarshal(data, &cfg1)
760 if cfg1.ImportPath != "" {
761 return cfg1.ImportPath, nil
762 }
763
764
765 data, _ = os.ReadFile(filepath.Join(dir, "vendor/vendor.json"))
766 var cfg2 struct{ RootPath string }
767 json.Unmarshal(data, &cfg2)
768 if cfg2.RootPath != "" {
769 return cfg2.RootPath, nil
770 }
771
772
773 var badPathErr error
774 for _, gpdir := range filepath.SplitList(cfg.BuildContext.GOPATH) {
775 if gpdir == "" {
776 continue
777 }
778 if rel := search.InDir(dir, filepath.Join(gpdir, "src")); rel != "" && rel != "." {
779 path := filepath.ToSlash(rel)
780
781
782
783
784
785
786
787 if err := checkModulePathLax(path); err != nil {
788 badPathErr = err
789 break
790 }
791 return path, nil
792 }
793 }
794
795 reason := "outside GOPATH, module path must be specified"
796 if badPathErr != nil {
797
798
799 reason = fmt.Sprintf("bad module path inferred from directory in GOPATH: %v", badPathErr)
800 }
801 msg := `cannot determine module path for source directory %s (%s)
802
803 Example usage:
804 'go mod init example.com/m' to initialize a v0 or v1 module
805 'go mod init example.com/m/v2' to initialize a v2 module
806
807 Run 'go help mod init' for more information.
808 `
809 return "", fmt.Errorf(msg, dir, reason)
810 }
811
812 var (
813 importCommentRE = lazyregexp.New(`(?m)^package[ \t]+[^ \t\r\n/]+[ \t]+//[ \t]+import[ \t]+(\"[^"]+\")[ \t]*\r?\n`)
814 )
815
816 func findImportComment(file string) string {
817 data, err := os.ReadFile(file)
818 if err != nil {
819 return ""
820 }
821 m := importCommentRE.FindSubmatch(data)
822 if m == nil {
823 return ""
824 }
825 path, err := strconv.Unquote(string(m[1]))
826 if err != nil {
827 return ""
828 }
829 return path
830 }
831
832 var allowWriteGoMod = true
833
834
835 func DisallowWriteGoMod() {
836 allowWriteGoMod = false
837 }
838
839
840
841
842
843 func AllowWriteGoMod() {
844 allowWriteGoMod = true
845 }
846
847
848
849 func MinReqs() mvs.Reqs {
850 retain := append([]string{}, additionalExplicitRequirements...)
851 for _, m := range buildList[1:] {
852 _, explicit := index.require[m]
853 if explicit || loaded.direct[m.Path] {
854 retain = append(retain, m.Path)
855 }
856 }
857 sort.Strings(retain)
858 str.Uniq(&retain)
859 min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList})
860 if err != nil {
861 base.Fatalf("go: %v", err)
862 }
863 return &mvsReqs{buildList: append([]module.Version{Target}, min...)}
864 }
865
866
867 func WriteGoMod() {
868
869
870
871 if !allowWriteGoMod || cfg.BuildMod == "vendor" {
872 return
873 }
874
875
876 if modRoot == "" {
877 return
878 }
879
880 if cfg.BuildMod != "readonly" {
881 addGoStmt()
882 }
883
884 if loaded != nil {
885 reqs := MinReqs()
886 min, err := reqs.Required(Target)
887 if err != nil {
888 base.Fatalf("go: %v", err)
889 }
890 var list []*modfile.Require
891 for _, m := range min {
892 list = append(list, &modfile.Require{
893 Mod: m,
894 Indirect: !loaded.direct[m.Path],
895 })
896 }
897 modFile.SetRequire(list)
898 }
899 modFile.Cleanup()
900
901 dirty := index.modFileIsDirty(modFile)
902 if dirty && cfg.BuildMod == "readonly" {
903
904
905 if cfg.BuildModExplicit {
906 base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly")
907 } else if cfg.BuildModReason != "" {
908 base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason)
909 } else {
910 base.Fatalf("go: updates to go.mod needed; to update it:\n\tgo mod tidy")
911 }
912 }
913
914 if !dirty && cfg.CmdName != "mod tidy" {
915
916
917
918
919 if cfg.CmdName != "mod init" {
920 modfetch.WriteGoSum(keepSums(true))
921 }
922 return
923 }
924
925 new, err := modFile.Format()
926 if err != nil {
927 base.Fatalf("go: %v", err)
928 }
929 defer func() {
930
931 index = indexModFile(new, modFile, false)
932
933
934
935 if cfg.CmdName != "mod init" {
936 modfetch.WriteGoSum(keepSums(true))
937 }
938 }()
939
940
941
942 if unlock, err := modfetch.SideLock(); err == nil {
943 defer unlock()
944 }
945
946 errNoChange := errors.New("no update needed")
947
948 err = lockedfile.Transform(ModFilePath(), func(old []byte) ([]byte, error) {
949 if bytes.Equal(old, new) {
950
951
952 return nil, errNoChange
953 }
954
955 if index != nil && !bytes.Equal(old, index.data) {
956
957
958
959
960
961
962 return nil, fmt.Errorf("existing contents have changed since last read")
963 }
964
965 return new, nil
966 })
967
968 if err != nil && err != errNoChange {
969 base.Fatalf("go: updating go.mod: %v", err)
970 }
971 }
972
973
974
975
976
977
978
979
980
981
982
983
984 func keepSums(keepBuildListZips bool) map[module.Version]bool {
985
986
987
988 modkey := func(m module.Version) module.Version {
989 return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
990 }
991 keep := make(map[module.Version]bool)
992 var mu sync.Mutex
993 reqs := &keepSumReqs{
994 Reqs: &mvsReqs{buildList: buildList},
995 visit: func(m module.Version) {
996
997
998 mu.Lock()
999 r := Replacement(m)
1000 if r.Path == "" {
1001 keep[modkey(m)] = true
1002 } else {
1003 keep[modkey(r)] = true
1004 }
1005 mu.Unlock()
1006 },
1007 }
1008 buildList, err := mvs.BuildList(Target, reqs)
1009 if err != nil {
1010 panic(fmt.Sprintf("unexpected error reloading build list: %v", err))
1011 }
1012
1013 actualMods := make(map[string]module.Version)
1014 for _, m := range buildList[1:] {
1015 if r := Replacement(m); r.Path != "" {
1016 actualMods[m.Path] = r
1017 } else {
1018 actualMods[m.Path] = m
1019 }
1020 }
1021
1022
1023
1024
1025
1026 if loaded != nil {
1027 for _, pkg := range loaded.pkgs {
1028 if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil {
1029 continue
1030 }
1031 for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) {
1032 if m, ok := actualMods[prefix]; ok {
1033 keep[m] = true
1034 }
1035 }
1036 }
1037 }
1038
1039
1040
1041
1042
1043 if keepBuildListZips {
1044 for _, m := range actualMods {
1045 keep[m] = true
1046 }
1047 }
1048
1049 return keep
1050 }
1051
1052
1053
1054 type keepSumReqs struct {
1055 mvs.Reqs
1056 visit func(module.Version)
1057 }
1058
1059 func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) {
1060 r.visit(m)
1061 return r.Reqs.Required(m)
1062 }
1063
1064 func TrimGoSum() {
1065
1066
1067 keepBuildListZips := false
1068 modfetch.TrimGoSum(keepSums(keepBuildListZips))
1069 }
1070
View as plain text