• Home

  • Custom Ecommerce
  • Application Development
  • Database Consulting
  • Cloud Hosting
  • Systems Integration
  • Legacy Business Systems
  • Security & Compliance
  • GIS

  • Expertise

  • About Us
  • Our Team
  • Clients
  • Blog
  • Careers

  • VisionPort

  • Contact
  • Our Blog

    Ongoing observations by End Point Dev people

    Specify versions for your dependencies in your Gemfiles

    Kamil Ciemniewski

    By Kamil Ciemniewski
    November 7, 2013

    How often have you been too lazy to put a version spec for gems you depended on in your projects? Do you fear updating the gems your app uses in production?

    Here is an elusive-obvious tip for you: Always specify version numbers for your dependencies in your app’s Gemfile.

    Version specs should:

    • be strict numbers for very fragile gems like Rails

    • use the pessimistic operator for others (with ~>)

    Updating apps with versionless Gemfiles is painful

    Newer gem versions often break compatibility. That makes updating a disaster if you don’t have any restrictions in place for your dependencies.

    We should coin a new term in the field of psychology: Update Anxiety.

    That’s precisely the state the vast majority of us is in when proceeding to update dependencies in our projects.

    In Rails, having a versionless Gemfile makes clean updates impossible.

    Fearing the update makes your app susceptible to bugs

    Newer versions of gems are there, not only for delivering new features. The history of changes between different versions mostly show changes related to bug fixes. If you see a gem which mostly delivers new features without fixing bugs—​stay away from it!

    If you do not update the gem set out of fear—​you could be missing out on available security updates and bug fixes.

    Fragile gems influence the whole stack

    There are some gems that you should update very carefully. These updates require planning and consideration before they are applied.

    Every Rails application is a stack of components which are built upon others. Rails operate on top of Rack and some middleware. Active Admin operates on top of many others like Active Record or meta search.

    Updating components that “live” at the bottom of the stack can influence every component above them.

    This it the reason you should treat such dependencies with care and specify a static version number like:

    gem 'rails', '3.2.14'
    

    In “semantic versioning” we trust

    Ruby Gem authors strongly advise following the “semantic versioning policy”. A versioning policy is just a way of incrementing next version numbers for a project.

    You can find a link to more info about this in the links at the bottom of this post.

    As per the ruby gems guides “semantic versioning” explains:

    PATCH 0.0.x level changes for implementation level detail changes, such as small bug fixes

    MINOR 0.x.0 level changes for any backwards compatible API changes, such as new functionality/features

    MAJOR x.0.0 level changes for backwards incompatible API changes, such as changes that will break existing users code if they update

    There is no enforcement of this by RubyGems for gems that are being pushed. Most of gems (if not almost all) follow it quite well though.

    The ‘pessimistic operator’

    Ever seen the ‘~>’ operator in Gemfiles? It’s called pessimistic because it:

    • allows for update up to the maximum number of the last specified digit

    • disallows any higher

    In tandem with the semantic versioning this gives us a possibility to say: “Allow any bug fix for the version 1.2.0 but reject minor changes”.

    You could specify it by placing:

    gem 'music-beers-and-unicorns', '~> 1.2.0'
    

    This allows you to use

    bundle update
    

    Without that much fear and hassle.

    More to read

    Interested in reading more? Here are some links for you:

    http://guides.rubygems.org/patterns/#semantic_versioning

    https://semver.org

    https://robots.thoughtbot.com/rubys-pessimistic-operator

    https://robots.thoughtbot.com/a-healthy-bundle

    https://github.com/thoughtbot/guides/tree/master/best-practices#bundler

    ruby rails


    Comments