BundlerでRubygemsとGitHubに公開してみる

# BundlerでRubygemsとGitHubに公開してみる

この文章は [こちら](https://monolog.linkode.co.jp/articles/satoyama/Rubygems%E3%81%A8Github%E3%81%B8%E5%85%AC%E9%96%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)からの転載です。

## はじめに

いつもお世話になっているRubygemsやGithubなどのエコシステムを体験してみたいという思いがありました。

RubygemsであればRubyのBundlerが楽だろうということで、
BundlerでRubygemsとGitHubでソフトウェアを公開するまでの流れを書いてみます。


## 何を作るか

何を作るか。
これが実は一番難しかったりするわけですが、今回は私自身が開発を行っていてたまに欲しくなるものにします。
普段、私はLinuxのサーバサイドのソフトウェアなどをよく開発しますが、その開発中にサーバ上で、あるツールやコマンドをバックグラウンドで起動させたり、任意のタイミングで停止させたり、デーモン化されていないものをデーモン化したいと思うことがあります。

例えば、サーバ上で負荷情報をモニタリングするときに、 `vmstat` で情報を書き出させ、別な作業を行い、任意のタイミングで停止させるようなケースです。

このとき、以下の様に起動停止が簡単にできれば、いいなぁと思うので、それをサポートするツールを作成してみたいと思います。


起動・停止のイメージ

```shell
$ nand start --out vmstat.log vmstat -n 3 
(ログアウトしたり、何か別のことをする)
$ nand stop vmstat
```
ここで、```nand``` が開発するツールとします。以下で、```nand```を開発、公開する過程を説明してみます。

もちろん、`ps`コマンドで確認して`kill`すればよいのですが、手順が多かったり、該当のプロセスを探したりするのが手間だったりするので、そのあたりも上手くサポートしてくれるツールを目指します。

## Ruby/Bundlerを使った開発

RubyとBundlerを使って`nand`を作成し、公開するまでの流れを説明します。

### rbenvでターゲットのRubyバージョンを用意

Rubyのrbenvは複数のRubyのバージョンを共存、切替をディレクトリやシェルレベルで行える
非常に便利なツールです。
rbenvおよびRubyのダウンロードからビルド、インストールまで行うruby-buildについては、説明を割愛します。
今回はRuby 2.0以上をターゲットにすることにします。

```shell
$ rbenv install 2.0.0-p598
(以下略)
```

インストール完了後、ログインしている端末上でインストールしたRubyのバージョンを利用するようにしておきます。

```shell
$ rbenv shell 2.0.0-p598
$ rbenv rehash
$ ruby -v
ruby 2.0.0p598 (2014-11-13 revision 48408) [x86_64-darwin13.4.0]
```


### Bundlerの準備

BundlerはインストールしたRubyのgemsディレクトリにインストールすることなく、
開発環境のローカルにgemパッケージをインストールして利用してくれる素敵パッケージです。
Bundlerはrubygemsで提供されていますので、これはインストールしたRubyのgemsディレクトリに
インストールします。

```shell
$ gem install bundler
(中略)
$ bundle version
Bundler version 1.9.1
```

### 雛形の作成

インストールしたBundlerで雛形を作成します。

```shell
$ bundle gem nand -b -t --coc --mit
Creating gem 'nand'...
      create  nand/Gemfile
      create  nand/.gitignore
      create  nand/lib/nand.rb
      create  nand/lib/nand/version.rb
      create  nand/nand.gemspec
      create  nand/Rakefile
      create  nand/README.md
      create  nand/bin/console
      create  nand/bin/setup
      create  nand/CODE_OF_CONDUCT.md
      create  nand/LICENSE.txt
      create  nand/.travis.yml
      create  nand/.rspec
      create  nand/spec/spec_helper.rb
      create  nand/spec/nand_spec.rb
      create  nand/exe/nand
Initializing git repo in /YOUR/PATH/nand
```

`-b` は `nand/exec/nand` を作成 `-t`はテスト用のディレクトリ(rspec)作成です。
`--mit`はMITライセンス、`--coc`はContributor Code of Conductに関するテキストを出力するオプションです。
"Contribute Code of Conduct"については[こちら](http://qiita.com/nstoym/items/ca711287117074a810aa)などを参考にしてください。

bundlerは1.9から雛形のディレクトリ構造が変わっています。
1.9以前は`-b`で生成される実行ファイルは、`bin/nand`に出力されていましたが、
1.9以降は`exec/nand`以下に生成されますので、
開発中に、`bundle install --binstubs`とすると`bin/nand`にbinstubが生成されます。
`bin`にパスを通しておくことで、毎回`bundle exec`を付けることなく、`nand start...`で試行できます。

同様に、依存性を解決してREPL(irbやpryなど)を利用したい場合、`bin/console`が出力されていますので、`console`で実行できます。
`bin/setup`は`bundle install`を実行するもので、その他のセットアップ処理を追加する場合は、こちらを利用しましょう。
 

ここでは、混乱がないようにbinstubを利用せずに、必要なものは全て`bundle exec`を付けています。

### gemspecの編集

`nand/nand.gempsec`が生成されています。このファイルをまず編集します。`TODO`などを適宜編集しましょう。
`spec.homepage` はGitHubのリポジトリにしておくと、RubygemsのページからGitHubのリポジトリに飛べて便利になります。

#### 依存ライブラリ

`nand`はCLIツールです。RubyのCLIツールとしてとても便利な[`thor`](https://github.com/erikhuda/thor)を利用しますので、`nand.gemspec`に依存性を追加しておきます。

```ruby:nand.gemspec
(前略)
  spec.add_development_dependency "bundler", "~> 1.9"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "rspec"
  
  spec.add_dependency "thor"
(後略)
```

依存するライブラリでシステムのgemにないものを開発環境にインストールします。

```shell
$ bundle install --path vendor/bundle
(後略)
```

開発していて、依存ライブラリが増えたら、都度`nand.gemspec`に追記して、`bundle install`を実行します。

このあたりで、GitHubに最初のコミットをしてみましょう。

### GitHub にコミット


```shell
$ git commit -a -m "1st commit"
$ git remote add origin https://github.com/linkodehub/nand.git
$ git push origin master
(後略)
```

コミット用のブランチは"master"として、リモートのGitHubを"origin"としておいた方が `rake release`でトラブルが少なくてよいです。

### 開発


バックアップ用途やtypoなどログが汚くなるのを晒したくないので、
開発時はなるべくmasterブランチ以外で行った方が無難だと思います。
ブランチの命名など運用については、[GitHub Flow](https://gist.github.com/Gab-km/3705015)などを参考にするとよいでしょう。

```shell
$ git checkout -b dev
```

あとは、実際の開発を進めてください。
なお、ここまで説明に利用してきたNandのGitHubリポジトリは[こちら](https://github.com/linkodehub/nand)になります。


#### ドキュメントの整備

`Ruby`で作成していますので、`rdoc`などを整備していくと利用者は助かると思いますが、
まずは`README.md`を書きましょう。GitHubのリポジトリのページでも表示されるので、
説明や簡単な使い方などは載せておくべきかと思います。

日本語で書く場合は`README.ja.md`や`README-ja.md`などとするのを見かけます。


### Gemの公開

開発がある程度進んで、動作するようになったら、`gem`をRubygems.orgに登録しましょう。
登録前にアカウントを作成する必要があります。

アカウント作成自体は以下のサイトなどを参考にしてください。

* [絵付きでわかりやすいサイト](http://dev.classmethod.jp/server-side/language/how-to-publish-rubygems/)
* [本家のガイド](http://guides.rubygems.org/)

`rake release`は "master"ブランチであることを期待するようですので、開発ブランチから"master"ブランチへマージを事前にしておきます。

```shell
$ bundle exec rake release
(後略)
```

前述していますが、事前に`bundle install --binstubs`をして、`./bin`をPATHに追加しておけば、`bundle exec`は省略できます。

Rubygemsに登録すると[ダウンロードされた数](https://rubygems.org/gems/nand)が分かるので、少しずつでも増えていくダウンロード数を見るのは感慨深いモノがあります。

### バッジ

公開されている`README.md`には試験の結果やコードの品質チェックなど、様々なバッジが付いているのを見たことがあると思います。

#### gem version バッジ

[![Gem Version](https://badge.fury.io/rb/nand.svg)](http://badge.fury.io/rb/nand)

Rubygems.orgに登録していれば、[gemのページ](https://rubygems.org/gems/nand)にある"LINKS"の"Badge"から、gemのバージョンを表示するバッジのURLを取得できます。

Markdownの内容をコピーしてREADME.mdに貼り付けてコミットしましょう。

```
[![Gem Version](https://badge.fury.io/rb/nand.svg)](http://badge.fury.io/rb/nand)
```

#### Gitterバッジ

[Gitter](https://gitter.im/)とはGitHubにあるOrginizationやリポジトリに対して、チャットルームを作成できるWebサービスです。

GitHubのアカウントで登録できるので簡単です。
サインインしてホームから"Create a room"でリポジトリのチャットルームを作ってみましょう。

![create_room](https://qiita-image-store.s3.amazonaws.com/0/6547/ab8b1bd2-f887-f241-6830-c55babecc129.png)


![create room to add badge](https://qiita-image-store.s3.amazonaws.com/0/6547/b872b315-0679-71b1-6294-2e169166f61b.png)

ここで、 "Add badge to README on GitHub(via pull request)"にチェックを入れておくと、
gitter-badgerから`README.md`に対してバッジのURLが貼り付けられたプルリクエストが来るので、
取り込みます。

初めてのプルリクエストのマージには丁度いい練習になると思います。

その他、様々なサービスと連携することで、より *意識が高い* リポジトリに見えるでしょう。
他の方の[ブログ](http://morizyun.github.io/blog/travis-ci-code-climate-rubygem-org-coverall-gemnusium-inch-ci/)が参考になります。

### 最後に

以上で、説明は終了です。
この文章が誰かの参考になれば、幸いです。

また、この説明は後から思い出しながら書いたものなので、間違いがあるかもしれません。
間違いなどありましたら、ご指摘ください。


あとは、継続できるかどうかですね。(自戒)