Create a Gem 

in Ruby



presented by Jen Diamond
at Pivotal Labs on Aug. 22, 2013
L.A.Railsbridge Eastside/Westside Monthly Ruby Bash


  • We are going to create a simple Gem in Ruby so we can see what a basic gem looks like. It will be a Lorem Ipsum generator.
  • We will then add the Gem Thor to make it a command line interface. 
  • We will then run a simple rspec test on it so we can view a basic test.


Run this command in your Terminal. 

This creates and names all the files you need for your gem. 

We are going to create a Lorem Ipsum Generator. 

You can call it whatever you want but seeing as we are creating a Lorem Ipsum generator we'll call it lorem.   


    $ bundle gem lorem


Notice that this command also initialized a git repository for you on your local machine and gives you the path name for it.

cd into your lorem directory

$ cd lorem

type ls to list your files that were just generated
$ ls

  Gemfile  lib   L lorem.rb   L lorem      L  version.rb  LICENSE.txt   
lorem.gemspec Rakefile README.md



Add your name, email, summary, a description and a homepage(any website)  to your `lorem.gemspec` file.

In order to create a gem, you need to define a gem specification, commonly called a gemspec.  A gemspec consists of several attributes. Some of these are required; most of them are optional.

The main body of this document is an alphabetical 
list of gemspec attributes, each with a description, example usage, notes, and more.

        \# coding: utf-8
        lib = File.expand_path('../lib', __FILE__)
        $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
        require 'lorem/version'
    
        Gem::Specification.new do |spec|
            spec.name          = "lorem"
            spec.version       = Lorem::VERSION
            spec.platform      = Gem::Platform::RUBY
            spec.authors       = ["your name"]
            spec.email         = ["your@email.com"]
            spec.homepage      = ""
            spec.summary       = %q{Jenipsum generator}
            spec.description   = %q{Generates jenipsum text}
            spec.license       = "MIT"

            spec.add_development_dependency "bundler", "~> 1.3"
            spec.add_development_dependency "rake"

            spec.files         = `git ls-files`.split($/)
            spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
            spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
            spec.require_paths = ["lib"]

        end

If you neglect to change these areas you will get this error when you go to run $ gem build lipsum.gemspec

ERROR: While executing gem ... (Gem::InvalidSpecificationException) "FIXME" 
  or "TODO" is not a description

    Open your file lib/lorem.rb 
    Make it look like this. 

      This is the file that is loaded when people require your gem. 

      You can customize it with the behavior you want it to have.

require "lorem/version"module Lorem
  def self.ipsum
       "Fantastic, yes, but gory. Help. It is a juniper. Pikku and Friendly ate all the kibbles. Formaldehyde, an exacto, a comb, a napkin, and a typewriter combined with vitamins, a bicycle, whiskey, batteries, flippers and a bike messenger twisted around the bend one curve at a time during the entire tour through Texas with Madi and my bass. "
  end
end 




Run this command

$ gem build lorem.gemspec  



Congratulations, 

you have created a gem!


Now you can 

add Thor

Thor helps us build a 
command line interface for our gem. 

What is that you ask...

It is how we "talk" to our computer.
We give it commands it understands through the terminal. 
Ones you may know are cd for change directory or rm for remove.



  Make sure you are still in your 
  lorem directory if not then...

$ cd lorem  

    Create a cli.rb file in lib/lorem 
      In this file create a class that inherits from Thor 
      and your lorem file. 
      Add all of this code.
require "thor" require "lorem"
module Lorem  class CLI < Thor  desc "ipsum", "Lorem Ipsum text generator"  def ipsum  puts Lorem.ipsum  end  end end



Create a bin directory
$ mkdir bin  





    Create executable file naming it what you 
    want your gem command to be; 
    in our case lorem.    
    Do not add a .extention to the end of it, so it's called lorem not lorem.rb or lorem.txt or lorem.jpg
     Add the following code into your bin/lorem file 
#!/usr/bin/env ruby
require 'lorem/cli'

Lorem::CLI.start
                          

   In the lorem.gemspec file, add 

    spec.add_runtime_dependency "thor"
    before end.

\# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'lorem/version'
    
