LoginSignup
77

More than 5 years have passed since last update.

Create Ruby Gem by Bundler

Last updated at Posted at 2013-01-22

Bundlerはパッケージのインストーラでよく利用されていますが
パッケージの作成や Rubygems に公開することもできます。

Environment

  • Ruby: 2.2.3
  • Bundler: 1.10.6
  • RSpec: 3.4.1

First release

この手順は bouquet という名前の Gem を作成します。
(Gem の名前は任意に変更してください。)

Create Gem

bundle gem のコマンドでパッケージに必要なファイルが作成されます。
code of conduct, license, tests gem の質問に答えると、それに応じたファイルが作成されます。
(質問の回答は ~/.bundle/config に保存されます。次回から質問されません。)

$ bundle gem bouquet
Creating gem 'bouquet'...
Do you want to include a code of conduct in gems you generate?
Codes of conduct can increase contributions to your project by contributors who prefer collaborative, safe spaces. You can read more about the code of conduct at contributor-covenant.org. Having a code of conduct means agreeing to the responsibility of enforcing it, so be sure that you are prepared to do that. For suggestions about how to enforce codes of conduct, see bit.ly/coc-enforcement. y/(n): y
Code of conduct enabled in config
Do you want to license your code permissively under the MIT license?
This means that any other developer or company will be legally allowed to use your code for free as long as they admit you created it. You can read more about the MIT license at choosealicense.com/licenses/mit. y/(n): y
MIT License enabled in config
Do you want to generate tests with your gem?
Type 'rspec' or 'minitest' to generate those test files now and in the future. rspec/minitest/(none): rspec
      create  bouquet/Gemfile
      create  bouquet/.gitignore
      create  bouquet/lib/bouquet.rb
      create  bouquet/lib/bouquet/version.rb
      create  bouquet/bouquet.gemspec
      create  bouquet/Rakefile
      create  bouquet/README.md
      create  bouquet/bin/console
      create  bouquet/bin/setup
      create  bouquet/CODE_OF_CONDUCT.md
      create  bouquet/LICENSE.txt
      create  bouquet/.travis.yml
      create  bouquet/.rspec
      create  bouquet/spec/spec_helper.rb
      create  bouquet/spec/bouquet_spec.rb
Initializing git repo in /Users/user/bouquet

Initial commit

Bundler ではパッケージの作成に Git のコマンドを利用します。
git status コマンドを実行すると Initial commit を勧められます。

$ cd bouquet/
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

  new file:   .gitignore
  new file:   .rspec
  new file:   .travis.yml
  new file:   CODE_OF_CONDUCT.md
  new file:   Gemfile
  new file:   LICENSE.txt
  new file:   README.md
  new file:   Rakefile
  new file:   bin/console
  new file:   bin/setup
  new file:   bouquet.gemspec
  new file:   lib/bouquet.rb
  new file:   lib/bouquet/version.rb
  new file:   spec/bouquet_spec.rb
  new file:   spec/spec_helper.rb

Initial commitgit commit コマンドで実行します。

$ git commit -m "Initial commit"

Rake Task

rake -T コマンドで利用できるタスクの一覧が表示されます。
(最初のリリースのバージョンは 0.1.0 が設定されています。)

$ rake -T
rake build          # Build bouquet-0.1.0.gem into the pkg directory
rake install        # Build and install bouquet-0.1.0.gem into system gems
rake install:local  # Build and install bouquet-0.1.0.gem into system gems without network access
rake release        # Create tag v0.1.0 and build and push bouquet-0.1.0.gem to Rubygems
rake spec           # Run RSpec code examples

Run RSpec

rake spec コマンドでテストを実行できます。
bundle gem のコマンドで作成されたサンプルはテストが失敗するようになっています。

$ rake spec

Bouquet
  has a version number
  does something useful (FAILED - 1)

Failures:

  1) Bouquet does something useful
     Failure/Error: expect(false).to eq(true)

       expected: true
            got: false

       (compared using ==)
     # ./spec/bouquet_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 0.00151 seconds (files took 0.20151 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/bouquet_spec.rb:8 # Bouquet does something useful

期待する値が true なのに false が得られています。 expect(false)expect(true) に編集しましょう。

spec/bouquet_spec.rb:

require 'spec_helper'

describe Bouquet do
  it 'has a version number' do
    expect(Bouquet::VERSION).not_to be nil
  end

  it 'does something useful' do
    expect(true).to eq(true)
  end
end

もう一度 rake spec コマンドを実行するとテストが成功していますね。

$ rake spec

Bouquet
  has a version number
  does something useful

Finished in 0.00152 seconds (files took 0.20152 seconds to load)
2 examples, 0 failures

