8

I'm writing an application and import some package B. This package has the vendor directory inside which, in turn, contains package C. I also want to use that package C in my app directly.

So I decided to use glide package manager. It downloads both B and C into myapp/vendor directory, but keeps myapp/vendor/B/vendor/C inside. So when I build my app, it builds with two different versions of C (also with myapp/vendor/C).

How to avoid that?

1) Either, is there a package manager that handles that? govend seems to with its --prune argument, but it doesn't respect the versions of these C packages.

2) Or, how to make glide properly handle the nested vendor directories?

Edit

My example is https://github.com/orloffm/flat. It uses cat and - indirectly - toy packages. cat has some older version of toy vendored and commited into repository. I do glide create && glide install and end up with this:

.
├── flat.go
├── glide.lock
├── glide.yaml
└── vendor
    └── github.com
        └── orloffm
            ├── cat
            │   ├── cat.go
            │   ├── vendor
            │   │   └── github.com
            │   │       └── orloffm
            │   │           └── toy
            │   │               └── toy.go
            │   └── vendor.yml
            └── toy
                └── toy.go

I don't want to have nested vendor directory with toy.

Mikhail Orlov
  • 2,789
  • 2
  • 28
  • 38
  • I don't use `glide` right now, but are you sure you have the latest version? Just a quick glance at the docs shows `"Because of this Glide flattens the dependency tree into a single top level vendor/ directory."` – JimB Jul 26 '16 at 18:13
  • As JimB stated, most current vendoring tools that I've used automatically flatten the dependency tree. This is practically required, because the same package imported from two different unique paths are actually considered two different unique packages, as you found. I know `govendor` does it by default. – Kaedys Jul 26 '16 at 18:55
  • @Kaedys +1 for govendor. I've used it in quite a few projects. – tier1 Jul 26 '16 at 19:35
  • Flattening the vendor directory is indeed a core glide feature; can you also include the exact glide invocation you're using and what your config file looks like? – Sam Whited Jul 27 '16 at 01:05
  • @SamWhited It is `https://github.com/orloffm/flat`. It uses `cat` and indirectly `toy`. But `cat` has some old version of `toy` vendored. I do `glide create` and `glide install` and get vendor/cat/vendor/toy. – Mikhail Orlov Jul 27 '16 at 08:46

1 Answers1

2

I was able to install and run your flat program by making the following changes (also sent you a PR https://github.com/orloffm/flat/pull/1):

1) flat.go needs to import "github.com/orloffm/toy" because of new(toy.RubberToy) - otherwise it doesn't compile

2) add glide.yaml file that list both "cat" and "toy" libraries as dependencies:

package: github.com/orloffm/flat
import:
- package: github.com/orloffm/cat
- package: github.com/orloffm/toy

3) run glide install --strip-vcs --strip-vendor (or the equivalent shortcut glide install -s -v) to install packages and remove nested vendor/ directories (I'm using glide version 0.11.0-dev installed with go get -u github.com/Masterminds/glide; glide install --help shows the --strip-vendor option).

4) GOBIN=$PWD go install && ./flat produces

Cat pushes the toy.
The toy makes a very loud noise.

I think the best would be not to include the vendor directory into your libraries - this messes things up and makes life more difficult for the library users (for example, need to remember to use additional options to glide). Let the "clients" of those libraries - package main packages - either to vendor all the dependencies (including transitive ones) or specify them in a configuration such as glide.yaml and let the tool (glide) to fetch and install them properly.

dmitris
  • 1,441
  • 1
  • 12
  • 13