Gem::Specification.new do |spec|
  spec.name          = "lorem"
  spec.version       = Lorem::VERSION
  spec.platform      = Gem::Platform::RUBY
  spec.authors       = ["your name"]
  spec.email         = ["your@email.com"]
  spec.homepage      = ""
  spec.summary       = %q{Jenipsum generator}
  spec.description   = %q{Generates jenipsum text}
  spec.license       = "MIT"

  spec.add_development_dependency "bundler", "~> 1.3"
  spec.add_development_dependency "rake"
  spec.add_runtime_dependency "thor"
              spec.files         = `git ls-files`.split($/)
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.executables   = spec.files.grep(%r{^bin/}) { |f|  File.basename(f) }  spec.require_paths = ["lib"]

end 

Now it's time to run your gem in your commandline!

$ bundle exec bin/lorem ipsum
 
If you get an 
$ ERROR bundler: not executable: 
bin/lorem  
Run $ chmod +x bin/lorem


Now we are going to add a test.

We are using Rspec.



Let's add some rspec testing to our gem 
$ rspec --init

Let's checkout the files that were just generated

$ ls

 Gemfile  lib   L lorem.rb   L lorem      L  version.rb  LICENSE.txt   
lorem.gemspec Rakefile README.md
spec L spec_helper.rb

   In the lorem.gemspec file,  add 

    spec.add_development_dependency "rspec"
    before end.

\# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'lorem/version'
    
Gem::Specification.new do |spec|
  spec.name          = "lorem"
  spec.version       = Lorem::VERSION
  spec.platform      = Gem::Platform::RUBY
  spec.authors       = ["your name"]
  spec.email         = ["your@email.com"]
  spec.homepage      = ""
  spec.summary       = %q{Jenipsum generator}
  spec.description   = %q{Generates jenipsum text}
  spec.license       = "MIT"

  spec.add_development_dependency "bundler", "~> 1.3"
  spec.add_development_dependency "rake"
  spec.add_runtime_dependency "thor"  spec.add_development_dependency "rspec"
              spec.files         = `git ls-files`.split($/)
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.executables   = spec.files.grep(%r{^bin/}) { |f|  File.basename(f) }  spec.require_paths = ["lib"]

end 



Create a lorem_spec.rb file in your spec directory.
This is where you will write your test.

$ touch spec/lorem_spec.rb


    Write this into your spec/lorem_spec.rb


require 'spec_helper' module Lorem describe Lorem do it "should not be empty" do expect(Lorem.ipsum).to_not be_empty end it "should include 'Fantastic'" do expect(Lorem.ipsum).to include('Fantastic') end end end



    Write this into your spec/spec_helper.rb

require "lorem"

# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# Require this file using `require "spec_helper"` to ensure that it is only
# loaded once.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus

  # Run specs in random order to surface order dependencies. If you find an
  # order dependency and want to debug it, you can fix the order by providing
  # the seed, which is printed after each run.
  #     --seed 1234
  config.order = 'random'
end 




     It is now time to run your test...

 $ rspec spec/lorem_spec.rb

    

     This is what you should see...

 $ rspec spec/lorem_spec.rb Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
..

Finished in 0.0032 seconds
2 examples, 0 failures
    


    

     If you see this, read the errors and check your code.

$ rspec spec/lorem_spec.rb 
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
FF

Failures:

  1) Lorem should not be empty
     Failure/Error: expect(Lorem.ipsum).to_not be_empty
     NoMethodError:
       undefined method `ipsum' for Lorem:Module
     # ./spec/lorem_spec.rb:6:in `block (2 levels) in <module:Lorem>'

  2) Lorem should include 'Fantastic'
     Failure/Error: expect(Lorem.ipsum).to include('Fantastic')
     NoMethodError:
       undefined method `ipsum' for Lorem:Module
     # ./spec/lorem_spec.rb:10:in `block (2 levels) in <module:Lorem>'
Finished in 0.0032 seconds
2 examples, 2 failures



    



Once both your tests pass you 

are finished and have a beautiful new gem to experiment with!


Thank you. I hope you enjoyed making a gem. 

Checkout these reference where I gleaned a lot 

of this info from. 

http://railscasts.com/episodes/245-new-gem-with-bundler

http://bundler.io/v1.3/rubygems.html

http://guides.rubygems.org/make-your-own-gem





Also Thanks to Rails Girls Summer of Code where 

I initially made this gem. 


Thanks also to Jessica Lynn Suttles, Andre Arko and Joyce Hsu who all helped me with this presentation.

Create a Gem in Ruby

By jendiamond

Create a Gem in Ruby

Create a Gem in Ruby. See what a simple gem looks like and a simple test by creating your own Lorem Ipsum Generator. Make it a Command Line executable and run a test on it.

  • 4,830