1
2
3
4
5 package modconv
6
7 import (
8 "fmt"
9 "os"
10 "runtime"
11 "sort"
12 "strings"
13
14 "cmd/go/internal/base"
15
16 "golang.org/x/mod/modfile"
17 "golang.org/x/mod/module"
18 "golang.org/x/mod/semver"
19 )
20
21
22
23 func ConvertLegacyConfig(f *modfile.File, file string, data []byte, queryPackage func(path, rev string) (module.Version, error)) error {
24 i := strings.LastIndex(file, "/")
25 j := -2
26 if i >= 0 {
27 j = strings.LastIndex(file[:i], "/")
28 }
29 convert := Converters[file[i+1:]]
30 if convert == nil && j != -2 {
31 convert = Converters[file[j+1:]]
32 }
33 if convert == nil {
34 return fmt.Errorf("unknown legacy config file %s", file)
35 }
36 mf, err := convert(file, data)
37 if err != nil {
38 return fmt.Errorf("parsing %s: %v", file, err)
39 }
40
41
42
43 versions := make([]module.Version, len(mf.Require))
44 replace := make(map[string]*modfile.Replace)
45
46 for _, r := range mf.Replace {
47 replace[r.New.Path] = r
48 replace[r.Old.Path] = r
49 }
50
51 type token struct{}
52 sem := make(chan token, runtime.GOMAXPROCS(0))
53 for i, r := range mf.Require {
54 m := r.Mod
55 if m.Path == "" {
56 continue
57 }
58 if re, ok := replace[m.Path]; ok {
59 m = re.New
60 }
61 sem <- token{}
62 go func(i int, m module.Version) {
63 defer func() { <-sem }()
64 version, err := queryPackage(m.Path, m.Version)
65 if err != nil {
66 fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), m.Path, m.Version, err)
67 return
68 }
69
70 versions[i] = version
71 }(i, m)
72 }
73
74 for n := cap(sem); n > 0; n-- {
75 sem <- token{}
76 }
77
78 need := map[string]string{}
79 for _, v := range versions {
80 if v.Path == "" {
81 continue
82 }
83
84 if needv, ok := need[v.Path]; !ok || semver.Compare(needv, v.Version) < 0 {
85 need[v.Path] = v.Version
86 }
87 }
88 paths := make([]string, 0, len(need))
89 for path := range need {
90 paths = append(paths, path)
91 }
92 sort.Strings(paths)
93 for _, path := range paths {
94 if re, ok := replace[path]; ok {
95 err := f.AddReplace(re.Old.Path, re.Old.Version, path, need[path])
96 if err != nil {
97 return fmt.Errorf("add replace: %v", err)
98 }
99 }
100 f.AddNewRequire(path, need[path], false)
101 }
102
103 f.Cleanup()
104 return nil
105 }
106
View as plain text