github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/go/not-internal/modconv/convert.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package modconv 6 7 import ( 8 "fmt" 9 "os" 10 "sort" 11 "strings" 12 "sync" 13 14 "github.com/gagliardetto/golang-go/cmd/go/not-internal/base" 15 "github.com/gagliardetto/golang-go/cmd/go/not-internal/modfetch" 16 "github.com/gagliardetto/golang-go/cmd/go/not-internal/par" 17 18 "golang.org/x/mod/modfile" 19 "golang.org/x/mod/module" 20 "golang.org/x/mod/semver" 21 ) 22 23 // ConvertLegacyConfig converts legacy config to modfile. 24 // The file argument is slash-delimited. 25 func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error { 26 i := strings.LastIndex(file, "/") 27 j := -2 28 if i >= 0 { 29 j = strings.LastIndex(file[:i], "/") 30 } 31 convert := Converters[file[i+1:]] 32 if convert == nil && j != -2 { 33 convert = Converters[file[j+1:]] 34 } 35 if convert == nil { 36 return fmt.Errorf("unknown legacy config file %s", file) 37 } 38 mf, err := convert(file, data) 39 if err != nil { 40 return fmt.Errorf("parsing %s: %v", file, err) 41 } 42 43 // Convert requirements block, which may use raw SHA1 hashes as versions, 44 // to valid semver requirement list, respecting major versions. 45 var ( 46 work par.Work 47 mu sync.Mutex 48 need = make(map[string]string) 49 replace = make(map[string]*modfile.Replace) 50 ) 51 52 for _, r := range mf.Replace { 53 replace[r.New.Path] = r 54 replace[r.Old.Path] = r 55 } 56 for _, r := range mf.Require { 57 m := r.Mod 58 if m.Path == "" { 59 continue 60 } 61 if re, ok := replace[m.Path]; ok { 62 work.Add(re.New) 63 continue 64 } 65 work.Add(r.Mod) 66 } 67 68 work.Do(10, func(item interface{}) { 69 r := item.(module.Version) 70 repo, info, err := modfetch.ImportRepoRev(r.Path, r.Version) 71 if err != nil { 72 fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), r.Path, r.Version, err) 73 return 74 } 75 mu.Lock() 76 path := repo.ModulePath() 77 // Don't use semver.Max here; need to preserve +incompatible suffix. 78 if v, ok := need[path]; !ok || semver.Compare(v, info.Version) < 0 { 79 need[path] = info.Version 80 } 81 mu.Unlock() 82 }) 83 84 var paths []string 85 for path := range need { 86 paths = append(paths, path) 87 } 88 sort.Strings(paths) 89 for _, path := range paths { 90 if re, ok := replace[path]; ok { 91 err := f.AddReplace(re.Old.Path, re.Old.Version, path, need[path]) 92 if err != nil { 93 return fmt.Errorf("add replace: %v", err) 94 } 95 } 96 f.AddNewRequire(path, need[path], false) 97 } 98 99 f.Cleanup() 100 return nil 101 }