[Ruby] RubyGem の作り方
こちらを参考にサンプルを作成しながら学ぶ。
[markdown]
> * [RubyGemはめっちゃ簡単に作れる! – 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/ruby-gem-easy-publish-library-rails/)
## ひな型の作成
事前に gem と bundler を update する。
“`prettyprinted
% 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 とした。
プロジェクトディレクトリとひな型が作成される。
“`prettyprinted
% 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 はユニークなものを付ける。
> * [Patterns – RubyGems Guides](http://guides.rubygems.org/patterns/#consistent-naming)
`_` と `-` が名前に含まれていると、ディレクトリ構成や呼び出し方に違いが出てくる。
> * [Name your gem – RubyGems Guides](http://guides.rubygems.org/name-your-gem/)
### gemspec の修正
`dw_test.gemspec` に必要な情報を記載する。公開される情報となる。
最低限の対応として ToDo 部分を修正しておく。
> * [君がOpsでもRubyで書いたライブラリはGemで配ろう – Qiita](http://qiita.com/sawanoboly/items/ede7715c605e5822ad22#%E6%A6%82%E8%A6%81%E3%82%92gemspec%E3%81%AB)
“`ruby: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` する。
“`prettyprinted
% bundle install
“`
gemspec その他生成されるファイルについては下記が詳しい。
> * [bundle gemは何をしてくれるのか? – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20141026/making_of_bundle_gem)
### rubygems.org へ公開しないための設定
rubygems.org へプライベートな gem をうっかり公開しないための設定。
以下の設定があると `rake release` 時の振る舞いが変わる。
`spec.metadata[‘allowed_push_host’]` に公開サーバ(会社のサーバなど)を指定する。
“`ruby: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! を実装する。
“`ruby:lib/dw_test.rb
require “dw_test/version”
module DwTest
def self.greet
‘Hello World!’
end
end
“`
### 動作確認
`irb` で動作を確認する。
“`prettyprinted
% bundle exec irb
irb(main):001:0> require ‘dw_test’
=> true
irb(main):002:0> DwTest.greet
=> “Hello World!”
“`
### テスト(RSpec)
RSpec でテストを書く。
`spec/` 以下の対応するファイルを修正する。
“`ruby: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
“`
テストを実行する。
“`prettyprinted
% 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` を作成する。
“`ruby:exe/run_dw_test
#!/usr/bin/env ruby
require “dw_test”
puts DwTest.greet
“`
## パッケージ
`rake` タスクが用意されている。
“`prettyprinted
% 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 をビルドし、ローカルにインストールする
“`prettyprinted
% rake install:local
dw_test 0.1.0 built to pkg/dw_test-0.1.0.gem.
dw_test (0.1.0) installed.
“`
インストールを確認する。
“`prettyprinted
% gem list | grep dw_test
dw_test (0.1.0)
“`
実行する。
“`prettyprinted
% run_dw_test
Hello World!
“`
以上で gem のインストールと利用が確認できた。
### git commit
必要に応じて README.md も修正する。
修正を行ったら、`lib/dw_test/version.rb` のバージョン番号も変更する。
“`prettyprinted
% git add .
% git commit -m “first commit”
“`
GitHub に push する。
“`prettyprinted
% git remote add origin git@github.com:DriftwoodJP/dw_test.git
“`
## 公開
rubygems.org へ公開するかしないか。
### プライベートで利用する場合
rubygems.org へ公開せず、プライベートで利用する場合。
リポジトリで管理し、install, generate する。
“`prettyprinted
% git clone git@github.com:DriftwoodJP/dw_test.git
% cd dw_test
% bundle install
% rake install
“`
その他、自前でサーバを立てる方法もある。
GitHub は使えなくなった。
> * [GitHub、Gemの自動作成をやめる](https://www.infoq.com/jp/news/2009/10/github-stops-gem-building)
名前がぶつからないようなネーミングで rubygems.org に公開した方が便利そうである。
### rubygems.org へ公開する場合
[RubyGems.org](https://rubygems.org/) にアカウントがなければ Sign up する。
初回のみ。
ログイン後、[Edit profile | RubyGems.org](https://rubygems.org/profile/edit) を開く。
– Hide email in public profile をチェック(オプション)。
– Twitter username を追加(オプション)。
– API ACCESS にある curl ワンライナーを実行する。
以上で準備が完了する。
`rake release` を実行する。
“`prettyprinted
% 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` できるか確認する。
“`prettyprinted
% 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で公開する手順 – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20141017/gem_push_ruby_gem_org)
> * [RubyGemsにGemを公開する方法](http://changesworlds.com/2015/01/how-to-publish-gem-in-rubygems/)
> * [作成したgemを扱う際の注意点 – Qiita](http://qiita.com/ogawatti/items/5cd81a51a9f92152175f)
RubyGems.org にあることも確認できた。
> * [dw_test | RubyGems.org | your community gem host](https://rubygems.org/gems/dw_test)
### rake release が途中で停止する場合の対処方法
追記:2021/02/14
https://rubygems.org/ で2段階認証を設定している場合、リリースの途中で停止します。
下記のようなタイミングでワンタイムパスワードを入力すると完了しました。
“`prettyprinted
% rake release
bcupgrade 0.9.4 built to pkg/bcupgrade-0.9.4.gem.
Tag v0.9.4 has already been created.
“`
> – [二段階認証をしていたら bundle exec rake release が動かなかった | tail -f pinzo.log](https://pinzolo.github.io/2019/07/26/rake-release-does-not-work-by-mfa.html)
## 補遺
> * [書き捨てのRubyスクリプトをgemにするときの育て方の一例 – ククログ(2016-09-08)](http://www.clear-code.com/blog/2016/9/8.html)
> * [Make your own gem – RubyGems Guides](http://guides.rubygems.org/make-your-own-gem/)
> * [必要最小のgemの作り方とインストール – ザリガニが見ていた…。](http://d.hatena.ne.jp/zariganitosh/20141016/minimum_making_of_gem)
> * [Travis CI、Coveralls、Code Climate、RubyGems、Gemnasium、deppbotと連携させよう! – 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/travis-ci-code-climate-rubygem-org-coverall-gemnusium-inch-ci/)
e-book があるよう。
> * [Build a Ruby Gem | Brandon Hilkert](http://brandonhilkert.com/books/build-a-ruby-gem/)
「gemパッケージの作り方」として1章割かれているようなので読みたい。
[/markdown]