Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reflect: Type.PkgPath() doesn't return proper import path for vendored import #12739

Closed
szank opened this issue Sep 24, 2015 · 5 comments
Closed

Comments

@szank
Copy link

szank commented Sep 24, 2015

Hi,
We were using reflect package to get the import path of some of our dependencies. We are using
GO15VENDOREXPERIMENT.

When we call PkgPath() on a Type interface acquired from an instance of a struct from the codec package (github.com/ugorji/go/codec) we get import path :
bitbucket.org/{our_project_dir}/vendor/github.com/ugorji/go/codec

This is not in line with the PkgPath() call documentation, and we are using those import paths to generate a import clause for our generated go code.
The result looks like this :

package example

import(
    bitbucket.org/{our_project_dir}/vendor/github.com/ugorji/go/codec
    {...}
)
{...}

This file clearly doesn't compile. Could you please fix the behaviour of the PkgPath() call when the project is using GO15VENDOREXPERIMENT?

@ianlancetaylor ianlancetaylor changed the title reflect.Type.PkgPath() doesn't return proper import path reflect: Type.PkgPath() doesn't return proper import path Sep 24, 2015
@ianlancetaylor ianlancetaylor added this to the Go1.6 milestone Sep 24, 2015
@ianlancetaylor ianlancetaylor changed the title reflect: Type.PkgPath() doesn't return proper import path reflect: Type.PkgPath() doesn't return proper import path for vendored import Sep 24, 2015
@minux
Copy link
Member

minux commented Sep 25, 2015

I think the value returned by PkgPath is reasonable because
it uniquely identifies the package.

Just returning "github.com/ugorji/go/codec" doesn't always
work because there could be different versions of the package
under different vendor directories in the same program.

Consider this project file layout:
prjA/
pkg1/
vendor/
github.com/ugorji/go/codec/
vendor/prjB/
vendor/
github.com/ugorji/go/codec/
pkg2/

Both prjA/pkg1 and vendor/prjB/pkg2 will use their own version of
github.com/ugorji/go/codec, But those two packages are different,
PkgPath method must return different values.

The example might be contrived, but it illustrates the subtlety of
vendoring packages without import path rewriting.

Because this kind of vendoring is explicitly supported by the go
tool, I don' think we can change PkgPath to strip the prefix. You'd
better deal with it in your generator.

@ugorji
Copy link
Contributor

ugorji commented Sep 25, 2015

@minux Based on the documentation, the PkgPath is the import path.

Documentation states:

// PkgPath returns a named type's package path, that is, the import path
// that uniquely identifies the package, such as "encoding/base64".
// If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
// the package path will be the empty string.
PkgPath() string

The vendor implementation should be transparent/invisible at runtime.
I would think that the PkgPath of a type should always mirror the import
path in the go file, as this is what is reasonably expected, and hides the
implementation details of vendoring.

@minux
Copy link
Member

minux commented Sep 25, 2015 via email

@rsc
Copy link
Contributor

rsc commented Oct 14, 2015

This is working as intended. Quoting golang.org/s/go15vendor:

If there is a source directory d/vendor, then, when compiling a source file within the subtree rooted at d, import "p" is interpreted as import "d/vendor/p" if that exists.

When you ask about the package in question you find out is not the real one but a vendored copy. This is true, and it is correct behavior.

@rsc rsc closed this as completed Oct 14, 2015
@dmitshur
Copy link
Contributor

I had the same question, and this issue answered it.

dmitshur added a commit to sourcegraph/prototools that referenced this issue Feb 23, 2016
This is needed when this package is vendored via Go 1.6 /vendor/ support.

The PkgPath returned value does not strip /vendor/ prefix, as documented in golang/go#12739.
KevinPike pushed a commit to doubledutch/mock that referenced this issue Feb 26, 2016
"import" statements cannot contain vendor paths when GO15VENDOREXPERIMENT
is enabled. golang/go#12111

reflect.PkgPath returns the actual package path used by a type. This can
include the vendor directory. golang/go#12739

When writing "import" statements using reflect.PkgPath, /vendor/ should
be stripped from the import path.
luma added a commit to autopilothq/easyjson that referenced this issue Feb 13, 2017
If the package that easyjson is being used on is vendor'd
then we need to strip off the vendor'd bit of the pkg path

Fixes: mailru#29
See: golang/go#12739
@golang golang locked and limited conversation to collaborators Feb 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants