[Ruby] RubyGem の作り方

こちらを参考にサンプルを作成しながら学ぶ。

Contents

ひな型の作成

事前に gem と bundler を update する。

% gem update --system
% gem update bundler
% gem -v
2.6.6
% bundler -v
Bundler version 1.13.0

bundle gem

bundle gem の後に gem name を指定。ここでは dw_test とした。
プロジェクトディレクトリとひな型が作成される。

% bundle gem dw_test -t
Creating gem 'dw_test'...
MIT License enabled in config
Code of conduct enabled in config
      create  dw_test/Gemfile
      create  dw_test/.gitignore
      create  dw_test/lib/dw_test.rb
      create  dw_test/lib/dw_test/version.rb
      create  dw_test/dw_test.gemspec
      create  dw_test/Rakefile
      create  dw_test/README.md
      create  dw_test/bin/console
      create  dw_test/bin/setup
      create  dw_test/.travis.yml
      create  dw_test/.rspec
      create  dw_test/spec/spec_helper.rb
      create  dw_test/spec/dw_test_spec.rb
      create  dw_test/LICENSE.txt
      create  dw_test/CODE_OF_CONDUCT.md
Initializing git repo in /Users/****/projects/dw_test

gem name はユニークなものを付ける。

_- が名前に含まれていると、ディレクトリ構成や呼び出し方に違いが出てくる。

gemspec の修正

dw_test.gemspec に必要な情報を記載する。公開される情報となる。
最低限の対応として ToDo 部分を修正しておく。

dw_test.gemspec
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'dw_test/version'
Gem::Specification.new do |spec|
  spec.name          = "dw_test"
  spec.version       = DwTest::VERSION
  spec.authors       = ["DriftwoodJP"]
  spec.email         = ["DriftwoodJP@users.noreply.github.com"]
  spec.summary       = %q{RubyGem sample for me.}
  spec.description   = %q{RubyGem sample for me.}
  spec.homepage      = "https://github.com/DriftwoodJP/dw_test"
  spec.license       = "MIT"
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
  # to allow pushing to a single host or delete this section to allow pushing 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 do |f|
    f.match(%r{^(test|spec|features)/})
  end
  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]
  spec.add_development_dependency "bundler", "~> 1.13"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec", "~> 3.0"
end

依存 gem なども必要に応じて修正する。
修正後、bundle install する。

% bundle install

gemspec その他生成されるファイルについては下記が詳しい。

rubygems.org へ公開しないための設定

rubygems.org へプライベートな gem をうっかり公開しないための設定。
以下の設定があると rake release 時の振る舞いが変わる。

spec.metadata['allowed_push_host'] に公開サーバ(会社のサーバなど)を指定する。

dw_test.gemspec
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
  # to allow pushing to a single host or delete this section to allow pushing 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

今回は https://rubygems.org/ へ公開するので、これらはコメントアウトする。

実装

lib/dw_test.rb に Hello World! を実装する。

lib/dw_test.rb
require "dw_test/version"
module DwTest
  def self.greet
    'Hello World!'
  end
end

動作確認

irb で動作を確認する。

% bundle exec irb
irb(main):001:0> require 'dw_test'
=> true
irb(main):002:0> DwTest.greet
=> "Hello World!"

テスト(RSpec)

RSpec でテストを書く。
spec/ 以下の対応するファイルを修正する。

spec/dw_test_spec.rb
require "spec_helper"
describe DwTest do
  it "has a version number" do
    expect(DwTest::VERSION).not_to be nil
  end
  describe "#greet" do
    it "returns Hello World!" do
      expect(DwTest.greet).to eq('Hello World!')
    end
  end
end

テストを実行する。

% rspec spec/dw_test_spec.rb
DwTest
  has a version number
  #greet
    returns Hello World!
Finished in 0.01127 seconds (files took 0.61275 seconds to load)
2 examples, 0 failures

rake spec が用意されている(後述)。

実行コマンドの追加

コンソール上で使える run_dw_test コマンドを作成する。
spec.bindir = "exe" となっているので exe/run_dw_test を作成する。

exe/run_dw_test
#!/usr/bin/env ruby
require "dw_test"
puts DwTest.greet

パッケージ

rake タスクが用意されている。

% rake -vT
rake build            # Build dw_test-0.1.0.gem into the pkg directory
rake clean            # Remove any temporary products
rake clobber          # Remove any generated files
rake install          # Build and install dw_test-0.1.0.gem into system gems
rake install:local    # Build and install dw_test-0.1.0.gem into system gems without network access
rake release[remote]  # Create tag v0.1.0 and build and push dw_test-0.1.0.gem to Rubygems
rake spec             # Run RSpec code examples

Gem をビルドし、ローカルにインストールする

% rake install:local
dw_test 0.1.0 built to pkg/dw_test-0.1.0.gem.
dw_test (0.1.0) installed.

インストールを確認する。

% gem list | grep dw_test
dw_test (0.1.0)

実行する。

% run_dw_test
Hello World!

以上で gem のインストールと利用が確認できた。

git commit

必要に応じて README.md も修正する。
修正を行ったら、lib/dw_test/version.rb のバージョン番号も変更する。

% git add .
% git commit -m "first commit"

GitHub に push する。

% git remote add origin git@github.com:DriftwoodJP/dw_test.git

公開

rubygems.org へ公開するかしないか。

プライベートで利用する場合

rubygems.org へ公開せず、プライベートで利用する場合。
リポジトリで管理し、install, generate する。

% git clone git@github.com:DriftwoodJP/dw_test.git
% cd dw_test
% bundle install
% rake install

その他、自前でサーバを立てる方法もある。
GitHub は使えなくなった。

名前がぶつからないようなネーミングで rubygems.org に公開した方が便利そうである。

rubygems.org へ公開する場合

RubyGems.org にアカウントがなければ Sign up する。
初回のみ。
ログイン後、Edit profile | RubyGems.org を開く。

  • Hide email in public profile をチェック(オプション)。
  • Twitter username を追加(オプション)。
  • API ACCESS にある curl ワンライナーを実行する。
    以上で準備が完了する。
    rake release を実行する。
% rake release
dw_test 0.1.2 built to pkg/dw_test-0.1.2.gem.
Tagged v0.1.2.
Pushed git commits and tags.
Pushed dw_test 0.1.2 to rubygems.org.

gem install できるか確認する。

% gem search -r dw_test
*** REMOTE GEMS ***
dw_test (0.1.2)
% gem install dw_test
Fetching: dw_test-0.1.2.gem (100%)
Successfully installed dw_test-0.1.2
1 gem installed
% run_dw_test
Hello World!

RubyGems.org にあることも確認できた。

rake release が途中で停止する場合の対処方法

追記:2021/02/14

https://rubygems.org/ で2段階認証を設定している場合、リリースの途中で停止します。
下記のようなタイミングでワンタイムパスワードを入力すると完了しました。

% rake release
bcupgrade 0.9.4 built to pkg/bcupgrade-0.9.4.gem.
Tag v0.9.4 has already been created.

補遺

e-book があるよう。

「gemパッケージの作り方」として1章割かれているようなので読みたい。

パーフェクトRuby
パーフェクトRuby

posted with amazlet at 16.09.11
技術評論社 (2014-10-31)
売り上げランキング: 51,436