@@ -35,11 +35,30 @@ import (
35
35
"golang.org/x/mod/semver"
36
36
)
37
37
38
+ // Variables set by other packages.
39
+ //
40
+ // TODO(#40775): See if these can be plumbed as explicit parameters.
41
+ var (
42
+ // RootMode determines whether a module root is needed.
43
+ RootMode Root
44
+
45
+ // ForceUseModules may be set to force modules to be enabled when
46
+ // GO111MODULE=auto or to report an error when GO111MODULE=off.
47
+ ForceUseModules bool
48
+
49
+ allowMissingModuleImports bool
50
+ )
51
+
52
+ // Variables set in Init.
38
53
var (
39
54
initialized bool
55
+ modRoot string
56
+ gopath string
57
+ )
40
58
41
- modRoot string
42
- Target module.Version
59
+ // Variables set in initTarget (during {Load,Create}ModFile).
60
+ var (
61
+ Target module.Version
43
62
44
63
// targetPrefix is the path prefix for packages in Target, without a trailing
45
64
// slash. For most modules, targetPrefix is just Target.Path, but the
49
68
// targetInGorootSrc caches whether modRoot is within GOROOT/src.
50
69
// The "std" module is special within GOROOT/src, but not otherwise.
51
70
targetInGorootSrc bool
52
-
53
- gopath string
54
-
55
- // RootMode determines whether a module root is needed.
56
- RootMode Root
57
-
58
- // ForceUseModules may be set to force modules to be enabled when
59
- // GO111MODULE=auto or to report an error when GO111MODULE=off.
60
- ForceUseModules bool
61
-
62
- allowMissingModuleImports bool
63
71
)
64
72
65
73
type Root int
@@ -362,6 +370,7 @@ func LoadModFile(ctx context.Context) {
362
370
Target = module.Version {Path : "command-line-arguments" }
363
371
targetPrefix = "command-line-arguments"
364
372
buildList = []module.Version {Target }
373
+ rawGoVersion .Store (Target , latestGoVersion ())
365
374
return
366
375
}
367
376
@@ -377,24 +386,29 @@ func LoadModFile(ctx context.Context) {
377
386
// Errors returned by modfile.Parse begin with file:line.
378
387
base .Fatalf ("go: errors parsing go.mod:\n %s\n " , err )
379
388
}
380
- modFile = f
381
- index = indexModFile (data , f , fixed )
382
-
383
389
if f .Module == nil {
384
390
// No module declaration. Must add module path.
385
391
base .Fatalf ("go: no module declaration in go.mod. To specify the module path:\n \t go mod edit -module=example.com/mod" )
386
392
}
387
393
394
+ modFile = f
395
+ initTarget (f .Module .Mod )
396
+ index = indexModFile (data , f , fixed )
397
+
388
398
if err := checkModulePathLax (f .Module .Mod .Path ); err != nil {
389
399
base .Fatalf ("go: %v" , err )
390
400
}
391
401
392
402
setDefaultBuildMod () // possibly enable automatic vendoring
393
- modFileToBuildList ()
403
+ buildList = modFileToBuildList (modFile )
394
404
if cfg .BuildMod == "vendor" {
395
405
readVendorList ()
396
406
checkVendorConsistency ()
397
407
}
408
+ if index .goVersionV == "" && cfg .BuildMod == "mod" {
409
+ addGoStmt ()
410
+ WriteGoMod ()
411
+ }
398
412
}
399
413
400
414
// CreateModFile initializes a new module by creating a go.mod file.
@@ -427,6 +441,7 @@ func CreateModFile(ctx context.Context, modPath string) {
427
441
fmt .Fprintf (os .Stderr , "go: creating new go.mod: module %s\n " , modPath )
428
442
modFile = new (modfile.File )
429
443
modFile .AddModuleStmt (modPath )
444
+ initTarget (modFile .Module .Mod )
430
445
addGoStmt () // Add the go directive before converted module requirements.
431
446
432
447
convertedFrom , err := convertLegacyConfig (modPath )
@@ -437,7 +452,7 @@ func CreateModFile(ctx context.Context, modPath string) {
437
452
base .Fatalf ("go: %v" , err )
438
453
}
439
454
440
- modFileToBuildList ()
455
+ buildList = modFileToBuildList (modFile )
441
456
WriteGoMod ()
442
457
443
458
// Suggest running 'go mod tidy' unless the project is empty. Even if we
@@ -563,19 +578,31 @@ func AllowMissingModuleImports() {
563
578
allowMissingModuleImports = true
564
579
}
565
580
566
- // modFileToBuildList initializes buildList from the modFile.
567
- func modFileToBuildList () {
568
- Target = modFile .Module .Mod
569
- targetPrefix = Target .Path
581
+ // initTarget sets Target and associated variables according to modFile,
582
+ func initTarget (m module.Version ) {
583
+ Target = m
584
+ targetPrefix = m .Path
585
+
570
586
if rel := search .InDir (base .Cwd , cfg .GOROOTsrc ); rel != "" {
571
587
targetInGorootSrc = true
572
- if Target .Path == "std" {
588
+ if m .Path == "std" {
589
+ // The "std" module in GOROOT/src is the Go standard library. Unlike other
590
+ // modules, the packages in the "std" module have no import-path prefix.
591
+ //
592
+ // Modules named "std" outside of GOROOT/src do not receive this special
593
+ // treatment, so it is possible to run 'go test .' in other GOROOTs to
594
+ // test individual packages using a combination of the modified package
595
+ // and the ordinary standard library.
596
+ // (See https://golang.org/issue/30756.)
573
597
targetPrefix = ""
574
598
}
575
599
}
600
+ }
576
601
602
+ // modFileToBuildList returns the list of non-excluded requirements from f.
603
+ func modFileToBuildList (f * modfile.File ) []module.Version {
577
604
list := []module.Version {Target }
578
- for _ , r := range modFile .Require {
605
+ for _ , r := range f .Require {
579
606
if index != nil && index .exclude [r .Mod ] {
580
607
if cfg .BuildMod == "mod" {
581
608
fmt .Fprintf (os .Stderr , "go: dropping requirement on excluded version %s %s\n " , r .Mod .Path , r .Mod .Version )
@@ -586,7 +613,7 @@ func modFileToBuildList() {
586
613
list = append (list , r .Mod )
587
614
}
588
615
}
589
- buildList = list
616
+ return list
590
617
}
591
618
592
619
// setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
@@ -650,20 +677,29 @@ func convertLegacyConfig(modPath string) (from string, err error) {
650
677
return "" , nil
651
678
}
652
679
653
- // addGoStmt adds a go directive to the go.mod file if it does not already include one.
654
- // The 'go' version added, if any, is the latest version supported by this toolchain.
680
+ // addGoStmt adds a go directive to the go.mod file if it does not already
681
+ // include one. The 'go' version added, if any, is the latest version supported
682
+ // by this toolchain.
655
683
func addGoStmt () {
656
684
if modFile .Go != nil && modFile .Go .Version != "" {
657
685
return
658
686
}
687
+ v := latestGoVersion ()
688
+ if err := modFile .AddGoStmt (v ); err != nil {
689
+ base .Fatalf ("go: internal error: %v" , err )
690
+ }
691
+ rawGoVersion .Store (Target , v )
692
+ }
693
+
694
+ // latestGoVersion returns the latest version of the Go language supported by
695
+ // this toolchain.
696
+ func latestGoVersion () string {
659
697
tags := build .Default .ReleaseTags
660
698
version := tags [len (tags )- 1 ]
661
699
if ! strings .HasPrefix (version , "go" ) || ! modfile .GoVersionRE .MatchString (version [2 :]) {
662
700
base .Fatalf ("go: unrecognized default version %q" , version )
663
701
}
664
- if err := modFile .AddGoStmt (version [2 :]); err != nil {
665
- base .Fatalf ("go: internal error: %v" , err )
666
- }
702
+ return version [2 :]
667
703
}
668
704
669
705
var altConfigs = []string {
@@ -880,10 +916,6 @@ func WriteGoMod() {
880
916
return
881
917
}
882
918
883
- if cfg .BuildMod != "readonly" {
884
- addGoStmt ()
885
- }
886
-
887
919
if loaded != nil {
888
920
reqs := MinReqs ()
889
921
min , err := reqs .Required (Target )
@@ -1010,7 +1042,12 @@ func keepSums(keepBuildListZips bool) map[module.Version]bool {
1010
1042
}
1011
1043
buildList , err := mvs .BuildList (Target , reqs )
1012
1044
if err != nil {
1013
- panic (fmt .Sprintf ("unexpected error reloading build list: %v" , err ))
1045
+ // This call to mvs.BuildList should not fail if we have already read the
1046
+ // complete build list. However, the initial “build list” initialized by
1047
+ // modFileToBuildList is not complete: it contains only the explicit
1048
+ // dependencies of the main module. So this call can fair if this is the
1049
+ // first time we have actually loaded the real build list.
1050
+ base .Fatalf ("go: %v" , err )
1014
1051
}
1015
1052
1016
1053
actualMods := make (map [string ]module.Version )
0 commit comments