[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 部分を修正しておく。
# 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']
に公開サーバ(会社のサーバなど)を指定する。
# 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! を実装する。
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/
以下の対応するファイルを修正する。
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
を作成する。
#!/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章割かれているようなので読みたい。