]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/go/internal/modload/modfile.go
[dev.cmdgo] all: merge master (9eee0ed) into dev.cmdgo
[gostls13.git] / src / cmd / go / internal / modload / modfile.go
index 03e02e73b63f659f0ec6e3eff89299f691763c6d..31e79a36460b4cb8cad8bb6749eadb2fd2945734 100644 (file)
@@ -56,11 +56,13 @@ const (
        go117LazyTODO = false
 )
 
-var modFile *modfile.File
-
 // modFileGoVersion returns the (non-empty) Go version at which the requirements
 // in modFile are intepreted, or the latest Go version if modFile is nil.
 func modFileGoVersion() string {
+       _ = TODOWorkspaces("this is obviously wrong.")
+       // Yes we're picking arbitrarily, we'll have to pass through the version
+       // we care about
+       modFile := MainModules.ModFile(MainModules.Versions()[0])
        if modFile == nil {
                return LatestGoVersion()
        }
@@ -92,9 +94,6 @@ type modFileIndex struct {
        exclude         map[module.Version]bool
 }
 
-// index is the index of the go.mod file as of when it was last read or written.
-var index *modFileIndex
-
 type requireMeta struct {
        indirect bool
 }
@@ -137,8 +136,10 @@ var ErrDisallowed = errors.New("disallowed module version")
 // CheckExclusions returns an error equivalent to ErrDisallowed if module m is
 // excluded by the main module's go.mod file.
 func CheckExclusions(ctx context.Context, m module.Version) error {
-       if index != nil && index.exclude[m] {
-               return module.VersionError(m, errExcluded)
+       for _, mainModule := range MainModules.Versions() {
+               if index := MainModules.Index(mainModule); index != nil && index.exclude[m] {
+                       return module.VersionError(m, errExcluded)
+               }
        }
        return nil
 }
@@ -306,19 +307,37 @@ func CheckDeprecation(ctx context.Context, m module.Version) (deprecation string
        return summary.deprecated, nil
 }
 
+func replacement(mod module.Version, index *modFileIndex) (fromVersion string, to module.Version, ok bool) {
+       if r, ok := index.replace[mod]; ok {
+               return mod.Version, r, true
+       }
+       if r, ok := index.replace[module.Version{Path: mod.Path}]; ok {
+               return "", r, true
+       }
+       return "", module.Version{}, false
+}
+
 // Replacement returns the replacement for mod, if any, from go.mod.
 // If there is no replacement for mod, Replacement returns
 // a module.Version with Path == "".
 func Replacement(mod module.Version) module.Version {
-       if index != nil {
-               if r, ok := index.replace[mod]; ok {
-                       return r
-               }
-               if r, ok := index.replace[module.Version{Path: mod.Path}]; ok {
-                       return r
+       _ = TODOWorkspaces("support replaces in the go.work file")
+       foundFrom, found, foundModRoot := "", module.Version{}, ""
+       for _, v := range MainModules.Versions() {
+               if index := MainModules.Index(v); index != nil {
+                       if from, r, ok := replacement(mod, index); ok {
+                               modRoot := MainModules.ModRoot(v)
+                               if foundModRoot != "" && foundFrom != from && found != r {
+                                       _ = TODOWorkspaces("once the go.work file supports replaces, recommend them as a way to override conflicts")
+                                       base.Errorf("conflicting replacements found for %v in workspace modules defined by %v and %v",
+                                               mod, modFilePath(foundModRoot), modFilePath(modRoot))
+                                       return found
+                               }
+                               found, foundModRoot = r, modRoot
+                       }
                }
        }
-       return module.Version{}
+       return found
 }
 
 // resolveReplacement returns the module actually used to load the source code
@@ -333,7 +352,7 @@ func resolveReplacement(m module.Version) module.Version {
 // indexModFile rebuilds the index of modFile.
 // If modFile has been changed since it was first read,
 // modFile.Cleanup must be called before indexModFile.
-func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex {
+func indexModFile(data []byte, modFile *modfile.File, mod module.Version, needsFix bool) *modFileIndex {
        i := new(modFileIndex)
        i.data = data
        i.dataNeedsFix = needsFix
@@ -345,12 +364,12 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd
 
        i.goVersionV = ""
        if modFile.Go == nil {
-               rawGoVersion.Store(Target, "")
+               rawGoVersion.Store(mod, "")
        } else {
                // We're going to use the semver package to compare Go versions, so go ahead
                // and add the "v" prefix it expects once instead of every time.
                i.goVersionV = "v" + modFile.Go.Version
-               rawGoVersion.Store(Target, modFile.Go.Version)
+               rawGoVersion.Store(mod, modFile.Go.Version)
        }
 
        i.require = make(map[module.Version]requireMeta, len(modFile.Require))
@@ -490,8 +509,8 @@ type retraction struct {
 //
 // The caller must not modify the returned summary.
 func goModSummary(m module.Version) (*modFileSummary, error) {
-       if m == Target {
-               panic("internal error: goModSummary called on the Target module")
+       if m.Version == "" && MainModules.Contains(m.Path) {
+               panic("internal error: goModSummary called on a main module")
        }
 
        if cfg.BuildMod == "vendor" {
@@ -515,7 +534,7 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
        }
 
        actual := resolveReplacement(m)
-       if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" {
+       if HasModRoot() && cfg.BuildMod == "readonly" && !inWorkspaceMode() && actual.Version != "" {
                key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
                if !modfetch.HaveSum(key) {
                        suggestion := fmt.Sprintf("; to add it:\n\tgo mod download %s", m.Path)
@@ -553,27 +572,29 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
                }
        }
 
-       if index != nil && len(index.exclude) > 0 {
-               // Drop any requirements on excluded versions.
-               // Don't modify the cached summary though, since we might need the raw
-               // summary separately.
-               haveExcludedReqs := false
-               for _, r := range summary.require {
-                       if index.exclude[r] {
-                               haveExcludedReqs = true
-                               break
-                       }
-               }
-               if haveExcludedReqs {
-                       s := new(modFileSummary)
-                       *s = *summary
-                       s.require = make([]module.Version, 0, len(summary.require))
+       for _, mainModule := range MainModules.Versions() {
+               if index := MainModules.Index(mainModule); index != nil && len(index.exclude) > 0 {
+                       // Drop any requirements on excluded versions.
+                       // Don't modify the cached summary though, since we might need the raw
+                       // summary separately.
+                       haveExcludedReqs := false
                        for _, r := range summary.require {
-                               if !index.exclude[r] {
-                                       s.require = append(s.require, r)
+                               if index.exclude[r] {
+                                       haveExcludedReqs = true
+                                       break
+                               }
+                       }
+                       if haveExcludedReqs {
+                               s := new(modFileSummary)
+                               *s = *summary
+                               s.require = make([]module.Version, 0, len(summary.require))
+                               for _, r := range summary.require {
+                                       if !index.exclude[r] {
+                                               s.require = append(s.require, r)
+                                       }
                                }
+                               summary = s
                        }
-                       summary = s
                }
        }
        return summary, nil
@@ -585,7 +606,7 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
 //
 // rawGoModSummary cannot be used on the Target module.
 func rawGoModSummary(m module.Version) (*modFileSummary, error) {
-       if m == Target {
+       if m.Path == "" && MainModules.Contains(m.Path) {
                panic("internal error: rawGoModSummary called on the Target module")
        }