Open ydnar opened 9 years ago
@ydnar I like your approach.
I think the fetch is the tricky part, because the fetcher
must get the repository and checkout to the history point, considering the support for the current four version control systems which go get
currently support.
I'm not sure, because I haven't check its code, if nut
support the four of them.
@ydnar & @ifraixedes:
import "github.com/user/app/_vendor/github.com/other/package@abf7t4e2"
This approach is similar to what gopack.in is trying to accomplish except that the dependencies are not vendored. One problem I found with having the package version in the import paths is whenever I need to change the package version, I may have to change more than one place, for example, all paths have to be changed from github.com/user/app/_vendor/github.com/other/package@123
to github.com/user/app/_vendor/github.com/other/package@456
.
nut
is designed to allow you to update the dependencies without worrying about the referred import paths: only the dependencies in the vendor
folder is updated to the version specified in Nut.toml
.
I think the fetch is the tricky part, because the fetcher must get the repository and checkout to the history point
Yes, that's exactly what nut
gives you - it checks out the version specified in Nut.toml
.
@jingweno you're right—changing dependencies everywhere would be a pain. I suppose you could encode it once via a tagged comment, and check out the specific version in the vendor directory:
import "github.com/user/app/vendor/github.com/other/repo" //+@ b65e2f
Declaring a conflicting version of a dependency in two different files would be an error.
I suppose you could encode it once via a tagged comment, and check out the specific version in the vendor directory
It sounds like you'd prefer to declaring import paths with version in the Go code. Any reason of that? Having used this approach for a while, e.g. gopack.in
etc, I found it very fragile to define versioned dependencies this way - in your case, I never know what version of a package I'm using unless I find the import statement having the version tag (maybe building a tool to automate that would work, but still not quite straightforward), needless to say updating the version. Why not defining the dependencies and their versions in a "master" file like Nut.toml
? It makes updating the version very straightfoward. It also will never have the conflicting version of a dependency problem as you mentioned.
I didn't think before that having the version in the import or a comment as @ydnar suggested in his last comment implies to update all the files when you update them to another version and then you have to commit a lot of changes to the repository, even though to make commit is a big deal, some people don't want to have those changes in the history.
Then the solution to have a metadata file as Nut.toml
solves that case.
If Go natively introduced versioned dependencies, how would they do it? I suspect it would be embedded in .go
files rather than an external dependencies file.
Tooling exists for parsing Go source files; embedding in comments has plenty of precedent (build flags, generate commands, C).
I suspect it would be embedded in .go files rather than an external dependencies file.
I'd agree with you if Go was to support this, it may be in the Go files. But is it the best solution? I'll need to understand why it's better than a metadata file.
I personally prefer having my dependencies explicitly declared in one place as oppose to spread out across my code base. I really like Nut's approach, which is pretty similar to Rust's Cargo. Nut may even work pretty well with the upcoming Go's external package and hopefully rewriting import paths will no longer be necessary, in the near future.
I really like Nut's approach, which is pretty similar to Rust's Cargo.
Yes, I got the inspiration from cargo
:smile:
Nut may even work pretty well with the upcoming Go's external package and hopefully rewriting import paths will no longer be necessary, in the near future.
Could you give me a pointer on Go's external package? It's to my interest to make nut
future proof.
My bad, I was under the impression that it was almost accepted but it turns out it is still under discussion at: https://groups.google.com/forum/#!topic/golang-dev/74zjMON9glU
What if, instead of parsing a separate dependency file, authors could explicitly list their dependencies in the import statements? The
nut
command would parse Go files looking for vendored dependencies, and fetch / clean as necessary?We did an experiment in an internal package and the following worked:
We manually vendored the dependency in the app’s _vendor directory at
_vendor/github.com/other/package@abf7t4e2
. The only thing missing is a glue tool to find and fetch dependencies missing from the _vendor directory.