Hacker News new | ask | show | jobs
by ollysb 5055 days ago
For a number of reasons Bundler/rubgems does a far better job of reproducible builds.

1) Maven doesn't generate an equivalent of Bundler's lock file. It resolves the versions to be used on each build. If you have dependencies on snapshot versions then there's no way to ensure that all developers are using the same snapshot. OK, you can always specify versions explicitly, but then you lose the benefits of snapshots etc. Bundler's lock file allows you to easily check for newer versions(a gem at a time if you like) without losing reproducible builds.

2) Developers can't upload their jars to the central maven repository. There are gatekeepers. This means that the latest versions of many projects aren't in the central repository. For those projects you have to use their own specific repository. This leads to problem 3. With rubygems developers can upload gems straight into rubygems.org. Also, because most projects are in github and you can specify git dependencies with Bundler you're able to depend on any version of a project(regardless of whether or not it's been released to rubygems.org), all the way down to the commit level.

3) 3rd party repositories change and can be unreliable. This means a jar can become unavailable without any notice. In practice the only way to guard against this is to use a proxy repository like nexus or artifactory, yay, another server to maintain...

1 comments

1) The whole value of depending on snapshots is letting each developer run everything against their local, possibly-modified versions; there would be no point forcing snapshot builds to be reproducible. Release builds aren't allowed to depend on snapshots. Maybe I'm just too used to maven, but I don't see how you'd do it any other way.

2) Gatekeepers have their advantages; how you run a repository is pretty independent of the build tool. It would be possible to start a "anyone can upload anything" maven repository if this was thought useful.

3) Surely the notion of having your build depend on a random third-party git repository is far more worrying than depending on a random third-party maven repository - wouldn't you need to set up a git mirror server, which is more effort than nexus or artifactory?

First of all, let me say I'm not a maven hater. If I was working on a java project I'd use it.

1) The problem is that until you lock down the dependencies you can never be sure exactly which versions will be used. When you use bundler it generates a file specifying all of the versions that should be used. This gets checked into your repository so everyone is sharing exactly the same versions. This means you don't get situations where you check some code in and you break the build because the build server has downloaded a newer version of a dependency(used to happen a lot for me).

2) It's true it would be possible to start a "anyone can upload anything" repository. Having seen how well rubygems.org works in this scenario I think the java community should really get one organised. Either by enhancing the central maven repository or replacing it entirely(it's always been damn slow to browse anyway).

3) In my experience Github projects tend to be pretty persistent, if you have any concerns though you can always hit the fork button and depend on that. Having said that, using git dependencies is definitely the plan B option.

>1) The problem is that until you lock down the dependencies you can never be sure exactly which versions will be used. When you use bundler it generates a file specifying all of the versions that should be used. This gets checked into your repository so everyone is sharing exactly the same versions. This means you don't get situations where you check some code in and you break the build because the build server has downloaded a newer version of a dependency(used to happen a lot for me).

So how's this different from using non-snapshot dependencies in maven? You mentioned checking for new versions as an advantage for bundler, but you can do that with a single command in maven.