summaryrefslogtreecommitdiffstats
path: root/src/cmd/go/internal/modconv/convert.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:14:23 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:14:23 +0000
commit73df946d56c74384511a194dd01dbe099584fd1a (patch)
treefd0bcea490dd81327ddfbb31e215439672c9a068 /src/cmd/go/internal/modconv/convert.go
parentInitial commit. (diff)
downloadgolang-1.16-upstream.tar.xz
golang-1.16-upstream.zip
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/go/internal/modconv/convert.go')
-rw-r--r--src/cmd/go/internal/modconv/convert.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/cmd/go/internal/modconv/convert.go b/src/cmd/go/internal/modconv/convert.go
new file mode 100644
index 0000000..5d4165c
--- /dev/null
+++ b/src/cmd/go/internal/modconv/convert.go
@@ -0,0 +1,108 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package modconv
+
+import (
+ "fmt"
+ "os"
+ "runtime"
+ "sort"
+ "strings"
+
+ "cmd/go/internal/base"
+ "cmd/go/internal/modfetch"
+
+ "golang.org/x/mod/modfile"
+ "golang.org/x/mod/module"
+ "golang.org/x/mod/semver"
+)
+
+// ConvertLegacyConfig converts legacy config to modfile.
+// The file argument is slash-delimited.
+func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error {
+ i := strings.LastIndex(file, "/")
+ j := -2
+ if i >= 0 {
+ j = strings.LastIndex(file[:i], "/")
+ }
+ convert := Converters[file[i+1:]]
+ if convert == nil && j != -2 {
+ convert = Converters[file[j+1:]]
+ }
+ if convert == nil {
+ return fmt.Errorf("unknown legacy config file %s", file)
+ }
+ mf, err := convert(file, data)
+ if err != nil {
+ return fmt.Errorf("parsing %s: %v", file, err)
+ }
+
+ // Convert requirements block, which may use raw SHA1 hashes as versions,
+ // to valid semver requirement list, respecting major versions.
+ versions := make([]module.Version, len(mf.Require))
+ replace := make(map[string]*modfile.Replace)
+
+ for _, r := range mf.Replace {
+ replace[r.New.Path] = r
+ replace[r.Old.Path] = r
+ }
+
+ type token struct{}
+ sem := make(chan token, runtime.GOMAXPROCS(0))
+ for i, r := range mf.Require {
+ m := r.Mod
+ if m.Path == "" {
+ continue
+ }
+ if re, ok := replace[m.Path]; ok {
+ m = re.New
+ }
+ sem <- token{}
+ go func(i int, m module.Version) {
+ defer func() { <-sem }()
+ repo, info, err := modfetch.ImportRepoRev(m.Path, m.Version)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), m.Path, m.Version, err)
+ return
+ }
+
+ path := repo.ModulePath()
+ versions[i].Path = path
+ versions[i].Version = info.Version
+ }(i, m)
+ }
+ // Fill semaphore channel to wait for all tasks to finish.
+ for n := cap(sem); n > 0; n-- {
+ sem <- token{}
+ }
+
+ need := map[string]string{}
+ for _, v := range versions {
+ if v.Path == "" {
+ continue
+ }
+ // Don't use semver.Max here; need to preserve +incompatible suffix.
+ if needv, ok := need[v.Path]; !ok || semver.Compare(needv, v.Version) < 0 {
+ need[v.Path] = v.Version
+ }
+ }
+ paths := make([]string, 0, len(need))
+ for path := range need {
+ paths = append(paths, path)
+ }
+ sort.Strings(paths)
+ for _, path := range paths {
+ if re, ok := replace[path]; ok {
+ err := f.AddReplace(re.Old.Path, re.Old.Version, path, need[path])
+ if err != nil {
+ return fmt.Errorf("add replace: %v", err)
+ }
+ }
+ f.AddNewRequire(path, need[path], false)
+ }
+
+ f.Cleanup()
+ return nil
+}