zakihayaメモ

RubyとRailsのことが中心

bundlerを使ってGemを作成する

Gemの作り方を勉強するために、どうしようもないGemを作ってみます。
テストを作成し、Travis CIで自動テストができることが目標です。

ソースはこちら
zakihaya/hello-zakihaya · GitHub

Gemを作成する準備

Gemの雛形を作成する

$ bundle gem hello_zakihaya

gemspecファイルを編集する

# hello_zakihaya.gemspec

# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'hello_zakihaya/version'

Gem::Specification.new do |spec|
  spec.name          = "hello_zakihaya"
  spec.version       = HelloZakihaya::VERSION
  spec.authors       = ["hayazaki"]
  spec.email         = ["toru.hayazaki@gmail.com"]
  spec.description   = %q{greeting with zakihaya}
  spec.summary       = %q{You can greet to zakihaya with modification whatever you want}
  spec.homepage      = "https://github.com/zakihaya/hello-zakihaya"
  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 = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.3"
  spec.add_development_dependency "rake"
  spec.add_development_dependency "rspec"
  spec.add_dependency "activesupport"
end

編集したのは下の2点です。

  1. spec.description、spec.summaryの部分がTODOになっているので記述
  2. activesupportrspecの依存関係を追加

Gemfileにはgemspecと書いてあるのでノータッチ。

Gemをインストール

$ bundle install

テストを実装する

ディレクトリとファイルの準備

テストコードを置くディレクトリを作成する

$ mkdir spec

spec_helper.rbを作成する

# spec/spec_helper.rb

require 'rubygems'

# rspecの設定など
RSpec.configure do |config|
end

テストの実装

# spec/hello_zakihaya_spec.rb

require 'spec_helper'
require 'hello_zakihaya'

describe HelloZakihaya do
  describe "#say" do
    let(:hello_zakihaya) { HelloZakihaya.new }

    context "with modification" do
      it do
        expect(hello_zakihaya.say("small")).to eq "Hello small zakihaya"
      end 
    end 

    context "without modification" do
      it do
        expect(hello_zakihaya.say).to eq "Hello zakihaya"
      end 
    end 
  end 
end

テストを実行する時は

$ bundle exec rspec

Gemの中身を実装する

実行ファイルを編集

普通はこのファイルはmoduleにしておくそうなのですが、今回は1ファイルなのでclassにしちゃいました。

# lib/hello_zakihaya.rb

require "hello_zakihaya/version"
require "active_support/all"

class HelloZakihaya
  def say(modifiation = nil)
    if modifiation.present?
      "Hello #{modifiation} zakihaya"
    else
      "Hello zakihaya"
    end 
  end 
end

version.rbを編集

# lib/hello_zakihaya/version.rb 

class HelloZakihaya
  VERSION = "0.0.1"
end

テストを実行

$ bundle exec rspec
..

Finished in 0.00145 seconds (files took 0.31777 seconds to load)
2 examples, 0 failures

問題なさげ

試しに実行してみる

$ irb -I ./lib -rhello_zakihaya
irb(main):001:0> hello_zakihaya = HelloZakihaya.new
=> #<HelloZakihaya:0x007f871a271430>
irb(main):002:0> hello_zakihaya.say('small')
=> "Hello small zakihaya"
irb(main):003:0> hello_zakihaya.say
=> "Hello zakihaya"

何やらいい感じ

Gemfileを使って実行してみる

Gemfileの準備

適当なディレクトリを作成して、Gemfileを置く

# Gemfile

source 'https://rubygems.org'

gem "hello_zakihaya", git: 'git@github.com:zakihaya/hello-zakihaya.git'

Gemをインストール

$ bundle install --path=./gems
Fetching git@github.com:zakihaya/hello-zakihaya.git
Cloning into bare repository '/path_to_dir/zakihaya/gems/ruby/2.0.0/cache/bundler/git/hello-zakihaya-ab6b21fa940a70b867b4448a34a700d718504fad'...
remote: Counting objects: 32, done.
remote: Compressing objects: 100% (22/22), done.
remote: Total 32 (delta 8), reused 29 (delta 5)
Receiving objects: 100% (32/32), 4.23 KiB | 0 bytes/s, done.
Resolving deltas: 100% (8/8), done.
Checking connectivity... done.
Cloning into '/path_to_dir/zakihaya/gems/ruby/2.0.0/bundler/gems/hello-zakihaya-23604ae1e4df'...
done.
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Installing i18n (0.6.9) 
Installing json (1.8.1) 
Installing minitest (5.3.5) 
Installing thread_safe (0.3.4) 
Installing tzinfo (1.2.1) 
Installing activesupport (4.1.2) 
Using hello_zakihaya (0.0.1) from git@github.com:zakihaya/hello-zakihaya.git (at master) 
Using bundler (1.3.5) 
Your bundle is complete!
It was installed into ./gems

問題ナッシング

irbで実行

$ bundle exec irb
irb(main):001:0> require "hello_zakihaya"
=> true
irb(main):002:0> hello_zakihaya = HelloZakihaya.new
=> #<HelloZakihaya:0x007ff6120ca638>
irb(main):003:0> hello_zakihaya.say("small")
=> "Hello small zakihaya"
irb(main):004:0> hello_zakihaya.say
=> "Hello zakihaya"

Travis CIで自動テストを行う

Travis CIと連携する

TravisGithubのアカウントでログインし、連携をONにする

f:id:zakihaya:20140628154941p:plain

テスト結果をReadmeに表示

これを記述すればいいらしい

# README.md

[![Build Status](https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME].png)](https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME])

.travis.ymlファイルを追加

# .travis.yml

language: ruby
rvm:
  - 2.0.0

rakeタスクを追加

# Rakefile

require 'rspec/core/rake_task'
task :default => :spec
RSpec::Core::RakeTask.new

感想など

  • Gemは意外と簡単に作れる。(今回のはブログ書きながらで2時間半くらい)
  • Travis CIを初めて使ったのだが、これは便利。今後も積極的に使ってみたい。

ギモン

  • hello_zakihaya.rbで require "active_support/all" の部分を require "active_support/core_ext" にしてたら、Travisのテストが通らなかった。
    ローカルではOK。なぜだろう。。。

〜参考にさせていただきました〜

Ruby - Gemを作って、自動テストを回して、公開してみる方法 - Qiita