[Ruby] RubyGem の作り方

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

[markdown]
> * [RubyGemはめっちゃ簡単に作れる! – 酒と泪とRubyとRailsと](http://morizyun.github.io/blog/ruby-gem-easy-publish-library-rails/)

3分 gem クッキング from Kenji Mori

## ひな型の作成

事前に 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章割かれているようなので読みたい。

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

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

[/markdown]