1
2
3
4
5 package modload
6
7 import (
8 "context"
9 "errors"
10 "os"
11 "sort"
12
13 "cmd/go/internal/gover"
14 "cmd/go/internal/modfetch"
15 "cmd/go/internal/modfetch/codehost"
16
17 "golang.org/x/mod/module"
18 )
19
20
21
22
23
24
25
26 func cmpVersion(p string, v1, v2 string) int {
27 if v2 == "" {
28 if v1 == "" {
29 return 0
30 }
31 return -1
32 }
33 if v1 == "" {
34 return 1
35 }
36 return gover.ModCompare(p, v1, v2)
37 }
38
39
40
41 type mvsReqs struct {
42 roots []module.Version
43 }
44
45 func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
46 if mod.Version == "" && MainModules.Contains(mod.Path) {
47
48
49 return r.roots, nil
50 }
51
52 if mod.Version == "none" {
53 return nil, nil
54 }
55
56 summary, err := goModSummary(mod)
57 if err != nil {
58 return nil, err
59 }
60 return summary.require, nil
61 }
62
63
64
65
66
67
68
69 func (*mvsReqs) Max(p, v1, v2 string) string {
70 if cmpVersion(p, v1, v2) < 0 {
71 return v2
72 }
73 return v1
74 }
75
76
77
78 func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) {
79 return m, nil
80 }
81
82 func versions(ctx context.Context, path string, allowed AllowedFunc) (versions []string, origin *codehost.Origin, err error) {
83
84
85 err = modfetch.TryProxies(func(proxy string) error {
86 repo, err := lookupRepo(ctx, proxy, path)
87 if err != nil {
88 return err
89 }
90 allVersions, err := repo.Versions(ctx, "")
91 if err != nil {
92 return err
93 }
94 allowedVersions := make([]string, 0, len(allVersions.List))
95 for _, v := range allVersions.List {
96 if err := allowed(ctx, module.Version{Path: path, Version: v}); err == nil {
97 allowedVersions = append(allowedVersions, v)
98 } else if !errors.Is(err, ErrDisallowed) {
99 return err
100 }
101 }
102 versions = allowedVersions
103 origin = allVersions.Origin
104 return nil
105 })
106 return versions, origin, err
107 }
108
109
110
111
112
113
114 func previousVersion(ctx context.Context, m module.Version) (module.Version, error) {
115 if m.Version == "" && MainModules.Contains(m.Path) {
116 return module.Version{Path: m.Path, Version: "none"}, nil
117 }
118
119 list, _, err := versions(ctx, m.Path, CheckAllowed)
120 if err != nil {
121 if errors.Is(err, os.ErrNotExist) {
122 return module.Version{Path: m.Path, Version: "none"}, nil
123 }
124 return module.Version{}, err
125 }
126 i := sort.Search(len(list), func(i int) bool { return gover.ModCompare(m.Path, list[i], m.Version) >= 0 })
127 if i > 0 {
128 return module.Version{Path: m.Path, Version: list[i-1]}, nil
129 }
130 return module.Version{Path: m.Path, Version: "none"}, nil
131 }
132
133 func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
134
135 return previousVersion(context.TODO(), m)
136 }
137
View as plain text