5
5
package modload
6
6
7
7
import (
8
- "cmd/go/internal/base"
9
- "cmd/go/internal/cfg"
10
- "cmd/go/internal/gover"
11
- "cmd/go/internal/mvs"
12
- "cmd/go/internal/par"
13
- "cmd/go/internal/slices"
14
8
"context"
15
9
"errors"
16
10
"fmt"
17
11
"os"
18
12
"reflect"
19
13
"runtime"
20
14
"runtime/debug"
15
+ "slices"
21
16
"strings"
22
17
"sync"
23
18
"sync/atomic"
24
19
20
+ "cmd/go/internal/base"
21
+ "cmd/go/internal/cfg"
22
+ "cmd/go/internal/gover"
23
+ "cmd/go/internal/mvs"
24
+ "cmd/go/internal/par"
25
+
25
26
"golang.org/x/mod/module"
26
27
)
27
28
@@ -91,6 +92,15 @@ type cachedGraph struct {
91
92
// accept and/or return an explicit parameter.
92
93
var requirements * Requirements
93
94
95
+ func mustHaveGoRoot (roots []module.Version ) {
96
+ for _ , m := range roots {
97
+ if m .Path == "go" {
98
+ return
99
+ }
100
+ }
101
+ panic ("go: internal error: missing go root module" )
102
+ }
103
+
94
104
// newRequirements returns a new requirement set with the given root modules.
95
105
// The dependencies of the roots will be loaded lazily at the first call to the
96
106
// Graph method.
@@ -102,6 +112,8 @@ var requirements *Requirements
102
112
// If vendoring is in effect, the caller must invoke initVendor on the returned
103
113
// *Requirements before any other method.
104
114
func newRequirements (pruning modPruning , rootModules []module.Version , direct map [string ]bool ) * Requirements {
115
+ mustHaveGoRoot (rootModules )
116
+
105
117
if pruning == workspace {
106
118
return & Requirements {
107
119
pruning : pruning ,
@@ -114,25 +126,28 @@ func newRequirements(pruning modPruning, rootModules []module.Version, direct ma
114
126
if workFilePath != "" && pruning != workspace {
115
127
panic ("in workspace mode, but pruning is not workspace in newRequirements" )
116
128
}
117
-
118
129
for i , m := range rootModules {
119
130
if m .Version == "" && MainModules .Contains (m .Path ) {
120
131
panic (fmt .Sprintf ("newRequirements called with untrimmed build list: rootModules[%v] is a main module" , i ))
121
132
}
122
133
if m .Path == "" || m .Version == "" {
123
134
panic (fmt .Sprintf ("bad requirement: rootModules[%v] = %v" , i , m ))
124
135
}
125
- if i > 0 {
126
- prev := rootModules [i - 1 ]
127
- if prev .Path > m .Path || (prev .Path == m .Path && gover .ModCompare (m .Path , prev .Version , m .Version ) > 0 ) {
128
- panic (fmt .Sprintf ("newRequirements called with unsorted roots: %v" , rootModules ))
129
- }
130
- }
136
+ }
137
+
138
+ // Allow unsorted root modules, because go and toolchain
139
+ // are treated as the final graph roots but not trimmed from the build list,
140
+ // so they always appear at the beginning of the list.
141
+ r := slices .Clip (slices .Clone (rootModules ))
142
+ gover .ModSort (r )
143
+ if ! reflect .DeepEqual (r , rootModules ) {
144
+ fmt .Fprintln (os .Stderr , "RM" , rootModules )
145
+ panic ("unsorted" )
131
146
}
132
147
133
148
rs := & Requirements {
134
149
pruning : pruning ,
135
- rootModules : slices . Clip ( rootModules ) ,
150
+ rootModules : rootModules ,
136
151
maxRootVersion : make (map [string ]string , len (rootModules )),
137
152
direct : direct ,
138
153
}
@@ -157,7 +172,7 @@ func (rs *Requirements) String() string {
157
172
func (rs * Requirements ) initVendor (vendorList []module.Version ) {
158
173
rs .graphOnce .Do (func () {
159
174
mg := & ModuleGraph {
160
- g : mvs .NewGraph (cmpVersion , MainModules .GraphRoots ()),
175
+ g : mvs .NewGraph (cmpVersion , MainModules .Versions ()),
161
176
}
162
177
163
178
if MainModules .Len () != 1 {
@@ -278,6 +293,7 @@ var readModGraphDebugOnce sync.Once
278
293
// Unlike LoadModGraph, readModGraph does not attempt to diagnose or update
279
294
// inconsistent roots.
280
295
func readModGraph (ctx context.Context , pruning modPruning , roots []module.Version , unprune map [module.Version ]bool ) (* ModuleGraph , error ) {
296
+ mustHaveGoRoot (roots )
281
297
if pruning == pruned {
282
298
// Enable diagnostics for lazy module loading
283
299
// (https://golang.org/ref/mod#lazy-loading) only if the module graph is
@@ -301,13 +317,20 @@ func readModGraph(ctx context.Context, pruning modPruning, roots []module.Versio
301
317
})
302
318
}
303
319
320
+ var graphRoots []module.Version
321
+ if inWorkspaceMode () {
322
+ graphRoots = roots
323
+ } else {
324
+ graphRoots = MainModules .Versions ()
325
+ }
304
326
var (
305
327
mu sync.Mutex // guards mg.g and hasError during loading
306
328
hasError bool
307
329
mg = & ModuleGraph {
308
- g : mvs .NewGraph (cmpVersion , MainModules . GraphRoots () ),
330
+ g : mvs .NewGraph (cmpVersion , graphRoots ),
309
331
}
310
332
)
333
+
311
334
if pruning != workspace {
312
335
if inWorkspaceMode () {
313
336
panic ("pruning is not workspace in workspace mode" )
@@ -380,6 +403,7 @@ func readModGraph(ctx context.Context, pruning modPruning, roots []module.Versio
380
403
})
381
404
}
382
405
406
+ mustHaveGoRoot (roots )
383
407
for _ , m := range roots {
384
408
enqueue (m , pruning )
385
409
}
@@ -789,6 +813,10 @@ func tidyPrunedRoots(ctx context.Context, mainModule module.Version, old *Requir
789
813
roots = append (roots , module.Version {Path : "go" , Version : v })
790
814
pathIsRoot ["go" ] = true
791
815
}
816
+ if v , ok := old .rootSelected ("toolchain" ); ok {
817
+ roots = append (roots , module.Version {Path : "toolchain" , Version : v })
818
+ pathIsRoot ["toolchain" ] = true
819
+ }
792
820
// We start by adding roots for every package in "all".
793
821
//
794
822
// Once that is done, we may still need to add more roots to cover upgraded or
@@ -1254,6 +1282,11 @@ func tidyUnprunedRoots(ctx context.Context, mainModule module.Version, old *Requ
1254
1282
)
1255
1283
if v , ok := old .rootSelected ("go" ); ok {
1256
1284
keep = append (keep , module.Version {Path : "go" , Version : v })
1285
+ keptPath ["go" ] = true
1286
+ }
1287
+ if v , ok := old .rootSelected ("toolchain" ); ok {
1288
+ keep = append (keep , module.Version {Path : "toolchain" , Version : v })
1289
+ keptPath ["toolchain" ] = true
1257
1290
}
1258
1291
for _ , pkg := range pkgs {
1259
1292
if ! pkg .fromExternalModule () {
0 commit comments