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 loaderstate *State
43 roots []module.Version
44 }
45
46 func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
47 if mod.Version == "" && r.loaderstate.MainModules.Contains(mod.Path) {
48
49
50 return r.roots, nil
51 }
52
53 if mod.Version == "none" {
54 return nil, nil
55 }
56
57 summary, err := goModSummary(r.loaderstate, mod)
58 if err != nil {
59 return nil, err
60 }
61 return summary.require, nil
62 }
63
64
65
66
67
68
69
70 func (*mvsReqs) Max(p, v1, v2 string) string {
71 if cmpVersion(p, v1, v2) < 0 {
72 return v2
73 }
74 return v1
75 }
76
77
78
79 func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) {
80 return m, nil
81 }
82
83 func versions(loaderstate *State, ctx context.Context, path string, allowed AllowedFunc) (versions []string, origin *codehost.Origin, err error) {
84
85
86 err = modfetch.TryProxies(func(proxy string) error {
87 repo, err := lookupRepo(loaderstate, ctx, proxy, path)
88 if err != nil {
89 return err
90 }
91 allVersions, err := repo.Versions(ctx, "")
92 if err != nil {
93 return err
94 }
95 allowedVersions := make([]string, 0, len(allVersions.List))
96 for _, v := range allVersions.List {
97 if err := allowed(ctx, module.Version{Path: path, Version: v}); err == nil {
98 allowedVersions = append(allowedVersions, v)
99 } else if !errors.Is(err, ErrDisallowed) {
100 return err
101 }
102 }
103 versions = allowedVersions
104 origin = allVersions.Origin
105 return nil
106 })
107 return versions, origin, err
108 }
109
110
111
112
113
114
115 func previousVersion(loaderstate *State, ctx context.Context, m module.Version) (module.Version, error) {
116 if m.Version == "" && loaderstate.MainModules.Contains(m.Path) {
117 return module.Version{Path: m.Path, Version: "none"}, nil
118 }
119
120 list, _, err := versions(loaderstate, ctx, m.Path, loaderstate.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 gover.ModCompare(m.Path, 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 (r *mvsReqs) Previous(m module.Version) (module.Version, error) {
135
136 return previousVersion(r.loaderstate, context.TODO(), m)
137 }
138
View as plain text