go: proposal: go/build: vendor directories are ignored when outside of $GOPATH

  1. What version of Go are you using (go version)? 1.6
  2. What operating system and processor architecture are you using (go env)? ubuntu 16.04 x86_64
  3. What did you do? I want to build a go project using gitlab-ci. The project gets clone on the build machine in /build/project, which is not inside the go path. The build fails due to import errors. I reproduced this manually: moving a project outside the GOPATH leads to ignoring the vendor folder.
  4. What did you expect to see? go searching for imports in the vendor directory
  5. What did you see instead? The vendor directory is ignored and go only searches in GOROOT and GOPATH

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 27
  • Comments: 37 (13 by maintainers)

Most upvoted comments

Sorry, but this doesn’t make sense to me. The vendoring feature is supposed to solve the problem of dependency management. I got all my dependencies except the go standard library as submodules of my project. Why am I forced to put this to a specific location in my filesystems? My GOPATH is set and the go tool searches for modules in there. When a project is located outside the GOPATH/src i would expect the go tool to search the vendor folder first and then the GOPATH for modules.

The design of the “vendor” mechanism is what you should expect: https://golang.org/s/go15vendor

Any deviations from that document should be filed as a bug, but this is not one.

This issue, as specified, is describing a deviation from that document. It simply says that, when compiling code located in “d/”, the go command will look for imports in “d/vendor/$path”. It makes no mention of GOPATH except in an example.

I’m going to reopen this issue to look at for Go 1.8. I think fixing this bug could be a key part of solving #12488.

Honestly I find it odd too. I don’t get why the “go way” is so phobic to freely located project directories. This has been one of the big three pains-in-my-ass when working with the language.

The design of the “vendor” mechanism is what you should expect: https://golang.org/s/go15vendor

Any deviations from that document should be filed as a bug, but this is not one.

Let’s move this to the mailing list. See https://golang.org/wiki/Questions for links.

The go tool is based on GOPATH. If you don’t want to use GOPATH, it’s hard to use the go tool.

Note that GOPATH can have multiple entries; see go help gopath.

I’m going to close this; we’re not going to be adding support for things like the vendor directory outside of the existing GOPATH support.

I didn’t know about the default path addition. Thanks. With that, I guess I’m just suggesting loosening the requirement for source to be under GOPATH when its not really needed. i.e all deps under vendor/.

There are many problems with running outside GOPATH. Among others, there’s no caching of built object files, so everything is much slower than it should be (go build, go test, and so on). Vendoring is pretty low on the list of problems.

It may be that GOPATH should be reconsidered but if so it should be done as a whole change, not just one piece at a time, like @bradfitz said above. The solution for now is to use GOPATH.

Duplicate of #17271 if anything.

Since the linked specification doesn’t state anywhere that the GOPATH is required, making the go tool handle this case, for instance with an option to specify the package path of the current working directory, is not going to be bug. My understanding is that this issue is then a feature request, and thus doesn’t deserve to be closed because it’s not a bug. In fact, the linked specification states «This proposal allows the Go community to move from builds that require custom GOPATH configuration beforehand to builds that just work», and one concerned by this feature request can interpret this failure as a deviation from this specification, since any build made where no GOPATH exists will require a custom GOPATH as a consequence.

With this, you have options:

  • vendor/ but no GOPATH - Your project is fully self-contained in its repo using vendoring.
  • GOPATH but no vendor/ - Your project shares its dependencies with your other projects.
  • GOPATH and vendor/ - Dependencies you’ve vendored with your favorite tool are tracked in your repo, but other dependencies are shared with other projects using the GOPATH.

But GOPATH is completely optional, and left as just a “good idea”.

You still get an error if you have no GOPATH and no created vendor/ directory.

Has there been any update on this? Why is Go so obsessed with forcing GOPATH on everyone and everything? https://github.com/golang/go/issues/3515

#17271 is a different but similar issue. That issue is that people should be able to have an auto-configured GOPATH. The resolution was proposed to auto resolve GOPATH to ./vendor but instead it would be autoresolved to $HOME/go

This issue is that I have a GOPATH configured, but I want to checkout code outside of that path and the ./vendor directory would override packages in the configured GOPATH.

I personally think that the GoLang contributors should give developers at least some amount of freedom. Closing an issue that is requested by so many because you think it’ll be slower, for people who are already aware of it and are still requesting it because of how painful the alternatives are is not the best way to go. I have projects in monorepo that use golang for some components.

All other languages work fine but working with Go is a pain because of having to link individual modules into the GOPATH. We get that it’ll be slow, but we want it anyway. IMHO a language should empower it’s users instead of dictating them.

In my humble opinion, vendor directories should not be ignored outside of GOPATH.

fetch:
    glide install
    @for dep in $(shell cd vendor; find * -type d -maxdepth 2 -mindepth 2); do \
      echo "Linking $$dep into $$GOPATH"; \
      rm -rf $$GOPATH/src/$$dep; \
        mkdir -p $$GOPATH/src/$${dep%/*}; \
        ln -fs $(shell pwd)/vendor/$$dep $$GOPATH/src/$$dep; \
    done

build: fetch
    ln -fs $(shell pwd) ${GOPATH}/src/gitlab.com/whois/$(shell basename $(shell pwd))
    go build -v

Because I personally have multiple repos in different languages and I just prefer to not install half of them in a GOPATH. Everytime I jump back into go I’m like “Yes I love programming in go! Now create a new project, add a dependency… Oh god.”

Here’s what works for me in GitLab-CI (building the required custom GOPATH to allow the use of vendoring):

build:
    script:
        - mypkg=x/y/z
        - rm -fr workspace
        - mkdir -p workspace/src/$(dirname $mypkg)
        - ln -s $PWD workspace/src/$mypkg
        - GOPATH=$PWD/workspace go build $mypkg/cmd/my-cmd