Ruby の Gem と Bundler を使ってみる
この記事に関連するお話です。
Ruby の開発版を使っていたので気付かなかったのですけれど、リリース版には gems/ 以下に bundled_gems として次のものが同梱されているのでした。
did_you_mean-1.2.0/ did_you_mean-1.2.0.gem minitest-5.10.3/ minitest-5.10.3.gem net-telnet-0.1.1/ net-telnet-0.1.1.gem power_assert-1.1.1/ power_assert-1.1.1.gem rake-12.3.0/ rake-12.3.0.gem test-unit-3.2.7/ test-unit-3.2.7.gem xmlrpc-0.3.0/ xmlrpc-0.3.0.gem
雛形の作成
sudo gem install bundle
で bundler をインストールしてから bundle gem rbmto
でプロジェクトの雛形を作成します。このときに 3 つの質問があるので、それぞれ minitest, y, n と答えました。
Creating gem 'rbmto'... 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): minitest 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 http://choosealicense.com/licenses/mit. y/(n): y MIT License enabled in config 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. Be sure that your email address is specified as a contact in the generated code of conduct so that people know who to contact in case of a violation. For suggestions about how to enforce codes of conduct, see http://bit.ly/coc-enforcement. y/(n): n create rbmto/Gemfile create rbmto/lib/rbmto.rb create rbmto/lib/rbmto/version.rb create rbmto/rbmto.gemspec create rbmto/Rakefile create rbmto/README.md create rbmto/bin/console create rbmto/bin/setup create rbmto/.gitignore create rbmto/.travis.yml create rbmto/test/test_helper.rb create rbmto/test/rbmto_test.rb create rbmto/LICENSE.txt Initializing git repo in /Users/home/rbmto
プロジェクトの設定
まずは rbmto.gemspec の編集から。ほとんどの項目が埋まっていて、プロジェクトの名前と説明を書くだけな感じでした。
spec.summary = %q{rbmto} spec.description = %q{Ruby de Mojiretsu wo Tanjun ni Okikae masu.}
この状態でとりあえず rake test
をしてみるとエラーに。起動された rake が /usr/bin/rake だったのが原因。gem install rake
で新しいものをインストール。
プロジェクトの実装
lib/rbmto.rb に実装していきます。class ではなく module で書くみたい。今まで書いたものをコピペして次の工程へ。実は module ではダメで class に戻したのは秘密。
テストの記述
/test/rbmto_test.rb に書いていきます。python でのテストを修正する形で記述しました。Ruby では class を使ってオブジェクト指向的に書いてあるので、いささか悩みました。それが先に書いた module ではダメで class にしたというもの。
module はインスタンス生成能力が無いので、インスタンス変数を使っているこのプログラムには合わないということなのでしょう。また、インスタンス変数にアクセスできなかったので、attr_reader を設定し、外部ファイルへのパスを保持するためにクラス変数 @@ も使いました。
rake test
でテストができます。何度も繰り返して pass するようにしました。テストを書いている時間の方が長かったような?
パッケージの作成
実行ファイルは exe に入れるみたい。参考にしているライブラリが書いていたので、自分も下記を追記することにしました。パスの一番先頭にカレントディレクトリの lib 追加してくれるみたい。
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
パスの関係は難しいですね。
gem build rbmto.gemspec
でカレントディレクトリに rbmto-0.1.0.gem が生成され、sudo gem install rbmto-0.1.0.gem
でグローバル環境にインストールされました。試しに irb で require 'rbmto'
とすると、ture が返ってきました!
これでライブラリまでは作成することができたけれども、実行コマンドを bin/ にインストールすることができない。どうすれば良いのだろう?
gemspec をいじるらしい。exe ディレクトリはすでに bindir = 'exe'
のように設定されているので、spec.executables の部分だけを spec.executables = "rbmto"
のように変更。これで /usr/local/bin/rbmto がインストールされるようになったけれども、何も言わない……。
エラーにすらならないことから気がついて、次の部分をコメントアウトすることで動くようになりました。
# if __FILE__ == $0 main() # end
GitHub からのインストール
あとは Git リポジトリから直接インストールすることができれば良いのだけれど、うまい手立てが見つからない。今のところは手動で次のようにしてやるしかなさそう?
git clone https://github.com/user_name/rbmto.git rbmto
cd rbmto
gem build rbmto.gemspec
sudo gem install rbmto
specific_install
を使うと良いことがわかりました。
gem specific_install -l 'git://github.com/user_name/rbmto.git'
ローカルにインストールしたい場合は --user-install オプションが効かないので、
GEM_HOME=~/.gem/ruby/2.6.0 gem specific_install -l https://github.com/user_name/rbmto.git
のように一時的に環境変数を指定してやると良いようです。