-
Notifications
You must be signed in to change notification settings - Fork 0
MR15 RubyGems Bundler
The big bosses at ACME, Inc. are so impressed with our mutant roster that they've decided to rename the company Mutantcorp and focus exclusively on mutant-based products.
They want a massively multiplayer mutant battle area, a mutant trading card mobile game, a mutant farm sim—the sky is the limit! And they want to build it all on the basic mutant class that we built for the roster.
In order to share the code across multiple projects, we'll extract our Mutant
class into a gem.
If you've ever used a third-party Ruby library or framework, you've probably used RubyGems, the default package manager for Ruby.
When you install command-line software, like UNIX utilities, you might use Homebrew or MacPorts. In some Linux distributions, including Ubuntu, you might use apt-get
. On others, you might use rpm
or yum
.
To install Ruby itself, you might use rvm
, chruby
, or rbenv
.
These are all examples of package management, and they make the distribution and installation of software dramatically easier than alternative methods.
We all write software in Ruby. Sometimes we need to reuse the same chunk of code in multiple projects. Sometimes our coworkers need to use software we've written for a previous project in a new project. Sometimes we want to share something we've written with the world.
Ruby includes a package manager out of the box. It's called RubyGems. Like other package managers, it provides a standardized structure that we can use to package and distribute software we've written.
To understand how nice this is, let's look at how it was before RubyGems arrived on the scene. Ruby recently celebrated its 20th birthday, but RubyGems wasn't released until 2003 and didn't become part of the standard library until 2007.
Before we had RubyGems, we might release libraries and reusable components as "plugins". If you wanted to use a plugin in your Ruby application, you had to put the code from the original project inside your project in its entirety. You had to commit it to your project's repo. If it needed updated, you had to manually replace it with the newer copy.
Heaven help you if the plugin had dependencies—and it pretty much always had dependencies.
Because you have to be very deliberate about every part of that process, it might make you feel in control, which has its appeal.
Good package management systems still leave you in control while automating the parts that can be safely automated. It's certainly not impossible to run into a dependency issue when installing a gem, but it's a lot less likely.
- Gems allow for code reuse across projects.
- Gems encourage contributions from others.
- Enhancements
- Issues
- Patches
- Input from domain experts (e.g. security, encryption)
- Open source gems are great for your portfolio (although you're all going to stay with your current employer forever, because they're awesome).
You don't need much to create a gem. Just a valid gemspec and your code. But you probably want to follow certain conventions to make managing your gem easier—for you as the author, and for others who may use it.
Jeweler is a tool for managing and releasing gems. It can also generate a scaffold for your gem when you first create it. Jeweler itself is, predictably, a gem.
We are not going to be using Jeweler today.
We have Bundler!
Bundler is also a gem, and you can install it accordingly.
$ gem install bundler
Bundler manages the dependencies in a Ruby application. It was released in 2010, and it's made managing the gems required by a project even easier than RubyGems alone. We'll be using Bundler to manage dependencies soon. For now, we're taking advantage of a different feature.
Bundler can also help you create and manage your own gems. Let's use it to create an new gem.
It's simple to generate the basic scaffolding of a gem with Bundler. We can just use the command bundle gem mutant
to create a gem called mutant
. Since we want to avoid naming conflicts with other gems, we'll namespace it right off the bat.
When generating a new gem with Bundler, you can add a namespace by including a hyphen in the name. Bundler will generate a nested folder structure using the hyphens as delimeters.
Go up a level from where roster.rb lives, because we'll be creating a new Git repo.
$ cd ..
$ bundle gem mutantcorp-mutant
TIP:
..
acts as a reference to the parent of the current file or directory.
If this is the first gem you've created, Bundler will ask if you'd like to generate test files for the new gem using either Rspec or Minitest, two popular test frameworks.
Creating gem 'mutantcorp-mutant'...
Do you want to generate tests with your gem?
Type 'rspec' or 'minitest' to generate those test files now and in the future. rspec/minitest/(none):
Let's choose minitest
.
Bundler will also ask if you'd like to license your new gem under the MIT license, a permissive license that most open source gems use.
Do you want to license your code permissively under the MIT license?
This means that any other developer or company will be legally allowed to use your code for free as long as they admit you created it. You can read more about the MIT license at http://choosealicense.com/licenses/mit. y/(n):
When writing internal libraries for your employer, you're going to want to choose n
. But catness
is going to be so marvelous we'll be itching to share it with the world.
Next, Bundler will ask if you'd like to include a code of conduct.
In case you're new to the field at large, toxic communities are all too common. If you're going to maintain an open source project, and you want to be part of the solution rather than the problem, including and enforcing a code of conduct might be a good start.
Do you want to include a code of conduct in gems you generate?
Codes of conduct can increase contributions to your project by contributors who prefer collaborative, safe spaces. You can read more about the code of conduct at contributor-covenant.org. Having a code of conduct means agreeing to the responsibility of enforcing it, so be sure that you are prepared to do that. Be sure that your email address is specified as a contact in the generated code of conduct so that people know who to contact in case of a violation. For suggestions about how to enforce codes of conduct, see http://bit.ly/coc-enforcement. y/(n):
Now that the interview is over, let's check out the directory structure.
$ cd mutantcorp-mutant
$ tree .
.
├── CODE_OF_CONDUCT.md
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
├── bin
│ ├── console
│ └── setup
├── lib
│ └── mutantcorp
│ ├── mutant
│ │ └── version.rb
│ └── mutant.rb
├── mutantcorp-mutant.gemspec
└── test
├── mutantcorp
│ └── mutant_test.rb
└── test_helper.rb
6 directories, 12 files
Bundler also automatically created a new Git repository for your gem, complete with a .gitignore file.
Let's take a closer look at some of these files.