gem を作って公開してみた 〜開発編〜

# 0. はじめに

こちらは前回の [gem を作って公開してみた 〜準備編〜](https://qiita.com/Satoooon/items/a04cc778b0e5ac11ae24) の続きの記事になります。
今回はgem の開発について解説していきたいと思います。

今回も以下のgemをベースにお話しします。

https://rubygems.org/gems/ruby_calendar

# 1. ディレクトリ構成

前回まででビルド実行までが完了した状態です。こちらが完了すると以下のようなディレクトリ構成になっていると思います。（ビルド時の受け答えによって多少の違いはあります)

```shell
ruby_calendar
├── CHANGELOG.md # 開発gemのチェンジログを記載するもの
├── CODE_OF_CONDUCT.md # ビルド時 Code of Conductの有無でyesで回答すると作成
├── Gemfile # 開発するうえで追加で必要なgemがあればこちらに追記する
├── Gemfile.lock
├── LICENSE.txt # ビルド時 MIT License の有無でyesで回答すると作成
├── README.md
├── Rakefile
├── bin
├── lib
├── pkg 
├── ruby_calendar.gemspec #開発gem関連の情報が集約されてるもの
└── spec
```

# 2. gemspec の編集
gemspecとは公開するgemの情報を集約しているものになります。
必須項目については入力しないと公開ができないためここで修正します。
以下のうち★マークがついている行は必須項目となります

```
Gem::Specification.new do |s|
  s.name        = 'example'# ★
  s.version     = '0.1.0' # ★
  s.licenses    = ['MIT']
  s.summary     = "This is an example!" # ★
  s.description = "Much longer explanation of the example!"
  s.authors     = ["Ruby Coder"] # ★
  s.email       = 'rubycoder@example.com'
  s.files       = ["lib/example.rb"] # ★
  s.homepage    = 'https://rubygems.org/gems/example'
  s.metadata    = { "source_code_uri" => "https://github.com/example/example" }
end
```

必須項目の内容と入力する概要について説明します

- `name` gem の名前。基本的に今回のフローでコマンド実行を行えば自動的にgem名が記載されているはずです。万が一gemのリネームなどが必要になった際こちらを修正してください
- `version` バージョン。後述しますが、可能であれば定数管理した方が良いと思います
- `summary` gemの概要。大体1行くらいでざっくりとした説明でOKです（もっと詳しい説明はdescriptionの方に書くことを推奨します）
- `authors` 開発者の名前。1人であれば文字列でもOKで複数人であれば配列の中に入力します
- `files` gemのファイル。gemの実行するファイルだけ指定します。テストなどファイルはエラーの原因となるので対象外です

またその他の項目等、gemspecの詳しいガイドについては以下に書かれているので参考にしてみてください。

https://guides.rubygems.org/specification-reference/

# 3. gem 実装

ここから実際にgemを実装していきます。


## 3-1. gem 実体の追加

雛形を作ると作ると `lib/` 配下に以下のようなものができていると思います。

```
# frozen_string_literal: true

require_relative "ruby_calendar/version"

module RubyCalendar
  class Error < StandardError; end
  # Your code goes here...
end
```

これらを修正していくことでgemの処理を追加していくことができます（以下は実装例です！）

```
# frozen_string_literal: true

require_relative "ruby_calendar/version"

module RubyCalendar
  class Error < StandardError; end

　def self.hello_world
    puts "Hello World"
  end

end
```

## 3-2. test の追加

minitestであれば `test/` 配下、 rspecであれば `spec/` 配下にテストファイルを追加することでgemの処理が正常に動作することができるテストを追加することができます。
以下はspec例です。

```
require 'spec_helper'

describe RubyCalendar do

  describe '#hello_world' do
    it 'returns "Hello World"' do
      expect(RubyCalendar.hello_world).to eq('Hello World')
    end
  end
end
```

以下のコマンドでテストコードを実行できます

```
$ bundle exec rspec

RubyCalendar 
  returns "Hello World"

1 example, 0 failures
```

# 4. 動作確認

実際に自分で作った者が動くか確認してみましょう。

## 4-1. bin/console で実行する

gemのカレントディレクトリにある `bin/` 配下にあるconsoleコマンドを実行するとirbを実行できます。こちらは開発途中のgemが反映できているのでそのまま動作確認することができます。

```
$ ./bin/console
irb(main):001:0> RubyCalendar.hello_world
=> "Hello World"
```

## 4-2. gemをビルドして動作確認

rake タスクにてgemをビルドするし、インストールを行って動作確認することもできます。

```
$ rake build
ruby_calendar 0.0.1 built to pkg/ruby_calendar-0.0.1.gem.
$ gem install pkg/ruby_calendar-0.0.1.gem
$ irb
irb(main):001:0> require "ruby_calendar"
=> false
irb(main):002:0> RubyCalendar.hello_world
=> "Hello World"
```

## 5. 最後に

今回はgemの開発まで行いました。次回はこれらを開発したgemを公開の仕方について説明します。
それでは次回　公開編で！！