LoginSignup
30
27

More than 5 years have passed since last update.

Gemの作り方:ActionMailerSandboxというGemを初めて作ってみたので、作り方をまとめた

Last updated at Posted at 2015-09-09

Gemを初めて作ってRubyGemsで公開したので、作業メモと感想をまとめてみた。

作ったGemはなんてことはないもので、ActionMailerのメール送信先を強制的に変更するもの。開発時に飛ばすメールを全部自分の手元に飛ばすために作った。

Gemの作り方

Gem作成コマンド

RailsにもRailsプラグインがあり、そちらでもGemのスケルトンを作れるみたいだけど、Raisl用だろうと普通のGemだろうと、bundleコマンドで作るのが良いと思う。

$ bundle gem newgem -t

なお、Railsプラグインの作り方は以下のコマンド。作成される物の構成は大きく変わらない。

$ ./bin/rails plugin new newplugin

Gemの初期設定

hoge.gemspecというファイルがあり、それがGemの設定ファイル。

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

Gem::Specification.new do |spec|
  spec.name          = "newgem"
  spec.version       = Splug::VERSION
  spec.authors       = ["zaru@sakuraba"]
  spec.email         = ["user@example.com"]

  spec.summary       = %q{TODO: Write a short summary, because Rubygems requires one.}
  spec.description   = %q{TODO: Write a longer description or delete this line.}
  spec.homepage      = "TODO: Put your gem's website or public repo URL here."

  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
  # delete this section to allow pushing this gem to any host.
  if spec.respond_to?(:metadata)
    spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
  else
    raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
  end

  spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.10"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec"
end

TODOと書かれている所を埋めていくと良い。具体的には以下の3つ。homepageにはGitHubのリポジトリを指定しておけばOK。全て英語で書く。

  • spec.summary
  • spec.description
  • spec.homepage

もし今から作ろうとしているGemは非公開、プライベートなGemだ!っていう場合は、spec.metadata['allowed_push_host']にpushしてもよいホストを指定しておこう。誤操作で公開してしまうことを防ぐことが出来る。そうじゃなくて、全世界に公開だ!という場合は、if spec.respond_to?の下りから全部消しても構わない。

Gemのデバッグ方法

普通にRspecでテストが書けるので、普通にテストすれば良い。

$ bundle exec rspec

Gemを組み込んで動作テストしたい

作ったGemをとりあえずテスト的に導入したいときがあります。その場合は、すでに編集したファイルをコミット済みの上で、以下のコマンドを実行するとローカルにインストールされます。

$ bundle exec rake install

使って見るにはrequireで呼び出せばOKです。なぜかpry環境下だと読みこむことが出来なかったので、irbで試しています。

$ irb
> require `newgem`

GemをRubyGemsに公開する

動作テストも終わり、いよいよ公開したいということになりました。まずは、RubyGems.orgにアクセスしユーザ登録をします。簡単です。そして、マイページにアクセスをして、設定ファイルのダウンロードコマンドをゲットします。

$ curl -u zaru https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials

こんなやつ。

そしたらいよいよリリースする。

$ bundle exec rake release

RubyGemsのGemを更新したい

何らかのバグ解消や新機能の追加でRubyGemsに公開したGemを更新したいという時には、Gemのバージョンを上げる必要がある。

lib/splug/version.rb
module Splug
  VERSION = "0.1.0" # ここのバージョンを変更する
end

あとはコミットしてプッシュしてからのrake releaseコマンドで完了。簡単ですね。

Gem独自の設定ファイルを作りたい

Gem自身にはデフォルトの設定があり、利用者側がそれを上書きできるような設定ファイルが欲しい。よくあるやつです。こんな時にもActiveSupportが強力な味方になってくれる。

lib/newgem/config.rb
require 'active_support/configurable'
module Newgem
  def self.configure(&block)
    yield @config ||= Newgem::Configuration.new
  end

  def self.config
    @config
  end

  class Configuration
    include ActiveSupport::Configurable
    config_accessor :hoge_configure
  end

  configure do |config|
    config.hoge_configure = "hoge"
  end
end

active_support/configurableを使うことで簡単に設定ファイルの下準備が可能になる。この例だとhoge_configureという設定キーを作り、Gem上ではデフォルトhogeが指定されている。要はブロックを渡して中身を上書きする感じ。

lib/newgem.rb
require "newgem/version"
require "newgem/config"

module Newgem
  class Newgem
    def example
      p Newgem.config.hoge_configure
    end
  end
end

Gem内部から設定値を使用するにはNewgem.config.hogeといった形で呼び出すことが出来る。

利用者側

Rails環境下の例になるが、こんな感じで上書き設定が可能になる。

Rails.root/initializers/newgem.rb
Newgem.configure do |config|
  config.hoge_configure = 'piyo'
end

Gemを作ってみて

今回作ったのはRailsに付属しているActionMailerのサンドボックス化するGemで、中身は単純にモンキーパッチでしかなく、モンキーパッチならGemじゃなくて良いじゃんとか思ったんだけど、プロジェクト作るたびにモンキーパッチ書いてたら面倒だなーと思ってGemにしてみた。この作法がGem界隈で正しいのかは知らない。

でもGemにして公開したことで同僚に簡単に勧められるようになったし良かったと思っている。Gem作成の第一歩としては、とても小さくて踏みやすい一歩。作ってみると思っていた以上に簡単だったし、公開自体もなんのことはない感じ。

無駄にGemを作る意味はないけど、なんらかの目的や役割が果たせるのなら、ガンガン作っていっていくと良いような気がした。

30
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
27