cannot find vendor directory under golang project - go

My golang version is go1.10.2 linux/amd64. I can build and run my go project(under gopath/src) without any problem but I cannot see vendor directory under my project folder. I would like to know if the vendor folder is a hidden directory? What are the possible reasons the vendor folder is not generated?

Vendor directory is used as an alternative to GOPATH when resolving dependencies. A dependency is first looked up in /vendor then in GOPATH then in GOROOT.
If you go get all your dependencies they'll be in GOPATH/src instead of /vendor.
To start adding project specific dependencies to vendor dir you need to use a dependency manager such as glide or dep or manually copy everything to /vendor.
This SO answer goes into more detail on using vendor dir in Go - https://stackoverflow.com/a/37238226/1589165

Related

Where is the go project working directory when using modules?

I am trying to download, make some tweaks and build a golang project from GitHub. The project's instructions are:
go get github.com/<vendor>/<projectName>
cd src/github.com/<vendor>/<projectName>
go build .
That used to work in the past — before enabling Go Modules.
Now I have GO111MODULE=on (go version go1.15.4 linux/amd64). When running the first command, go downloads the project as a module and all its dependencies.
But then there is no src/github.com/<vendor>/<projectName> folder anymore. Moreover, the is no folder named <projectName> anywhere in the system.
Instead, there is folder pkg/mod/github.com/<vendor> which contains the project folder with weird symbols in its name (exclamation marks etc.) and version identifiers.
How do I get the project folder available for making tweaks and builds?
As pointed by #Volker, good old git clone should be used.
It turns out that it should be used instead of go get github.com/<vendor>/<projectName> (no idea why the project vendor recommends that):
git clone git://github.com/<vendor>/<projectName>
cd <projectName>
go get ./...
# do tweaks here
go build .
If your goal is tweaks, the easiest way it use to use go mod vendor.
https://golang.org/ref/mod#go-mod-vendor
The go mod vendor command constructs a directory named vendor in the main module's root directory that contains copies of all packages needed to support builds and tests of packages in the main module

Using 'go build' fetches dependencies even though they are in vendor/

I am trying to fetch a Go project and copy the dependencies under the vendor/ directory so I have the complete source code of the project and its dependencies in my project. However, even after doing that, deleting the packages under $GOPATH/pkg/mod and rebuilding cause the Go compiler to re-fetch all dependencies, which takes a considerable of time.
This is what I did:
# Fetch the project, e.g. influx/telegraf
go get -d github.com/influxdata/telegraf
# CD into the project
cd $GOPATH/src/influxdata/telegraf
# Fetch the modules under vendor/ directory
go mod vendor
After calling the last command, Go will fetch all the dependencies under pkg/mod. Not sure why it is doing that, but I assume it is because it needs to build the project normally, and then move the fetched dependencies under the vendor/ folder. After that, I can build successfully. However, to make sure I no longer require those dependencies, I deleted the pkg/mod directory completely and rebuilt the project. Go compiler, for some reason, fetched the packages again.
Is there anything I am doing wrong?
Thanks!
The vendor folder is not used automatically in all cases.
To make sure dependencies are loaded from the main module's vendor folder, pass -mod=vendor to the go tool.
The vendor folder if present is only used automatically (if not specified otherwise with -mod=mod) if the go version specified by go.mod file is 1.14 or higher.
These are detailed in Command go: Maintaining module requirements:
If invoked with -mod=vendor, the go command loads packages from the main module's vendor directory instead of downloading modules to and loading packages from the module cache. The go command assumes the vendor directory holds correct copies of dependencies, and it does not compute the set of required module versions from go.mod files. However, the go command does check that vendor/modules.txt (generated by 'go mod vendor') contains metadata consistent with go.mod.
If invoked with -mod=mod, the go command loads modules from the module cache even if there is a vendor directory present.
If the go command is not invoked with a -mod flag and the vendor directory is present and the "go" version in go.mod is 1.14 or higher, the go command will act as if it were invoked with -mod=vendor.

How do I debug Go dependency packages?

Say my Go project depends on package example.com/foo. I am using Go 1.12, so the dependency is automatically pulled in by Go modules. That dependency has some problems/bugs, I want to add logs in the source code.
I can find the source code of the dependency on GitHub but I don't know how to make it into my project for debugging purpose.
First fetch all the dependency packages into the vendor folder.
go mod vendor
Then, change the source code in that and build your project by specifying to look into vendor folder.
go build -mod=vendor
or
go run -mod=vendor myapp.go
You can use replace directive:
replace example.com/original/import/path => /your/forked/import/path
Go module fetches packages into $GOPATH/pkg/mod you can change the source code there or using the vendor option of go mod to pull the packages into vendor folder and then start coding there.

Dependency issue within two projects that use same lib

I have two projects:
/myproject
/sharedproject
both of them are managed by dep, I have execute go get -u github.com/golang/dep/cmd/dep in order to have latest dep version, and run dep ensure on both projects.
When I run myproject I get following error:
cannot use op (type *"myproject/vendor/github.com/go-openapi/spec".Operation) as type *"sharedproject/vendor/github.com/go-openapi/spec".Operation
What is wrong and how to fix this?
Looks like the situation is that sharedproject vendors the github.com/go-openapi/spec dependency while myproject
gets both sharedproject and github.com/go-openapi/spec dependencies from
GOPATH.
Now when you refer to github.com/go-openapi/spec in sharedproject, it refers to
the package inside the vendor directory, which is technically different from the
same package in GOPATH, even if both have the same content. So when you pass a
variable of type *github.com/go-openapi/spec.Operation from myproject to a
function in sharedproject, the package of the type differs from what's expected and compilation fails.
To solve this, make sure sharedproject is vendored inside myproject. When
you do this, dep ensure will put a copy of sharedproject without its vendor
directory into myproject's vendor directory. After this, both myproject and sharedproject will use the github.com/go-openapi/spec package from myproject's vendor directory.
That does make local development hard if you change sharedproject often and want
to immediately use those changes in myproject (can't use dep till the changes are pushed to the Git remote). I'd work around that by copying
over sharedproject into myproject's vendor directory manually without using dep (excluding the vendor directory of course). Be careful to not commit those manually copied changes to Git though!

How to make sure go build is using all dependencies from vendor directory

I have used godep and vendored all my dependencies in vendor/ directory. Go build is working fine as well. However how can I be sure that all my dependencies are vendored?
Is there any command that can make sure of that?
My CI service (Travis is the one I use) lets me know. Because my test build will fail if the deps aren't available.
You should be using a CI service anyway, and then you get that benefit for free.
I use govendor to manage the dependencies, which has a status option. Here's some of the commands with govendor:
init Create the "vendor" folder and the "vendor.json" file.
list List and filter existing dependencies and packages.
add Add packages from $GOPATH.
update Update packages from $GOPATH.
remove Remove packages from the vendor folder.
status Lists any packages missing, out-of-date, or modified locally.
fetch Add new or update vendor folder packages from remote repository.
sync Pull packages into vendor folder from remote repository with revisions
from vendor.json file.
migrate Move packages from a legacy tool to the vendor folder with metadata.
Specifically, you'd do govendor status to check if there are missing packages.
If you decide to use govendor, you can get started by doing:
go get github.com/kardianos/govendor
govendor migrate (which will migrate from godeps to govendor)
Also, you mentioned in a comment that your deploying to Heroky, here's some documentation from them on govendor

Resources