ozn
ozn

Reputation: 2228

Go import from package's vendor

How can I specify to import/use a package from the vendor instead from the GOPATH/GOROOT?

$GOPATH/src/
$GOPATH/src/github.com/
$GOPATH/src/github.com/myproject/mypkg
$GOPATH/src/github.com/myproject/mypkg/mypkgfile1.go
package mypkg
import "github.com/someproject/somepkg" // importing from vendor

type MyStruct struct {
  Config somepkg.SomeStruct1
}
func New(config somepkg.SomeStruct1) MyStruct {...} 
func (m *MyStruct) DoSomething() {
  a := somepkg.SomeStruct1{}
  b := somepkg.SomeStruct2{}
  // do something with 'a' and 'b'
  out := somepkg.SomeFunc(a) 
}
func (m *MyStruct) MyFunc(input SomeStruct1) (output SomeStruct2, err error) {...}
$GOPATH/src/github.com/myproject/mypkg/mypkgfile2.go
$GOPATH/src/github.com/myproject/mypkg/vendor/github.com/someproject/somepkg/
$GOPATH/src/github.com/myproject/mypkg/vendor/github.com/someproject/somepkg/somepkgfile1.go
package somepkg
type SomeStruct1 struct {...}
type SomeStruct2 struct {...}
func SomeFunc(input SomeStruct1) (output SomeStruct2) {...}
$GOPATH/src/github.com/myproject/mypkg/go.mod
module gitHub.com/myproject/mypkg
go 1.1.4

require github.com/someproject/somepkg v1.0.0
$GOPATH/src/github.com/someproject/somepkg/somepkgfile1.go
package somepkg
type SomeStruct1 struct {...}
type SomeStruct2 struct {...}
func SomeFunc() {...}
$GOPATH/src/github.com/someproject/somepkg/go.mod
module gitHub.com/someproject/somepkg
go 1.1.4

require github.com/someproject/somepkg v1.0.0
$GOPATH/src/github.com/anotherproject/anotherpkpg/somepkgfile1.go
package main
import (
  "github.com/someproject/somepkg"
  "github.com/myproject/mypkg"
)
func main() {
  // do something with somepkg
  somepkg.SomeFunc()
  s := somepkg.SomeStruct1{...} 
  myData := mypkg.New(s) 
  m := mypkg.MyFunc()
  x := somepkg.SomeStruct1{...}
  y := mypkg.MyFunc(x)
}
$GOPATH/src/github.com/someproject/somepkg/go.mod
module gitHub.com/someproject/somepkg
go 1.1.4

require (
  github.com/myproject/mypkg v1.0.0
  github.com/someproject/somepkg v1.0.0
)

When I'm building/running anotherpkpg/main.go I keep getting a type mismatch error like:

cannot use &s (type *"someproject/somepkg".SomeStruct1) as type *"myproject/mypkg/vendor/github.com/someproject/somepkg".SomeStruct1 in argument to mypkg.New

Its not possible at all to be able do this? I get it that type mismatch can occur if the somepkg are of different version/releases. But There is no way to reference the vendored somepkg? I would think it would get even more complex when i

Upvotes: 0

Views: 1785

Answers (1)

bcmills
bcmills

Reputation: 5187

vendor directories work differently in GOPATH mode than in module mode.

Since github.com/myproject/mypkg/go.mod exists, you are presumably building github.com/myproject/mypkg and its dependencies in module mode. In module mode, only the vendor contents for the main module are used, and vendor directories for other packages are always ignored, so each package has exactly one location and one definition. (With -mod=vendor each package is loaded from your vendor directory; with -mod=readonly or -mod=mod each package is loaded from the module cache.)

Since github.com/anotherproject/anotherpkg/go.mod does not exist, Go 1.15 and earlier will by default build it in GOPATH mode. In GOPATH mode, the import statements within each directory refer to the packages in the vendor subtrees of all parent directories, and the vendored packages are treated as distinct packages even if they share the same import path.

The right long-term fix for your situation is probably to start building github.com/anotherproject/anotherpkg in module mode, and to use a replace directive if needed to point it at your working copy of github.com/myproject/mypkg.

You can set that up using a sequence of commands like:

# Enable module mode for anotherpkg.
cd $GOPATH/src/github.com/anotherproject/anotherpkg
go mod init github.com/anotherproject/anotherpkg

# Use the local copy of github.com/myproject/mypkg instead of the latest GitHub snapshot.
go mod edit -replace github.com/myproject/mypkg=$GOPATH/src/github.com/myproject/mypkg
go get -d github.com/myproject/mypkg

# Resolve any additional missing dependencies to their latest versions.
go mod tidy

Upvotes: 1

Related Questions