user_78361084
user_78361084

Reputation: 3928

How do I use a vendored argument to a function in an external package?

I have package a, which relies on an external package, language package:

package a

import (
    "fmt"

    "golang.org/x/text/language"
)

// Machine is a printer
type Machine struct{}

// Printer prints
type Printer interface {
    Print(lang language.Tag)
}

// Print prints the language
func (p *Machine) Print(l language.Tag) {
    fmt.Println(l.String())
}

For package a, I've run "dep init" and then "dep ensure".

In another package, I have a main.go file, which imports package a:

package main

import (
    "testing/a"

    "golang.org/x/text/language"
)

func main() {
    m := a.Machine{}
    m.Print(language.MustParse("en"))
}

I get an error:

cannot use "golang.org/x/text/language".MustParse("en") (type "golang.org/x/text/language".Tag) as type "testing/a/vendor/golang.org/x/text/language".Tag in argument to m.Print

If I put the main package in package a, it works fine. Why won't it work when calling from an external package?

Go version is 1.10.2

EDIT: i have full control over package a, so I can change the way I vendor things there. I can also upgrade my Go version if there is an easy fix with a newer Go version.

UPDATE: I've upgraded to Go 1.12.1 and have removed the existing vendor directory. I ran "go mod init" and "go mod vendor" for package a but still get the same error when I run main.go in package b.

cannot use "testing/b/vendor/golang.org/x/text/language".MustParse("en") (type "testing/b/vendor/golang.org/x/text/language".Tag) as type "testing/a/vendor/golang.org/x/text/language".Tag in argument to m.Print

If I try to import the vendored package directly from package a I get:

use of vendored package not allowed

Upvotes: 2

Views: 475

Answers (1)

Pallav Jha
Pallav Jha

Reputation: 3619

If the vendored copy of the dependencies are required to be used then the flag -mod=vendor is to be passed to go run

For example,

> tree
.
|-- a
|   `-- machine.go
`-- main.go

1 directory, 2 files

creating the module with the name testing because package a is imported as testing/a in main

> go mod init testing
go: creating new go.mod: module testing
> go mod vendor #this creates a vendor directory inside the project
go: finding golang.org/x/text/language latest
> tree -L 4
.
|-- a
|   `-- machine.go
|-- go.mod
|-- go.sum
|-- main.go
`-- vendor
    |-- golang.org
    |   `-- x
    |       `-- text
    `-- modules.txt

5 directories, 5 files  
> cat go.mod
module testing

go 1.12

require golang.org/x/text v0.3.0
> go run -mod=vendor main.go
en

Previous Answer

Below is my directory structure:

>tree /F
sample
│---go.mod
│---go.sum
│---main.go
│
└───a
    |---machine.go

Go Version

> go version
go version go1.12 windows/amd64

Module Creation

creating the module with the name testing because package a is imported as testing/a in main

> go mod init testing
go: creating new go.mod: module testing

Program execution

> go run main.go
go: finding golang.org/x/text/language latest
en

Upvotes: 0

Related Questions