spec の修正をコミットします。

$ git commit -am "Fix bouquet spec"

Gem Spec

rake install:local コマンドを実行するとエラーになります。
これは gemspecTODO の記載がある場合に発生します。

$ rake install:local
rake aborted!
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
ERROR:  While executing gem ... (Gem::InvalidSpecificationException)
    "FIXME" or "TODO" is not a description

Tasks: TOP => install:local => build
(See full trace by running task with --trace)

なので bouquet.gemspec ファイルの summary, description, homepage, metadata を編集します。
(gemspecRubygems に公開される Gem の仕様書です。)

bouquet.gemspec:

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

Gem::Specification.new do |spec|
  spec.name          = "bouquet"
  spec.version       = Bouquet::VERSION
  spec.authors       = ["ogom"]
  spec.email         = ["ogom@outlook.com"]

  spec.summary       = %q{bouquet summary.}
  spec.description   = %q{bouquet description.}
  spec.homepage      = ""
  spec.license       = "MIT"

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

もう一度 rake install:local コマンドを実行するとインストールが成功しています。

$ rake install:local
bouquet 0.1.0 built to pkg/bouquet-0.1.0.gem.
bouquet (0.1.0) installed.

gemspec の修正をコミットします。

$ git commit -am "Fix bouquet gemspec"

Release

rake release コマンドを実行するとエラーになります。
これは remote repository を利用していない場合に発生します。

$ rake release
bouquet 0.1.0 built to pkg/bouquet-0.1.0.gem.
Tagged v0.1.0.
Untagging v0.1.0 due to error.
rake aborted!
Couldn't git push. `git push  2>&1' failed with the following output:

fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

Tasks: TOP => release => release:source_control_push
(See full trace by running task with --trace)

なので GitHub にリポジトリを作成してコードをアップロードします。
(リポジトリは localhost など、どこでもよいです。)

$ git remote add origin git@github.com:dddrb/bouquet.git
$ git push -u origin master

もう一度、rake release コマンドを実行すると Rubygems に公開されます。

$ rake release
bouquet 0.1.0 built to pkg/bouquet-0.1.0.gem.
Tagged v0.1.0.
Pushed git commits and tags.
Pushed bouquet 0.1.0 to rubygems.org.

Rubygems に公開されているか gem install コマンドで確認しましょう。

$ gem install bouquet
Successfully installed bouquet-0.1.0
1 gem installed

Second release

こちらはバージョンアップの手順です。

Version UP

バージョンは version.rb で管理します。今回は 0.1.00.1.1 に編集しましょう。
(バージョンは Major.Minor.Patch の構成が一般的です。)

lib/bouquet/version.rb:

module Bouquet
  VERSION = "0.1.1"
end

rake -T コマンドでも 0.1.1 に変更されたことが解ります。

$ rake -T
rake build          # Build bouquet-0.1.1.gem into the pkg directory
rake install        # Build and install bouquet-0.1.1.gem into system gems
rake install:local  # Build and install bouquet-0.1.1.gem into system gems without network access
rake release        # Create tag v0.1.1 and build and push bouquet-0.1.1.gem to Rubygems
rake spec           # Run RSpec code examples

0.1.1 に変更はbouquet.gemspechomepageGitHub のリポジトリの URL を記述しましょう。
そして、コミットとアップロードをします。

$ git commit -am "Fix homepage at bouquet.gemspec"
$ git push origin master

Release

rake release コマンドを実行すると Rubygems に新しいバージョンが公開されます。

$ rake release
bouquet 0.1.1 built to pkg/bouquet-0.1.1.gem.
Tagged v0.1.1.
Pushed git commits and tags.
Pushed bouquet 0.1.1 to rubygems.org.

gem install コマンドでも新しいバージョンがダウンロードされます。

$ gem install bouquet
Fetching: bouquet-0.1.1.gem (100%)
Successfully installed bouquet-0.1.1
1 gem installed

Yank

新しいバージョンを Rubygems に公開すると、古いバージョンを非公開にします。
非公開にするには gemcutterGEM を利用します。

$ gem install gemcutter
$ gem yank bouquet --version 0.1.0
Yanking gem from https://rubygems.org...
Successfully deleted gem: bouquet (0.1.0)

これで古いバージョンをダウンロードできなくなりました。

$ gem install bouquet --version 0.1.0
ERROR:  Could not find a valid gem 'bouquet' (= 0.1.0) in any repository
ERROR:  Possible alternatives: bouquet

Tips

tests gem の質問で rspecminitest で応えていると travis の利用に必要な設定が自動で作成されています。

Enjoy GEM

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
77