1 # https://golang.org/issue/45094: 'go mod tidy' now accepts a '-go' flag
2 # to change the language version in use.
3 #
4 # The package import graph used in this test looks like:
5 #
6 # m --- a --- b
7 # |
8 # b_test --- c
9 # |
10 # c_test --- d
11 #
12 # The module diagram looks like:
13 #
14 # m --- a --- b
15 # |
16 # + --- c
17 # |
18 # + --- d
19 #
20 # Module b omits its dependency on c, and module c omits its dependency on d.
21 #
22 # In go 1.15, the tidy main module must require a (because it is direct),
23 # c (because it is a missing test dependency of an imported package),
24 # and d (because it is a missing transitive test dependency).
25 #
26 # In go 1.16, the tidy main module can omit d because it is no longer
27 # included in "all".
28 #
29 # In go 1.17, the main module must explicitly require b
30 # (because it is transitively imported by the main module).
31
32 cp go.mod go.mod.orig
33
34 # Pretend we're a release version so that we can theoretically
35 # write our version in toolchain lines.
36 env goversion=1.99.0
37 env TESTGO_VERSION=go${goversion}
38
39 # An invalid argument should be rejected.
40
41 ! go mod tidy -go=bananas
42 stderr '^invalid value "bananas" for flag -go: expecting a Go version like "'$goversion'"$'
43 cmp go.mod go.mod.orig
44
45 ! go mod tidy -go=0.9
46 stderr '^invalid value "0.9" for flag -go: expecting a Go version like "'$goversion'"$'
47
48 ! go mod tidy -go=2000.0
49 stderr '^invalid value "2000.0" for flag -go: maximum supported Go version is '$goversion'$'
50
51
52 # Supported versions should change the go.mod file to be tidy according to the
53 # indicated version.
54
55 go mod tidy -go=1.15
56 cmp go.mod go.mod.115
57
58 go mod tidy
59 cmp go.mod go.mod.115
60
61
62 go mod tidy -go=1.16
63 cmp go.mod go.mod.116
64
65 go mod tidy
66 cmp go.mod go.mod.116
67
68
69 go mod tidy -go=1.17
70 cmp go.mod go.mod.117
71
72 go mod tidy
73 cmp go.mod go.mod.117
74
75
76 # If we downgrade back to 1.15, we should re-resolve d to v0.2.0 instead
77 # of the original v0.1.0 (because the original requirement is lost).
78
79 go mod tidy -go=1.15
80 cmp go.mod go.mod.115-2
81
82
83 # -go= (with an empty argument) maintains the existing version or adds the
84 # default version (just like omitting the flag).
85
86 go mod tidy -go=''
87 cmp go.mod go.mod.115-2
88
89 cp go.mod.orig go.mod
90 go mod tidy -go=''
91 cmpenv go.mod go.mod.latest
92
93 # Repeat with go get go@ instead of mod tidy.
94
95 # Go 1.16 -> 1.17 should be a no-op.
96 cp go.mod.116 go.mod
97 go get go@1.16
98 cmp go.mod go.mod.116
99
100 # Go 1.17 -> 1.16 should leave b (go get is not tidy).
101 cp go.mod.117 go.mod
102 go get go@1.16
103 cmp go.mod go.mod.116from117
104
105 # Go 1.15 -> 1.16 should leave d (go get is not tidy).
106 cp go.mod.115 go.mod
107 go get go@1.16
108 cmp go.mod go.mod.116from115
109
110 # Go 1.16 -> 1.17 should add b.
111 cp go.mod.116 go.mod
112 go get go@1.17
113 stderr '^\tnote: expanded dependencies to upgrade to go 1.17 or higher; run ''go mod tidy'' to clean up'
114 cmp go.mod go.mod.117
115
116 # Go 1.16 -> 1.15 should add d,
117 # but 'go get' doesn't load enough packages to know that.
118 # (This leaves the module untidy, but the user can fix it by running 'go mod tidy'.)
119 cp go.mod.116 go.mod
120 go get go@1.15 toolchain@none
121 cmp go.mod go.mod.115from116
122 go mod tidy
123 cmp go.mod go.mod.115-2
124
125 # Updating the go line to 1.21 or higher also updates the toolchain line,
126 # only if the toolchain is higher than what would be implied by the go line.
127
128 cp go.mod.117 go.mod
129 go mod tidy -go=$goversion
130 cmpenv go.mod go.mod.latest
131
132 cp go.mod.117 go.mod
133 go mod tidy -go=1.21.0 # lower than $goversion
134 cmpenv go.mod go.mod.121toolchain
135
136
137 -- go.mod --
138 module example.com/m
139
140 require example.net/a v0.1.0
141
142 require (
143 example.net/c v0.1.0 // indirect
144 example.net/d v0.1.0 // indirect
145 )
146
147 replace (
148 example.net/a v0.1.0 => ./a
149 example.net/a v0.2.0 => ./a
150 example.net/b v0.1.0 => ./b
151 example.net/b v0.2.0 => ./b
152 example.net/c v0.1.0 => ./c
153 example.net/c v0.2.0 => ./c
154 example.net/d v0.1.0 => ./d
155 example.net/d v0.2.0 => ./d
156 )
157 -- m.go --
158 package m
159
160 import _ "example.net/a"
161
162 -- go.mod.115 --
163 module example.com/m
164
165 go 1.15
166
167 require example.net/a v0.1.0
168
169 require (
170 example.net/c v0.1.0 // indirect
171 example.net/d v0.1.0 // indirect
172 )
173
174 replace (
175 example.net/a v0.1.0 => ./a
176 example.net/a v0.2.0 => ./a
177 example.net/b v0.1.0 => ./b
178 example.net/b v0.2.0 => ./b
179 example.net/c v0.1.0 => ./c
180 example.net/c v0.2.0 => ./c
181 example.net/d v0.1.0 => ./d
182 example.net/d v0.2.0 => ./d
183 )
184 -- go.mod.115from116 --
185 module example.com/m
186
187 go 1.15
188
189 require example.net/a v0.1.0
190
191 require example.net/c v0.1.0 // indirect
192
193 replace (
194 example.net/a v0.1.0 => ./a
195 example.net/a v0.2.0 => ./a
196 example.net/b v0.1.0 => ./b
197 example.net/b v0.2.0 => ./b
198 example.net/c v0.1.0 => ./c
199 example.net/c v0.2.0 => ./c
200 example.net/d v0.1.0 => ./d
201 example.net/d v0.2.0 => ./d
202 )
203 -- go.mod.116from115 --
204 module example.com/m
205
206 go 1.16
207
208 require example.net/a v0.1.0
209
210 require (
211 example.net/c v0.1.0 // indirect
212 example.net/d v0.1.0 // indirect
213 )
214
215 replace (
216 example.net/a v0.1.0 => ./a
217 example.net/a v0.2.0 => ./a
218 example.net/b v0.1.0 => ./b
219 example.net/b v0.2.0 => ./b
220 example.net/c v0.1.0 => ./c
221 example.net/c v0.2.0 => ./c
222 example.net/d v0.1.0 => ./d
223 example.net/d v0.2.0 => ./d
224 )
225 -- go.mod.115-2 --
226 module example.com/m
227
228 go 1.15
229
230 require example.net/a v0.1.0
231
232 require (
233 example.net/c v0.1.0 // indirect
234 example.net/d v0.2.0 // indirect
235 )
236
237 replace (
238 example.net/a v0.1.0 => ./a
239 example.net/a v0.2.0 => ./a
240 example.net/b v0.1.0 => ./b
241 example.net/b v0.2.0 => ./b
242 example.net/c v0.1.0 => ./c
243 example.net/c v0.2.0 => ./c
244 example.net/d v0.1.0 => ./d
245 example.net/d v0.2.0 => ./d
246 )
247 -- go.mod.116 --
248 module example.com/m
249
250 go 1.16
251
252 require example.net/a v0.1.0
253
254 require example.net/c v0.1.0 // indirect
255
256 replace (
257 example.net/a v0.1.0 => ./a
258 example.net/a v0.2.0 => ./a
259 example.net/b v0.1.0 => ./b
260 example.net/b v0.2.0 => ./b
261 example.net/c v0.1.0 => ./c
262 example.net/c v0.2.0 => ./c
263 example.net/d v0.1.0 => ./d
264 example.net/d v0.2.0 => ./d
265 )
266 -- go.mod.117 --
267 module example.com/m
268
269 go 1.17
270
271 require example.net/a v0.1.0
272
273 require (
274 example.net/b v0.1.0 // indirect
275 example.net/c v0.1.0 // indirect
276 )
277
278 replace (
279 example.net/a v0.1.0 => ./a
280 example.net/a v0.2.0 => ./a
281 example.net/b v0.1.0 => ./b
282 example.net/b v0.2.0 => ./b
283 example.net/c v0.1.0 => ./c
284 example.net/c v0.2.0 => ./c
285 example.net/d v0.1.0 => ./d
286 example.net/d v0.2.0 => ./d
287 )
288 -- go.mod.116from117 --
289 module example.com/m
290
291 go 1.16
292
293 require example.net/a v0.1.0
294
295 require (
296 example.net/b v0.1.0 // indirect
297 example.net/c v0.1.0 // indirect
298 )
299
300 replace (
301 example.net/a v0.1.0 => ./a
302 example.net/a v0.2.0 => ./a
303 example.net/b v0.1.0 => ./b
304 example.net/b v0.2.0 => ./b
305 example.net/c v0.1.0 => ./c
306 example.net/c v0.2.0 => ./c
307 example.net/d v0.1.0 => ./d
308 example.net/d v0.2.0 => ./d
309 )
310 -- go.mod.latest --
311 module example.com/m
312
313 go $goversion
314
315 require example.net/a v0.1.0
316
317 require (
318 example.net/b v0.1.0 // indirect
319 example.net/c v0.1.0 // indirect
320 )
321
322 replace (
323 example.net/a v0.1.0 => ./a
324 example.net/a v0.2.0 => ./a
325 example.net/b v0.1.0 => ./b
326 example.net/b v0.2.0 => ./b
327 example.net/c v0.1.0 => ./c
328 example.net/c v0.2.0 => ./c
329 example.net/d v0.1.0 => ./d
330 example.net/d v0.2.0 => ./d
331 )
332 -- go.mod.121toolchain --
333 module example.com/m
334
335 go 1.21.0
336
337 toolchain $TESTGO_VERSION
338
339 require example.net/a v0.1.0
340
341 require (
342 example.net/b v0.1.0 // indirect
343 example.net/c v0.1.0 // indirect
344 )
345
346 replace (
347 example.net/a v0.1.0 => ./a
348 example.net/a v0.2.0 => ./a
349 example.net/b v0.1.0 => ./b
350 example.net/b v0.2.0 => ./b
351 example.net/c v0.1.0 => ./c
352 example.net/c v0.2.0 => ./c
353 example.net/d v0.1.0 => ./d
354 example.net/d v0.2.0 => ./d
355 )
356 -- a/go.mod --
357 module example.net/a
358
359 go 1.15
360
361 require example.net/b v0.1.0
362 -- a/a.go --
363 package a
364
365 import _ "example.net/b"
366
367 -- b/go.mod --
368 module example.net/b
369
370 go 1.15
371 -- b/b.go --
372 package b
373 -- b/b_test.go --
374 package b_test
375
376 import _ "example.net/c"
377
378 -- c/go.mod --
379 module example.net/c
380
381 go 1.15
382 -- c/c.go --
383 package c
384 -- c/c_test.go --
385 package c_test
386
387 import _ "example.net/d"
388
389 -- d/go.mod --
390 module example.net/d
391
392 go 1.15
393 -- d/d.go --
394 package d
395
View as plain text