There are different tools out there for creating gems. Back in the time, you could achieve this by using tools like Echoe or Jeweler. But you can do the same by using Bundler. Bundler is mostly use as a way of managing dependencies, but not a lot of people know you can use it to create a gem as well.
Run the ‘bundle gem’ command and pass your gem name as a parameter:
$ bundle gem my_gem create my_gem/Gemfile create my_gem/Rakefile create my_gem/LICENSE.txt create my_gem/README.md create my_gem/.gitignore create my_gem/my_gem.gemspec create my_gem/lib/my_gem.rb create my_gem/lib/my_gem/version.rb Initializating git repo in <path-to-gem>/my_gem
As you can see, the bundle gem command creates your gem directory and generates all necessary files to start. You also see that it automatically initializes an empty git repository.
my_gem.gemspec
Let’s take a look at the gemspec file. The only thing you have to is fill in the TODO items and you’ll have a working gemspec file. Though I prefer to alter the following as well:
- Prefer single-quoted strings when you don’t need string interpolation or special symbols
- Prefer %w to the literal array syntax when you need an array of words
- Avoid %q unless you have a string with both ‘ and ” in it
Also check the other gem files if you can apply one of the above ‘rules’.
You gemspec would then look like:
# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'my_gem/version' Gem::Specification.new do |spec| spec.name = 'my_gem' spec.version = MyGem::VERSION spec.authors = ['Michaël Rigart'] spec.email = %w(no@spam.com) spec.summary = 'Short summary of my_gem' spec.description = 'A bigger description describing my_gem' spec.homepage = 'https://michaelrigart.be' spec.license = 'MIT' spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = %w(lib) spec.add_development_dependency 'bundler', '~> 1.3' spec.add_development_dependency 'rake' end
One interesting part of this file are the file attributes towards the end of the file. Each of these is determined at runtime by using the git ls-files command by using git to determine the files that will be included in the gem and this is why bundle gem creates a git repository. This will also inherit the behavior of the .gitignore file so that temporary files and other files you don’t need are excluded from the gem as well.
MyGem::VERSION
You gem version number is defined as a constant called MyGem::VERSION. You’ll find the version.rb file in the lib/my_gem directory. All this file is responsible for is defining the version number.
So when you wan’t to update you gem to a newer version, increase this number.
module MyGem VERSION = '0.0.1' end
my_gem.rb
The other file generated in the lib directory is a file called my_gem.rb. This is the file that’s loaded when your gem is required. You can put any code in this file or create other files in the lib directory and require them here.
require 'my_gem/version' module MyGem # Your code goes here... end
Gemfile
In Rails applications, the Gemfile manages gem dependencies with Bundler. When we look inside this Gemfile, we’ll see that is has just one command: gemspec.
source 'https://rubygems.org' # Specify your gem's dependencies in my_gem.gemspec gemspec
The gemspec command will look inside your gemspec file for the dependencies and load them through Bundler. It’s best practice to just let Bundler handle the dependencies and load them automatically through the Gemfile.
Rakefile
The Rakefile only contains one rule by default:
require ‘bundler/gem_tasks’
This code generates three tasks. You can see them by running rake -T
$ rake -T rake build # Build my_gem-0.0.1.gem into the pkg directory. rake install # Build and install my_gem-0.0.1.gem into system gems. rake release # Create tag v0.0.1 and build and push my_gem-0.0.1.gem to Rubygems
README.md and LICENSE.txt
By default, gems include the MIT license. You can choose yourself whether you want to change to another license or not. Don’t forget to alter the gemspec license item if you do.
The README.md file contains the basic information about your gem: what is does, how to install, how to use it and how to contribute. Write all necessary information and you are good to go.
Publishing
Once your gem is finished, you are ready to publish your first version. Simply run the command:
$ rake build
This rake task generates a .gem file in the pkg/ folder. You now have a gem ready for use. So when you are sure, you can release your gem with the command:
$ rake release
This rake task will create a v0.0.1 tag, build the gem and push is to Rubygems.