...

Source file src/pkg/cmd/go/internal/modconv/convert.go

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

View as plain text