gemパッケージの作り方

Rubyのgemパッケージは個人でも作って公開することが出来るらしい。

雛形を生成する

Bundlerと呼ばれるgemパッケージを利用して雛形を生成し、それを土台にして作るのが一般的らしい。
Bundlerはgem installコマンドでインストール可能。

$ gem install bundler
$ bundle --version

さっそく雛形を作る。以下のコマンドを実行する。

$ bundle gem [gem名]

テストはrspecかminitestどっち使うか?とか、コードをGemに含めるかとかの質問に答えれば、指定したgem名のディレクトリが直下に生成される。

生成されたディレクトリ内には以下のようなファイルが含まれる。

ファイル 説明
Gemfile Bundlerがgemの依存関係を解決するために利用するファイル
Rakefile gemパッケージのビルドやリリースのためのタスクが定義されている
LICENSE.txt gemパッケージのライセンスについて記述するファイル。生成時はMITライセンス。
.gitignore Gitのソースコード管理に含めないファイルの一覧を記述するファイル。
[gem名].gemspec gemパッケージの構成や詳細情報を記述するファイル
lib/[gem名].rb gemパッケージのメインとなるソースコード
lib/[gem名]/version.rb gemパッケージのバージョンを記述しておくソースコード

gemspecファイル

生成されたファイルの中で最も重要なファイル。gemspecファイルはgemパッケージの作者に関する情報やgemパッケージを構成するために必要な情報が含まれている。

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

Gem::Specification.new do |spec|
  spec.name          = "gem_sample_pruby"
  spec.version       = GemSamplePruby::VERSION
  spec.authors       = ["TODO: Write your name"]
  spec.email         = ["TODO: Write your email address"]

  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. 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 { |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.12"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec", "~> 3.0"
end

nameはgemの名前、この値がrubygems.orgで公開される時の名称として使われる。versionも同様にここで設定した値がrubygems.orgで公開される時のバージョン番号になる。雛形作成時には定数「GemSamplePruby::VERSION」が設定されているが、これはversion.rb内で定義されているもの。descriptionにはgemの詳細な説明を記載する。

filesはgemパッケージに含む対象となるファイルのリストを表している。ここではgit ls-filesから取得した値がベースになっているということ、つまりgitの管理対象のファイルがそのままgemパッケージに含まれるファイルということ。

依存関係の解決

依存関係には「実行時に使うgemへの依存」と「開発時に使うgemへの依存」の2種類がある。どちらもgemspecファイル内に記述する。

  # 実行時に使うGem
  spec.add_runtime_dependency "json", ">= 1.7.3"

  # 開発時に使うGem
  spec.add_development_dependency "bundler", "~> 1.12"

Gemパッケージの開発ディレクトリ内でBundlerを利用して依存対象のGemパッケージをインストールしたときには、開発時に使うGemもインストールされるが、リリース後のパッケージをインストールすれば実行時に使うGemしかインストールされない。

作成したGemのビルドとインストール

作成したGemはRakeでビルドしてインストールする。

% rake build
gem_sample_pruby 0.1.0 built to pkg/gem_sample_pruby-0.1.0.gem.

直下にpkgディレクトリが生成され、その下にgemパッケージのバイナリファイルが生成される。
生成されたgemをインストールするには以下のコマンドを実行。

$ gem install pkg/gem_sample_pruby-0.1.0.gem
Successfully installed gem_sample_pruby-0.1.0
Parsing documentation for gem_sample_pruby-0.1.0
Installing ri documentation for gem_sample_pruby-0.1.0
Done installing documentation for gem_sample_pruby after 0 seconds
1 gem installed

ビルドとインストールを一つのコマンドで実行することもできる。

$ rake install

Gemパッケージを公開する

作成したGemパッケージを公開するには、rubygems.orgを利用する。アカウントが必要になるので事前にユーザー登録しておく。
アカウントを作成するとAPI KEYが発行される。このAPIキーを「~/.gem/credentials」というファイルに記述する必要があるが、以下のコマンドを使ってAPIキーの取得と同ファイルへの記載をまとめて行うことが出来る。

$ curl -u ryopeko https://rubygems.org/api/v1/api_key.yaml > ~/.gem.credentials
Enter host password for user 'ryopeko':
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    27    0    27    0     0     23      0 --:--:--  0:00:01 --:--:--    23

あとは「rake release」コマンドを実行するだけで簡単にgemパッケージを公開することができる。