github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/go/internal/modconv/dep.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  	"strconv"
    10  	"strings"
    11  
    12  	"cmd/go/internal/modfile"
    13  	"cmd/go/internal/module"
    14  	"cmd/go/internal/semver"
    15  )
    16  
    17  func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
    18  	mf := new(modfile.File)
    19  	var list []module.Version
    20  	var r *module.Version
    21  	for lineno, line := range strings.Split(string(data), "\n") {
    22  		lineno++
    23  		if i := strings.Index(line, "#"); i >= 0 {
    24  			line = line[:i]
    25  		}
    26  		line = strings.TrimSpace(line)
    27  		if line == "[[projects]]" {
    28  			list = append(list, module.Version{})
    29  			r = &list[len(list)-1]
    30  			continue
    31  		}
    32  		if strings.HasPrefix(line, "[") {
    33  			r = nil
    34  			continue
    35  		}
    36  		if r == nil {
    37  			continue
    38  		}
    39  		i := strings.Index(line, "=")
    40  		if i < 0 {
    41  			continue
    42  		}
    43  		key := strings.TrimSpace(line[:i])
    44  		val := strings.TrimSpace(line[i+1:])
    45  		if len(val) >= 2 && val[0] == '"' && val[len(val)-1] == '"' {
    46  			q, err := strconv.Unquote(val) // Go unquoting, but close enough for now
    47  			if err != nil {
    48  				return nil, fmt.Errorf("%s:%d: invalid quoted string: %v", file, lineno, err)
    49  			}
    50  			val = q
    51  		}
    52  		switch key {
    53  		case "name":
    54  			r.Path = val
    55  		case "revision", "version":
    56  			// Note: key "version" should take priority over "revision",
    57  			// and it does, because dep writes toml keys in alphabetical order,
    58  			// so we see version (if present) second.
    59  			if key == "version" {
    60  				if !semver.IsValid(val) || semver.Canonical(val) != val {
    61  					break
    62  				}
    63  			}
    64  			r.Version = val
    65  		}
    66  	}
    67  	for _, r := range list {
    68  		if r.Path == "" || r.Version == "" {
    69  			return nil, fmt.Errorf("%s: empty [[projects]] stanza (%s)", file, r.Path)
    70  		}
    71  		mf.Require = append(mf.Require, &modfile.Require{Mod: r})
    72  	}
    73  	return mf, nil
    74  }