Syndication Icon
Published December 13, 2020 Updated December 30, 2020
Cover
Ruby Bundler Scaffold Alternatives

The release of Bundler 2.2.0 changes how gems are generated. The experience was surprising enough to want to take a moment to discuss the new behavior, point out areas of improvement, and leave you with alternatives for improving your workflow.

Without further ado, let’s dive in!

Gem Generation

After upgrading to Bundler 2.2.0, I thought it would be interesting to see what’s new with gem generation by choosing to generate a demo gem:

Cover

As you can see from the above screenshot, I was immediately confronted with multiple prompts. This is new behavior. Thankfully, after going through this process once, I was no longer confronted with further prompts:

Cover

I much prefer the latter experience because encouraging swift gem generation with safe defaults — even if opinionated — is a better experience than being forced to think about all options up front.

Gem Configuration

For those not familiar with Bundler, it might not be entirely obvious where the above configuration is stored. The following will discuss the default and XDG configuration options available to you.

Default

By default, Bundler uses a global configuration which can be inspected via cat $HOME/.bundle/config:

BUNDLE_JOBS: "3"
BUNDLE_IGNORE_MESSAGES__HTTPARTY: "true"
BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES: "true"
BUNDLE_GEM__TEST: "rspec"
BUNDLE_GEM__MIT: "true"
BUNDLE_GEM__COC: "true"
BUNDLE_GEM__CI: "circle"
BUNDLE_GEM__RUBOCOP: "true"

The first three lines were configured previously by me while all lines prefixed with BUNDLE_GEM were added by Bundler during earlier generation of the demo gem. Unfortunately, none of the gem configuration is explained in the Bundler Configuration or Bundler Gem documentation.

XDG

XDG is nice UNIX standard for organizing program configurations, caches, data, etc. Since I am the maintainer of XDG for Ruby, it’s hard for me to enjoy non-XDG configurations as found with Bundler’s default configuration. That said, it is possible to contort Bundler to behave in an, almost, XDG-like manner using the following global variables:

export BUNDLE_USER_CACHE="$HOME/.cache/bundler"
export BUNDLE_USER_CONFIG="$HOME/.config/bundler/configuration.yml"
export BUNDLE_USER_HOME="$HOME/.local/share/bundler"
export BUNDLE_USER_PLUGIN="$HOME/.local/share/bundler/plugin"

The above configuration is what I use via my Dotfiles $HOME/.bashrc file. You might want to use these settings for your environment too, especially if you automate the setup of your machine.

Scaffold Alternatives

While fine for quick exploration, over time Bundler looses it’s ability to scale once you are developing and maintaining multiple projects and/or gems. For that, I’d like to suggest the following alternatives for consideration.

Rubysmith

Rubysmith was designed to fill a gap where you need to generate a Ruby project with professional and configurable defaults while also needing something more sophisticated than a Bundler Inline script. The default experience focuses on letting you get started quickly:

bundle install rubysmith
rubysmith --build demo

You can customize project generation further by using command line options or even adding a global and/or local YAML configuration. The power is yours!

Rubysmith can also be a great tool as an interview rubric if you want to see if an engineer can design, implement, and provide a working Ruby project of high quality for review and discussion.

See the Rubysmith documentation for further details.

Gemsmith

Gemsmith was designed to replace Bundler’s default gem generation with professional tooling based on years of experience of developing and maintaining projects published on RubyGems. Getting started is roughly equivalent to Rubysmith:

bundle install gemsmith
gemsmith --generate demo

As with Rubysmith, Gemsmith provides support for command line options as well as global and/or local configuration customization. For further details, check out the Gemsmith project documentation.

Conclusion

I hope the above was a useful exploration of using Bundler, Rubysmith, and Gemsmith to generate new Ruby projects. All have their uses but I do hope you’ll consider reaching for Rubysmith and/or Gemsmith when building your next Ruby project. 🎉