Gemfile Constraints
You can specify various different constraints in your Gemfiles when requiring other gems:
~> # the pessimistic version constraint
=, >, <, >= # obvious, right?
Before you go any further, make sure you know about semantic versioning, but be aware that not everyone uses it correctly (or at all).
The pessimistic constraint says that you can update the most minor version provided only.
So, ~>1.2.3 means that 1.2.3, 1.2.4, 1.2.5, 1.2.6 would be available, but not 1.3.0.
~1.2 means that 1.2 and all minor versions, 1.3 and all minor versions, etc are available, but not 2.0.
There is plenty of very vehement advice on what constraints to use and when. Here’s what I think: It depends.
If you are writing a gem, or library that will be used in many places, you probably want your code to run in as wide a variety of configurations as possible. Therefore you will want to use a loose constraint in your Gemfile, and only tighten it when you have to (e.g. for security fixes or when essential library functionality is introduced).
If your code is a stand-alone piece of software, you have a different set of requirements. In this case, you want a known configuration that you have tested and are confident that it works in production. Often, a more cautious approach is required.
The Gemfile and Gemfile.lock
The when bundler does its thing, it creates a dependency tree from the Gemfile and creates a Gemfile.lock file that contains the dependency requirements and the specific versions of the gems it has bundled. The information in the Gemfile.lock allows you to reproduce the gem environment (in terms of gem versions) precisely, which is essential for (regression) testing.
Recommended approach
For standalone software
Keep your Gemfile as loose as possible. Add restrictions when necessary. Assume semantic versioning, but be careful. Keep your Gemfile.lock under version control.
For writing gems & libraries
- Keep your Gemfile as loose a possible.
- Don’t keep your Gemfile.lock under version control.
- In your Gemfile, include references to:
- a
.local
file for any personal tools you may use that, but are not necessary to share - the gemspec See my other post about custom gemfiles
- a
Post Script
The semantic versioning specification is very clearly only talking about 100% documented APIs. However, you should really apply semantic versioning to all your software.
What exactly an API for a web site or an application is, exactly, isn’t always completely clear, especially in the language used by the semver spec.
But, basically:
- You fixed it: PATCH
- You added a feature: MINOR
- You broke an existing feature: MAJOR
Applications often don’t apply this type of versioning. Even the Ruby language itself doesn’t. This is largely, I suspect, because a MAJOR version upgrade is more marketable.
But, you can still apply your semantically versioned tags internally.