Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

adding a go-import "mod" meta tag makes dep ensure fail with "multiple meta tags match" error #2151

Closed
dmitshur opened this issue May 6, 2019 · 5 comments · Fixed by #2152

Comments

@dmitshur
Copy link
Member

dmitshur commented May 6, 2019

This problem with dep failing was reported to me as the author of a Go package, see here.

I've looked into the cause and reporting it here because it seems like a bug in dep.

What version of dep are you using (dep version)?

The latest via go get -u github.com/golang/dep/cmd/dep as of right now, commit 66ec1e8. Running git describe --tags reports v0.5.1-3-g66ec1e84.

What dep command did you run?

$ dep init
$ cat >main.go <<EOF
package main

import "fmt"
import "dmitri.shuralyov.com/text/kebabcase"

func main() {
    fmt.Println(kebabcase.Parse("foo-bar-baz").ToMixedCaps())
}
EOF
$ dep ensure -v

What did you expect to see?

Successful operation.

What did you see instead?

$ dep ensure -v
The following errors occurred while deducing packages:
  * "dmitri.shuralyov.com/text/kebabcase": unable to deduce repository and source type for "dmitri.shuralyov.com/text/kebabcase": unable to read metadata: multiple meta tags match import path "dmitri.shuralyov.com/text/kebabcase"

validateParams: could not deduce external imports' project roots

Cause

The Go package at the vanity import path dmitri.shuralyov.com/text/kebabcase currently has two go-import meta tags, one with the VCS type "git" telling the go command where to clone the containing repository via git, and another with the type "mod" telling the go command what Go module proxy can be used to fetch the module.

The "mod" go-import meta import is documented at the bottom of https://golang.org/cmd/go/#hdr-Import_path_syntax section.

The "mod" meta tag seems to be causing dep to think there are two VCS types and it throws the above error. If dep doesn't have full support the "mod" meta tag, it should be skipping over it instead of reporting an error.

The go command has no problems with fetching that module, both in Go 1.12 and Go 1.11.

@dmitshur
Copy link
Member Author

dmitshur commented May 6, 2019

The problem in code is inside the parseMetaGoImports function:

dep/gps/discovery.go

Lines 58 to 70 in 66ec1e8

if !ok || !strings.EqualFold(e.Name.Local, "meta") {
continue
}
if attrValue(e.Attr, "name") != "go-import" {
continue
}
if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
imports = append(imports, metaImport{
Prefix: f[0],
VCS: f[1],
RepoRoot: f[2],
})
}

The fix should be as little as:

 			continue
 		}
 		if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
+			// Ignore VCS type "mod", which is applicable only in module mode.
+			if f[1] == "mod" {
+				continue
+			}
 			imports = append(imports, metaImport{
 				Prefix:   f[0],
 				VCS:      f[1],

This issue and the fix for it are very similar to issue golang/go#31845 that was affecting the golang.org/x/tools/go/vcs package and the CL 175219 that resolved it.

@kevinburke
Copy link
Collaborator

I understand this is small and the fix is trivial, but it's still annoying how tools that used to work OK now suddenly need more investment in order to behave the same way that they did before. I thought the whole point of Go was to preserve compatibility, etc.

dmitshur added a commit that referenced this issue May 7, 2019
Apply the same change as in golang.org/cl/175219 to this copy of the
parseMetaGoImports function, helping keep them in sync.

The "mod" type is not a real version control system (VCS), it applies
only when in module mode. Skip it and continue to consider only real
VCS types.

This resolves parseMetaGoImports returning a "multiple meta tags match
import path" error on packages that offer go-import meta tags with both
a true VCS and the "mod" type.

Reference: https://golang.org/cmd/go/#hdr-Remote_import_paths

Fixes #2151
@dmitshur
Copy link
Member Author

dmitshur commented May 7, 2019

I’ve sent PR #2152 that resolves this issue.

I tested it on the package in the original issue report, and dep ensure was able to run successfully after the change.

@markeissler
Copy link

The following repo includes a Makefile that can target linux and macOS platforms

go-dep-fix

It will clone the dep repo, apply the patch, build and install the patched dep to both /usr/local/bin and $GOPATH/bin.

This make it easier for us to deploy this fix in our automated builds.

It goes without saying but I will say it: Use at your own risk.

You may have to modify the Makefile for your needs. It will replace your current dep entirely. You may need elevated privileges to perform the install step.

dmitshur added a commit that referenced this issue May 7, 2019
Apply the same change as in golang.org/cl/175219 to this copy of the
parseMetaGoImports function, helping keep them in sync.

The "mod" type is not a real version control system (VCS), it applies
only when in module mode. Skip it and continue to consider only real
VCS types.

This resolves parseMetaGoImports returning a "multiple meta tags match
import path" error on packages that offer go-import meta tags with both
a true VCS and the "mod" type.

Reference: https://golang.org/cmd/go/#hdr-Remote_import_paths

Fixes #2151
@dmitshur
Copy link
Member Author

dmitshur commented May 8, 2019

The fix has been merged to master branch.

It hasn't been included in a released version yet, but it can be installed right now from source code via go get -u github.com/golang/dep/cmd/dep (as described at the bottom of https://github.com/golang/dep#installation).

I've confirmed the original issue is resolved with the latest version:

$ dep init
$ cat >main.go <<EOF
package main

import "fmt"
import "dmitri.shuralyov.com/text/kebabcase"

func main() {
    fmt.Println(kebabcase.Parse("foo-bar-baz").ToMixedCaps())
}
EOF

$ dep ensure -v
# Gopkg.lock is out of sync with Gopkg.toml and project imports:
dmitri.shuralyov.com/text/kebabcase: imported or required, but missing from Gopkg.lock's input-imports

Root project is "example.com/p"
 1 transitively valid internal packages
 1 external packages imported from 1 projects
(0)   ✓ select (root)
(1)	? attempt dmitri.shuralyov.com/text/kebabcase with 1 pkgs; 1 versions to try
(1)	    try dmitri.shuralyov.com/text/kebabcase@master
(1)	✓ select dmitri.shuralyov.com/text/kebabcase@master w/1 pkgs
(2)	? attempt github.com/shurcooL/graphql with 1 pkgs; 1 versions to try
(2)	    try github.com/shurcooL/graphql@master
(2)	✓ select github.com/shurcooL/graphql@master w/1 pkgs
  ✓ found solution with 2 packages from 2 projects

Solver wall times by segment:
     b-source-exists: 940.112035ms
     b-list-versions: 825.797845ms
         b-list-pkgs: 324.933011ms
              b-gmal: 317.304225ms
            new-atom:    185.314µs
         select-atom:    134.555µs
         select-root:      129.1µs
             satisfy:    122.941µs
  b-deduce-proj-root:     39.599µs
               other:     24.658µs

  TOTAL: 2.408783283s

# Bringing vendor into sync
(1/2) Wrote github.com/shurcooL/graphql@master: new project
(2/2) Wrote dmitri.shuralyov.com/text/kebabcase@master: new project

$ echo $?
0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants