Ruby gems are a way of adding functionality to programs written in Ruby, including the popular web application framework Ruby on Rails. Gems are also a way for people to share their code to the world and contribute to open source.
This is a step-by-step guide to show you how to create and publish your own Ruby gem to Rubygems.org.
Create a git repository
You can use any git service like Github, Gitlab, or Bitbucket for this purpose. In this article we will use Github to share our gem.
Ignore the README, LICENSE, and .gitignore as we will generate those later.
Clone your repository
git clone [email protected]:yourname/onepunchman.git
This will clone an (almost) empty repository. To build our gem, we will use Bundler’s gem creator command to get a skeleton framework so that we can start quickly. This gem creator also provides useful defaults which make our life easier when creating Ruby gems.
We start by creating a temporary directory where we will place the generated code of Bundler’s gem builder.
mkdir TEMPORARY
cd TEMPORARY
bundle gem onepunchman
It will ask some questions on what additional files to include:
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. For suggestions about how to enforce codes of conduct, see bit.ly/coc-enforcement. y/(n): y Code of conduct enabled in config 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 choosealicense.com/licenses/mit. y/(n): y MIT License enabled in config 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): minitest
It is recommended that you include the Code of Conduct declaration, and set the license to MIT License so that others can freely use your code for any purpose. When deciding on the test framework, RSpec is fine but Minitest is the more lightweight option and still does the job.
The previous command will generate the following files:
create onepunchman/Gemfile create onepunchman/.gitignore create onepunchman/lib/onepunchman.rb create onepunchman/lib/onepunchman/version.rb create onepunchman/onepunchman.gemspec create onepunchman/Rakefile create onepunchman/README.md create onepunchman/bin/console create onepunchman/bin/setup create onepunchman/CODE_OF_CONDUCT.md create onepunchman/LICENSE.txt create onepunchman/.travis.yml create onepunchman/test/test_helper.rb create onepunchman/test/onepunchman_test.rb
The main file is located at lib/onepunchman.rb. This file sets up the entire gem and is the one that is included when you run “require ‘onepunchman'”.
Copy all the files under TEMPORARY/onepunchman into the “onepunchman” directory you cloned from github. Make sure you do not include the .git hidden folder.
Update the gemspec
The gemspec defines the details of the gem such as author information, description, dependencies, etc. Update this file to put in the gem’s description, which will be shown publicly once we push this to Rubygems.org.
Gem::Specification.new do |spec| spec.name = "onepunchman" spec.version = Onepunchman::VERSION spec.authors = ["Juan dela Cruz"] spec.email = ["[email protected]"] spec.summary = %q{Destroy all bugs with one punch!} spec.description = %q{This gem fixes all the bugs in your application using a single command.} spec.homepage = "https://rubygems.org/gems/onepunchman" spec.license = "MIT" ...(other details here)... end
Build your gem
You can now try to build or package your gem (without any functionality).
gem build onepunchman.gemspec
WARNING: open-ended dependency on minitest (>= 0, development) is not recommended if minitest is semantically versioned, use: add_development_dependency 'minitest', '~> 0' WARNING: See http://guides.rubygems.org/specification-reference/ for help
When this error message appears, edit the gemspec file to set the minimum versions for all your dependencies.
spec.add_development_dependency "bundler", "~> 1.10" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "minitest", '~> 5'
The build command will create onepunchman-0.1.0.gem. You have now created your own gem, but at the moment it doesn’t do anything.
Add your functionality
Your newly-created gem does not do anything at this point. To add functionality to your gem, we will need to add code in Ruby classes. In this example we will add the code to perform “attacks”.
Add lib/onepunchman/attack.rb
class Onepunchman::Attack def initialize end def normal_punch print "Normal punch!" return "boom!" end def serious_punch print "Serious punch!" return "BOOM!" end end
Require the file in lib/onepunchman.rb
require "onepunchman/version" require "onepunchman/attack" module Onepunchman # Your code goes here... end
Run your gem
Now that you have included something that your gem will do, you can now test it out by running your gem and trying out the “attacks”. First we will need to install the dependencies that our gem needs using the following command:
./bin/setup
This runs bundle install and installs the dependencies of your gem. We can now then install the gem using the usual way, but we specify the actual packaged gem file instead of fetching it via the internet.
gem install onepunchman-0.1.0.gem
To test it out, we can open an IRB (Interactive Ruby) instance and require our gem.
irb
irb> require 'onepunchman'
Alternatively, we can also use the console command that is built in when we used Bundler’s gem creator.
./bin/console
This commands runs an IRB instance where your gem is automatically loaded.
> attack = Onepunchman::Attack.new => # > attack.normal_punch Normal punch! > "boom!" > attack.serious_punch Serious punch! > "BOOM!"
Write tests
It is important that you write tests for your gem. It serves two purposes: it maintains the quality of your code so you do not publish broken functionality, and it also serves as documentation on how your gem works.
When you look at the test folder, you will see two files:
- test_helper.rb
- onepunchman_test.rb
The test_helper.rb file loads your gem and the Minitest gem when you run tests. You do not need to modify this file unless you need additional configuration for your tests.
The sample tests in the onepunchman_test.rb already provide a test that checks whether you have a version specified or not:
require 'test_helper' class OnepunchmanTest < Minitest::Test def test_that_it_has_a_version_number refute_nil ::Psei::VERSION end def test_it_does_something_useful assert false end end
We will need to update the second test so that it actually tests the functionality. For instructions on how to create Minitest specs, please refer to the README.
In this example we will need to test that the normal punch and serious punch attacks return the correct response.
You can create Unit tests or Specs using Minitest:
require 'test_helper' # An example using unit tests class OnepunchmanTest < Minitest::Test def setup @saitama = Onepunchman::Attack.new end def test_that_it_has_a_version_number refute_nil ::Onepunchman::VERSION end def test_normal_punch assert_equal "boom!", @saitama.normal_punch end end
require 'test_helper' # An example using specs describe Onepunchman do before do @saitama = Onepunchman::Attack.new end describe "when using a normal attack" do it "must respond strongly" do @saitama.normal_punch.must_equal "boom!" end end describe "when using a serious attack" do it "must respond VERY strongly" do @saitama.serious_punch.must_equal "BOOM!" end end end
Run your tests using this command:
rake test
If all of your tests pass, it will show an output similar to this:
Run options: --seed 63377 # Running: .Normal punch!.Normal punch!.Serious punch!. Finished in 0.003868s, 1034.2599 runs/s, 1034.2599 assertions/s. 4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
Publish your gem to RubyGems.org
Once we have added the functionality and the corresponding tests to our gem, we can now publish it to the world via Rubygems.org. You will need to provide your account details in order to push your gem.
$ gem push onepunchman-0.1.0.gem Enter your RubyGems.org credentials. Don't have an account yet? Create one at https://rubygems.org/sign_up Email: gem_author@example Password: Signed in. Pushing gem to RubyGems.org... Successfully registered gem: onepunchman (0.1.0)
Your gem is now published to Rubygems.org and you can view your gem using this URL:
https://rubygems.org/gems/onepunchman
Now on your Ruby or Rails code you can now install your published gem!
gem install onepunchman
Releasing new versions
During your gem's lifetime you will need to release a new version when you improve or change the functionality. To do this, update the version in lib/onepunchman/version.rb
module Onepunchman VERSION = "0.2.0" end
Then push your changes and mark your release:
$ git add $ git commit -m "Release for 0.2.0" $ git push $ git tag -a v0.2.0 -m "Add new attacks" $ git push --tags
Build the new version of your gem:
$ gem build onepunchman.gemspec
This will generate onepunchman-0.2.0.gem
Then publish the new version of your gem to Rubygems.org:
$ gem push onepunchman-0.2.0.gem