Hacker News new | ask | show | jobs
by pcx 2958 days ago
I think the current approach of announcing the death of `dep` before even having a stable alternative (`vgo`) is deeply flawed. With `dep` the ecosystem finally had something most of the developers agreed on, despite whatever shortcomings it had. The model was working. They could have adopted dep and improved on it. The packaging story for Golang has gone from worse to OK to worse again.

After all this progress, we still don't have a stable alternative and no clear date as to when it might be ready or even worse, the community is still not sure vgo will be the final one. Golang should be about pragmatic, practical decisions. The packaging situation is just the opposite.

3 comments

I don't disagree — dep has been a huge improvement on Go's package management story. Until dep was stable, we were using Glide, which is extremely buggy.

That said, if you ignore the doubts and arguments about the sanity of its dependency resolution algorithm, I think vgo's introduction of modules is its real contribution.

Go packages have been problematic since the start since their design, naively, conflates a bunch of concepts that most developers keep separate: File location, file structure and source repository. That is, when you do 'import "github.com/foo/bar"', there's a whole bunch of conventions at play that dictate where it can be fetched from and where it should be in the file system. Aside from the fact that the $GOPATH convention is maddeningly annoying to many developers, the design has several issues, such as that an entire git repository has to be fetched in order to use a nested package, or that a package can have multiple import paths. But getting rid of $GOPATH is in itself a huge deal.

I'm personally less concerned with the new MVS algorithm (though I personally prefer the more traditional lock file approach such as that used by dep, Cargo, Bundler, NPM, etc.), as long as I can get modules. While getting modules retrofitted into depwithout all the other stuff in the proposal would be lovely, I don't know if the module design is too dependent (heh) on the rest of vgo's versioning thesis to be separated out.

All of this feels like a classic case of "the perfect is the enemy of the good". Package and dependency management in Go is honestly a total mess today and with vgo challenging all current assumptions about how to generally approach packagement, it brings complete paralysis to the simple question of "how should I organize my dependencies right now".

As much as I loathe JavaScript or Ruby these days for their language, using npm or bundler simply feels sane despite all of their warts. Yes, `left-pad`. Yes, they do have their issues. But seriously, they just work and all open source packages comply to their specifications. And they can and do evolve gradually, like yarn shows.

It's just so funny how careful the Go community seems to tread about not breaking their language with all these Go 2 proposals and general resistance to new features — and then completely ignore this spirit to "move fast and break things" when it comes to package management.

> using npm or bundler simply feels sane

I feel the opposite. Lock files are awesome when your developing a package, but after you release it, you are at the mercy of all your dependencies in making sure that they don't break semvar. Each "npm install" will ignore any lock file your package was using during development.

It would be awesome if I could distribute a package-json.lock file with my npm package and have yarn/npm use it when resolving packages on fresh installations.

Yeah, this would mean that there may be duplicated libraries in your node_modules tree, each with a slightly different version, even if semver compat. However, people break semver to often anyway.

I want to deploy a package to npm and be sure that it will never break, ever.

Can't you do this right now by specifying exact dependency versions in package.json? Lock files should be for applications, not libraries.
Yes, but "npm install" will by default add a semver-compat package version. The vast majority of packages out there use what "npm install" gives you be default.

Furthermore, even if I use exact versions in my package.json, that doesn't stop my referenced packages from internally referencing semver-compat versions.

At the very least, you should reference exact versions at the top level. It is better than nothing.

> Each "npm install" will ignore any lock file your package was using during development.

That's true for npm, but not for bundler (luckily).

This is essentially what shrinkwrap does. Apparently it has issues, but it's designed to be the lock file for your package.json.
WRT modules, that seems like very confusing terminology. It seems to me that vgo calls what all others call packages moduels, and the fact that module is a really overloaded term does not help.
Go already has "packages", so it's not something that can be used for what vgo calls modules.

A Go package is similar to a Java or Python package; it's just a namespace. A vgo module can be thought of as a collection of packages that have a version number and a single canonical name.

I don't find the terms particularly confusing, given that Go doesn't already have anything called a module. It would really only be confusing if you're deep into another language that has "packages" and "modules". I personally don't find it difficult to context switch like that.

AFAIK for many languages a module is a unit of source code, e.g. a .py file for Python, and many modules constitute a package. And many times C/C++ are criticised for not having "modules" and for people having to #include header files which need to be maintained as a redundant module interface for the .o files. In Haskell every file generally starts with "module ModName where", and again, many modules make up a package.

Certainly it's not that big of a confusion, but still will probably be one in discussions, especially for polyglot programmers.

> They could have adopted dep and improved on it.

Not really because:

- The scope is different. dep is a package management tool. vgo is more than that. vgo intends to fully replace the go command. This is how we deprecate GOPATH.

- The underlying principles are different enough to make it difficult to "improve" on dep. It looked easier to start from scratch.

References:

"Go += Package Versioning", Russ Cox, https://research.swtch.com/vgo-intro

"FAQ: Why is the proposal not “use Dep”?", Russ Cox, https://github.com/golang/go/issues/24301#issuecomment-37122...

dep was always written with the intention that it would be merged into or replace to go tool. And it's still not settled that the underlying principles of vgo are valid -- which this article begins to unpack.
Yes! Speaking as a sysadmin who writes Go tools from time to time along with a lot of Bash, Ruby, etc, I’m no expert in the land of Go. But in terms of designing my code to be shareable and figuring out how to integrate it with other source code I deal with every day is a mess. dep had seemed a very promising direction, and so I’m really frustrated to see it’s been deprecated and we are still seemingly years out from a solution which may not even work well in the end. Quite honestly the situation is actively holding back Go, as it’s very hard to convince developers used to lock files and well defined packaging to build anything in a language with no official story on this, even after a decade. Go is rapidly losing the momentum it had for a while now that Rust is starting to become a more stable target and given Go’s inability to address package versioning.
From what I read `dep` isn't deprecated, and is right now the recommended way to track dependencies. I used `dep` in a project I started a bit ago (around the time of the announcement of `vgo`) and it's been working out just great.

That said I agree it's super frustrating, and the vgo announcement just had zero finesse. This isn't a language of experimenters hacking away, there are large production systems that run on solely Go code. Upending the main tool (`go` itself) and the versioning strategy is not to be taken lightly.

> Go is rapidly losing the momentum it had for a while now that Rust is starting to become a more stable target and given Go’s inability to address package versioning.

Here I disagree. Rust is fine for small utilities right now, but if you start building larger apps, developing with futures, tokio, and some of the other async libraries is a nightmare. The APIs are moving really quickly (`futures` hit 0.2, `tokio` is on 0.1 so I don't blame them really) and the ecosystem is still extremely immature. I'm excited for Rust, but it's not yet at the point that I want to build a complex application.