]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modconv: support convert replacements in Gopkg.lock
authorBaokun Lee <nototon@gmail.com>
Tue, 31 Jul 2018 17:49:55 +0000 (01:49 +0800)
committerJay Conrod <jayconrod@google.com>
Thu, 25 Apr 2019 14:03:58 +0000 (14:03 +0000)
Fixes #24087.
Updates #26711.

Change-Id: I7fe6b21fd391253a19cb1d35709a061872ea7b6e
Reviewed-on: https://go-review.googlesource.com/c/go/+/126915
Run-TryBot: Baokun Lee <nototon@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
src/cmd/go/internal/modconv/convert.go
src/cmd/go/internal/modconv/dep.go
src/cmd/go/internal/modconv/modconv_test.go
src/cmd/go/internal/modconv/testdata/traefik.dep [new file with mode: 0644]
src/cmd/go/internal/modconv/testdata/traefik.out [new file with mode: 0644]
src/cmd/go/testdata/script/mod_init_dep.txt

index 6fc6718e4733aee72208614e68e2382cf1ba0273..558664a8b38616753203316b0e259716ac38bfc5 100644 (file)
@@ -41,19 +41,29 @@ func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error {
 
        // Convert requirements block, which may use raw SHA1 hashes as versions,
        // to valid semver requirement list, respecting major versions.
-       var work par.Work
+       var (
+               work    par.Work
+               mu      sync.Mutex
+               need    = make(map[string]string)
+               replace = make(map[string]*modfile.Replace)
+       )
+
+       for _, r := range mf.Replace {
+               replace[r.New.Path] = r
+               replace[r.Old.Path] = r
+       }
        for _, r := range mf.Require {
                m := r.Mod
                if m.Path == "" {
                        continue
                }
+               if re, ok := replace[m.Path]; ok {
+                       work.Add(re.New)
+                       continue
+               }
                work.Add(r.Mod)
        }
 
-       var (
-               mu   sync.Mutex
-               need = make(map[string]string)
-       )
        work.Do(10, func(item interface{}) {
                r := item.(module.Version)
                repo, info, err := modfetch.ImportRepoRev(r.Path, r.Version)
@@ -76,15 +86,15 @@ func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error {
        }
        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)
        }
 
-       for _, r := range mf.Replace {
-               err := f.AddReplace(r.Old.Path, r.Old.Version, r.New.Path, r.New.Version)
-               if err != nil {
-                       return fmt.Errorf("add replace: %v", err)
-               }
-       }
        f.Cleanup()
        return nil
 }
