Pack gem and publish to RubyGems
這篇記錄寫完 Ruby 程式後如何包成 gem 並丟到 RubyGems 上分享。
基本流程:
- source code 放到
lib/lib/底下通常有<gem_name>.rb及<gem_name>/。<gem_name>.rb放此 gem 最主要的 class 及require,其餘 source code 放在<gem_name>/。 - test 放到
test/ - 在根目錄新增
<gem_name>.gemspec gem build xxx.gemspec生出xxx-x.x.x.gemgem push xxx-x.x.x.gempublish 到 RubyGems
以下以玩具 booksr 為例。
檔案結構:
1 | │ booksr.gemspec |
booksr.rb 的內容:
1 | require 'json' |
booksr.gemspec 內容:
1 | Gem::Specification.new do |s| |
runtime dependency 跟 development dependency 的差別是預設上不會安裝 development dependency 的 gem。
如果有 Gemfile,要改寫成吃 .gemspec:
1 | source 'https://rubygems.org' |
它會將 runtime dependency 當作基本的 dependency,development dependency 則會開個 development group。
生 gem:
1 | $ gem build booksr.gemspec` |
要 publish 到 RubyGems.org 前要先註冊帳號,publish 時需要輸入 Email 跟密碼驗證。
1 | $ gem push booksr-0.1.0.gem |
Troubleshooting
在 win7 底下 publish 遇到以下錯誤:
1 | ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError) |
Solution:抓 cacert.pem 放到 C:\Users\<username> 底下,並且增加檔案 .gemrc,內容為:
1 | :ssl_ca_cert: c:\users\xxx\cacert.pem |
碎念時間
我是先寫好 code 才開始調這些檔案結構(真相是寫 code 的時候根本不知道這些結構),跟 require 啊、bundler 啊、gem 啊不熟到爆炸,中間 unit test 還亂入,混亂了好一陣子。弄完稍微多懂一點,希望這篇沒有漏掉什麼,漏掉就再補囉!