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