index 690c206a1364e829e263096ae5422162b0fd41d7..f43330017168ebe9cf0fb4c80d62f67cf19fe241 100644 (file)
@@ -6,6 +6,9 @@ package modconv
 
 import (
        "fmt"
+       "net/url"
+       "path"
+       "regexp"
        "strconv"
        "strings"
 
@@ -15,9 +18,14 @@ import (
 )
 
 func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
+       type pkg struct {
+               Path    string
+               Version string
+               Source  string
+       }
        mf := new(modfile.File)
-       var list []module.Version
-       var r *module.Version
+       var list []pkg
+       var r *pkg
        for lineno, line := range strings.Split(string(data), "\n") {
                lineno++
                if i := strings.Index(line, "#"); i >= 0 {
@@ -25,7 +33,7 @@ func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
                }
                line = strings.TrimSpace(line)
                if line == "[[projects]]" {
-                       list = append(list, module.Version{})
+                       list = append(list, pkg{})
                        r = &list[len(list)-1]
                        continue
                }
@@ -52,6 +60,8 @@ func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
                switch key {
                case "name":
                        r.Path = val
+               case "source":
+                       r.Source = val
                case "revision", "version":
                        // Note: key "version" should take priority over "revision",
                        // and it does, because dep writes toml keys in alphabetical order,
@@ -68,7 +78,55 @@ func ParseGopkgLock(file string, data []byte) (*modfile.File, error) {
                if r.Path == "" || r.Version == "" {
                        return nil, fmt.Errorf("%s: empty [[projects]] stanza (%s)", file, r.Path)
                }
-               mf.Require = append(mf.Require, &modfile.Require{Mod: r})
+               mf.Require = append(mf.Require, &modfile.Require{Mod: module.Version{Path: r.Path, Version: r.Version}})
+
+               if r.Source != "" {
+                       // Convert "source" to import path, such as
+                       // git@test.com:x/y.git and https://test.com/x/y.git.
+                       // We get "test.com/x/y" at last.
+                       source, err := decodeSource(r.Source)
+                       if err != nil {
+                               return nil, err
+                       }
+                       old := module.Version{Path: r.Path, Version: r.Version}
+                       new := module.Version{Path: source, Version: r.Version}
+                       mf.Replace = append(mf.Replace, &modfile.Replace{Old: old, New: new})
+               }
        }
        return mf, nil
 }
+
+var scpSyntaxReg = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
+
+func decodeSource(source string) (string, error) {
+       var u *url.URL
+       var p string
+       if m := scpSyntaxReg.FindStringSubmatch(source); m != nil {
+               // Match SCP-like syntax and convert it to a URL.
+               // Eg, "git@github.com:user/repo" becomes
+               // "ssh://git@github.com/user/repo".
+               u = &url.URL{
+                       Scheme: "ssh",
+                       User:   url.User(m[1]),
+                       Host:   m[2],
+                       Path:   "/" + m[3],
+               }
+       } else {
+               var err error
+               u, err = url.Parse(source)
+               if err != nil {
+                       return "", fmt.Errorf("%q is not a valid URI", source)
+               }
+       }
+
+       // If no scheme was passed, then the entire path will have been put into
+       // u.Path. Either way, construct the normalized path correctly.
+       if u.Host == "" {
+               p = source
+       } else {
+               p = path.Join(u.Host, u.Path)
+       }
+       p = strings.TrimSuffix(p, ".git")
+       p = strings.TrimSuffix(p, ".hg")
+       return p, nil
+}
index 353161bc5a3c613182daa9cc6416c86729ef647f..ccc4f3d576f6c591ab9db5f1f92a53e566e8bfb9 100644 (file)
@@ -58,6 +58,9 @@ func Test(t *testing.T) {
                        for _, r := range out.Require {
                                fmt.Fprintf(&buf, "%s %s\n", r.Mod.Path, r.Mod.Version)
                        }
+                       for _, r := range out.Replace {
+                               fmt.Fprintf(&buf, "replace: %s %s %s %s\n", r.Old.Path, r.Old.Version, r.New.Path, r.New.Version)
+                       }
                        if !bytes.Equal(buf.Bytes(), want) {
                                t.Errorf("have:\n%s\nwant:\n%s", buf.Bytes(), want)
                        }
diff --git a/src/cmd/go/internal/modconv/testdata/traefik.dep b/src/cmd/go/internal/modconv/testdata/traefik.dep
new file mode 100644 (file)
index 0000000..8510f0f
--- /dev/null
@@ -0,0 +1,79 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+[[projects]]
+  name = "github.com/Nvveen/Gotty"
+  packages = ["."]
+  revision = "a8b993ba6abdb0e0c12b0125c603323a71c7790c"
+  source = "github.com/ijc25/Gotty"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/OpenDNS/vegadns2client"
+  packages = ["."]
+  revision = "a3fa4a771d87bda2514a90a157e1fed1b6897d2e"
+
+[[projects]]
+  name = "github.com/PuerkitoBio/purell"
+  packages = ["."]
+  revision = "8a290539e2e8629dbc4e6bad948158f790ec31f4"
+  version = "v1.0.0"
+
+[[projects]]
+  name = "github.com/PuerkitoBio/urlesc"
+  packages = ["."]
+  revision = "5bd2802263f21d8788851d5305584c82a5c75d7e"
+
+[[projects]]
+  name = "github.com/Shopify/sarama"
+  packages = ["."]
+  revision = "70f6a705d4a17af059acbc6946fb2bd30762acd7"
+
+[[projects]]
+  name = "github.com/VividCortex/gohistogram"
+  packages = ["."]
+  revision = "51564d9861991fb0ad0f531c99ef602d0f9866e6"
+  version = "v1.0.0"
+
+[[projects]]
+  branch = "containous-fork"
+  name = "github.com/abbot/go-http-auth"
+  packages = ["."]
+  revision = "65b0cdae8d7fe5c05c7430e055938ef6d24a66c9"
+  source = "github.com/containous/go-http-auth"
+
+[[projects]]
+  branch = "master"
+  name = "github.com/abronan/valkeyrie"
+  packages = [
+    ".",
+    "store",
+    "store/boltdb",
+    "store/consul",
+    "store/etcd/v2",
+    "store/etcd/v3",
+    "store/zookeeper"
+  ]
+  revision = "063d875e3c5fd734fa2aa12fac83829f62acfc70"
+  
+[[projects]]
+  branch = "master"
+  name = "github.com/mesosphere/mesos-dns"
+  packages = [
+    "detect",
+    "errorutil",
+    "logging",
+    "models",
+    "records",
+    "records/labels",
+    "records/state",
+    "util"
+  ]
+  revision = "b47dc4c19f215e98da687b15b4c64e70f629bea5"
+  source = "git@github.com:containous/mesos-dns.git"
+
+  [[projects]]
+  name = "gopkg.in/fsnotify.v1"
+  packages = ["."]
+  revision = "629574ca2a5df945712d3079857300b5e4da0236"
+  source = "github.com/fsnotify/fsnotify"
+  version = "v1.4.2"
\ No newline at end of file
diff --git a/src/cmd/go/internal/modconv/testdata/traefik.out b/src/cmd/go/internal/modconv/testdata/traefik.out
new file mode 100644 (file)
index 0000000..5054295
--- /dev/null
@@ -0,0 +1,14 @@
+github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c
+github.com/OpenDNS/vegadns2client a3fa4a771d87bda2514a90a157e1fed1b6897d2e
+github.com/PuerkitoBio/purell v1.0.0
+github.com/PuerkitoBio/urlesc 5bd2802263f21d8788851d5305584c82a5c75d7e
+github.com/Shopify/sarama 70f6a705d4a17af059acbc6946fb2bd30762acd7
+github.com/VividCortex/gohistogram v1.0.0
+github.com/abbot/go-http-auth 65b0cdae8d7fe5c05c7430e055938ef6d24a66c9
+github.com/abronan/valkeyrie 063d875e3c5fd734fa2aa12fac83829f62acfc70
+github.com/mesosphere/mesos-dns b47dc4c19f215e98da687b15b4c64e70f629bea5
+gopkg.in/fsnotify.v1 v1.4.2
+replace: github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c github.com/ijc25/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c
+replace: github.com/abbot/go-http-auth 65b0cdae8d7fe5c05c7430e055938ef6d24a66c9 github.com/containous/go-http-auth 65b0cdae8d7fe5c05c7430e055938ef6d24a66c9
+replace: github.com/mesosphere/mesos-dns b47dc4c19f215e98da687b15b4c64e70f629bea5 github.com/containous/mesos-dns b47dc4c19f215e98da687b15b4c64e70f629bea5
+replace: gopkg.in/fsnotify.v1 v1.4.2 github.com/fsnotify/fsnotify v1.4.2
index 29c840b3833af5af4b42eea539daf6aee0e41ff3..8cb3fa836ea48eeffda5d0323e573781f16ed65a 100644 (file)
@@ -21,6 +21,11 @@ go list
 go list -m all
 stdout 'rsc.io/sampler v1.0.0'
 
+# test dep replacement
+cd y
+go mod init
+cmp go.mod go.mod.replace
+
 -- go.mod1 --
 module x
 
@@ -32,3 +37,21 @@ package x
   name = "rsc.io/sampler"
   version = "v1.0.0"
 
+-- y/Gopkg.lock --
+[[projects]]
+  name = "z"
+  revision = "v1.0.0"
+  source = "rsc.io/quote"
+
+-- y/y.go --
+package y // import "y"
+import _ "z"
+
+-- y/go.mod.replace --
+module y
+
+go 1.13
+
+replace z v1.0.0 => rsc.io/quote v1.0.0
+
+require rsc.io/quote v1.0.0
\ No newline at end of file