A reference for building a Ruby gem. See also the official RubyGem.org Instructions for the latest info on this. There’s probably a bunch of stuff here that is outdated.
There’s a cool 8min
synopsis of most of this https://www.youtube.com/watch?v=g2zJC2XKblo
- Lowercase
- Underscores to separate words
- Dash to indicate an extension of an existing gem
bundle gem {{ GEM_NAME }}
- Answer prompts about which testing suite to use, CI, license, code of conduct, changelog, etc.
- In the root dir
See the the specifiction reference on rubygems.org.
- Create a configuration
attr_accessor
on the main module def self.configure(configuration_class)
class method takes a block and instantiates aConfiguration
object. See this example.
This things is instantiated with a config object.
See sidekiq example.
- Version numbers by default are in
lib/my-gem/version.rb
file. Why is there a file for this and not just hardcoded in the gemspec. No idea. - See semantic versioning.
- See also https://bundler.io/guides/gemfile.html
Rails::Railtie
provides several hooks to extend Rails and/or modify the initialization process.- To implement, an initializer is given an arbitrary name and the related code is placed within the ensuing block.
- Use an initializer to load a module into a Rails component.
require 'rails' require 'my_gem/some_class' module my_gem class Railtie < Rails::Railtie initializer "my_railtie.configure_rails_initialization" do ActionView::Base.send(:include, MyGem::Stuff) end end end
See also will_paginate example.
require 'rails'
require 'my_gem/some_class'
class Railtie < Rails::Railtie
initializer "my_railtie.configure_rails_initialization" do
ActiveSupport.on_load(:action_view) do
include MyGem::SomeClass
end
end
end
# lib/my_gem
require "my_gem/railtie" if defined?(Rails)
An alternative, and possibly safer approach is to just manually include the gem’s module in the Rails’ class where you want to use it.
bin/console
bundle console
irb -r my_gem -I ./lib
or add rake task for the lazytask :console do exec "irb -r mega_lotto -I ./lib" end
-e
flag runs a line of code when the environment starts. Useful if you need to run a config block.- Add it to a Gemfile by pointing to local checkout path
gem "my_gem", path: "~/development/ruby/gems/locotimezone"
- The Rakefile should already be setup to gather test files and run them using
the test framework selected with
bundle gem
.require 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |task| task.rspec_opts = ['—color'] end task default: :spec
Do not add gems to the Gemfile, just define the dependencies in the .gemspec
- Optimistic Version Constraint
Specify any version above a certain version gem
'some_dependency, '>= 1.0'
- Exact Version
gem 'rails', '4.0.2'
- Pessimistic Version Constraint
- Keep the version between minor releases. Example below will
install most recent version between 4.0.0 and 4.1.0. gem
'sass-rails', '~> 4.0.0'
- The decimal places change the version range. This example will
accept patches and minor releases: (4.1, 4.2, 4.0.1,…) gem
'sass-rails', '~> 4.0'
- Keep the version between minor releases. Example below will
install most recent version between 4.0.0 and 4.1.0. gem
- An optional support library can be loaded in the Gemfile when adding
the gem:
gem ‘locotimezone' require: ‘locotimezone/web'
. - Or use an initializer in Rails to add the require statement.
- Since a support library is optional, don’t require it in the main file of my_gem.rb
- In addition to providing libraries of Ruby code, gems can also expose
one or many executable files to your shell’s PATH.* You just need to
place the file in your gem’s bin directory, and then add it to the
list of executables in the gemspec.* touch bin/my_executable* the name
of the file is how it will be called in the terminal* chmod a+x
bin/my_executable* include the executable and dir in the gemspec
# !/usr/bin/env ruby require_relative "../lib/locotimezone"
rake install
to test it. If using rbenv, might need to rehash before it becomes available- Use the Ruby OptionParser to give the script the ability to use switches. See resque cmd line example
gem build my_gem.gemspec
gem install my_gem
- It will look locally first for a gem of that name, before going to rubygems.org
- Rake install in the gem project root will build and install it.
curl -u {{ USERNAME }} https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
gem push my_gem.gem
Build and push in one command with rake release
$ gem unpack some-gem