如何開發一個本身的 RubyGem?

##什麼是 RubyGemhtml

RubyGem 是 Ruby 語言的標準源碼打包格式。linux

你們一直都在用gem這個命令,可是不多有人知道這個東西是怎麼來的,這裏我從網上扒下一些資料彙總一下,分享給你們。最後面會有這些連接,想進一步瞭解的,能夠點進去看看。Ruby 語言深受其餘幾種腳本語言的影響,其中就有 Perl,而 Perl 有個 CPAN(Comprehensive Perl Archive Network),這個東西也就像是如今的 RubyGems.org ,可是當時 Ruby 是沒有這樣一個東西的。像 CPAN 和 RubyGem ,它們僅僅是定義好的一種源碼的打包和安裝方式,另外還有一些組織,會提供這種免費的公共的源碼包的存儲,這也就如今你們天天都要使用的安裝方式:git

gem install rails

在 RubyGem 的發展歷史當中,有幾位重要的人物,這裏也做爲八卦知識給你們曬一曬,就當作你們茶餘飯後的談點吧。Ruby 社區的人應該都知道 Jim Weirich 這我的,他已經在2014年2月份去世了,是一個可愛的白鬍子大叔,他和另外的四位 Rich Kilmer, Chad Fowler, David Black, Paul Brannan在2003年制定了 RubyGem 的基本規範和實現,可是其實 RubyGem 最先是 Ryan Leavengood 在2001年開發的,惋惜沒有流行起來,最後到了2003年,前面的5我的通過 Ryan Leavengood 的贊成,使用了 RubyGem 這個名稱,開發了新版的 RubyGem,其中並無使用 Ryan Leavengood 的代碼。這裏附上 rubygems 的執行文件連接,看看註釋,裏面有上面幾我的的名字 rubygems/blob/master/bin/gemgithub

rubygems 有默認的源,也能夠更改,國內的基本就是 https://rubygems.taobao.org 了,有些公司有本身的需求,也會搭建本身的私源。當前的官方源爲https://rubygems.org,這個源也是幾經展轉,早期的 Ruby 用戶都知道 http://gems.rubyforge.orghttp://gemcutter.org,甚至github都曾經做爲源使用過,也就是 http://gems.github.com,這三個如今都已經棄用了。ruby

看看,一個簡單的gem install 歷史還很多啊。session

##RubyGem的基本使用方法less

gem install rails  //安裝rails
gem install rails -v 4.2.0   //安裝指定版本的rails
gem search rails  //查找全部名稱中含有rails的gem
gem search ^rails  //查找全部名稱中以rails開頭的gem
gem search ^rails -d  //查找全部名稱中以rails開頭的gem,並顯示描述
gem build package.gemspec  //構建一個gem,就是把你本身寫的gem源碼,打包成一個.gem文件
gem push pack-1.0.gem  //發佈到源上,默認是rubygems.org

這裏只是簡單列出了最經常使用的使用方法,你們看看就好,命令頗有限,也很簡單,執行gem --help,基本上全部的東西你都能10分鐘內學會。ide

##如何製做一個本身的RubyGem工具

前幾年仍是有這樣那樣的工具,如今用bundler就夠了。測試

$ bundler gem mygem
      create  mygem/Gemfile
      create  mygem/Rakefile
      create  mygem/LICENSE.txt
      create  mygem/README.md
      create  mygem/.gitignore
      create  mygem/mygem.gemspec
      create  mygem/lib/mygem.rb
      create  mygem/lib/mygem/version.rb
Initializing git repo in /home/lizhe/Workspace/mygem

一個bundler命令就搞定了。來看看mygem這個文件夾下的東西:

total 24
-rw-rw-r-- 1 lizhe lizhe   90  7月  2 15:52 Gemfile
drwxrwxr-x 3 lizhe lizhe 4096  7月  2 15:52 lib
-rw-rw-r-- 1 lizhe lizhe 1062  7月  2 15:52 LICENSE.txt
-rw-rw-r-- 1 lizhe lizhe  850  7月  2 15:52 mygem.gemspec
-rw-rw-r-- 1 lizhe lizhe   29  7月  2 15:52 Rakefile
-rw-rw-r-- 1 lizhe lizhe  556  7月  2 15:52 README.md

如今來看看gemspec這個文件,它描述了這個Gem的各類信息

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

Gem::Specification.new do |spec|
  spec.name          = "mygem"
  spec.version       = Mygem::VERSION
  spec.authors       = ["lizhe"]
  spec.email         = ["lizhe@oneapm.com"]
  spec.summary       = %q{TODO: Write a short summary. Required.}
  spec.description   = %q{TODO: Write a longer description. Optional.}
  spec.homepage      = ""
  spec.license       = "MIT"

  spec.files         = `git ls-files -z`.split("\x0")
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.7"
  spec.add_development_dependency "rake", "~> 10.0"
end

我發現有人看到這個文件的內容時,卻是關心那個'git ls-files -z'.split("\x0")是什麼意思?以及那個\x0是什麼?附上一個連接,解釋一下,參考連接。這個文件最上面先把 lib 文件夾添加到 load path 中,Gem::Specification 的第一部分主要是描述這個 gem 的信息,包括名稱,版本等等,第二部分是這個 gem 都包括哪些文件,執行文件,測試文件以及哪些路徑下的文件能夠添加到 load path 中。第三部分是開發 mygem 須要依賴的其餘 gem。這些信息均可以自定義,先按照默認走。讓咱們 build 第一個 gem 吧。

$ rake build

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
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:149:in `sh'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:57:in `build_gem'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/gems/bundler-1.7.12/lib/bundler/gem_helper.rb:39:in `block in install'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/bin/ruby_executable_hooks:15:in `eval'
/home/lizhe/.rvm/gems/ruby-2.1.5@global/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => build
(See full trace by running task with --trace)

這個警告是提醒咱們須要替換gemspec中的FIXMETODO,這個警告若是不解決是沒法 build 一個 gem 的,直接刪除掉 summary 和 description 中的TODO

spec.summary       = %q{Write a short summary. Required.}
  spec.description   = %q{Write a longer description. Optional.}

再來執行:

$ rake build

mygem 0.0.1 built to pkg/mygem-0.0.1.gem.

好了,第一個 gem 誕生了。它就在當前目錄的 pkg 下: mygem-0.0.1.gem 。如何使用呢?不考慮 bundler 的狀況下,若是你開起了一個 irb 或者 pry 的 session 時,通常都會這樣寫:require "mygem",若是你如今這樣作,那確定不行,由於它尚未被安裝到 ruby 的 load path 中,那就把它安裝上。

$ rake install

mygem 0.0.1 built to pkg/mygem-0.0.1.gem.
mygem (0.0.1) installed.

安裝好了,那就來使用一下,打開 irb :

require "mygem"
=> true
Mygem
=> Mygem

看,已經可使用這個 module 了,不過這個 gem 啥也幹不了,那麼咱們就給它添加一個方法吧,打開 lib/mygem.rb ,添加一個方法:

require "mygem/version"

module Mygem
  def self.hello
    p "hello from my gem"
  end
end

保存,而後執行rake install,這個命令會先 build 而後 install ,再從新打開 irb :

require "mygem"
=> true
Mygem.hello
=> "hello from my gem"

可以正常運行了,那就來發布第一個 gem 吧:

rake release
// 輸入你在rubygems.org上的帳號和密碼

若是你的一個 rails 應用正好須要輸出一個hello from my gem,那麼如今你能夠在 Gemfile 中添加這個 gem 了:

gem 'mygem'

添加完執行 bundle install,你就能夠在你的 rails 應用中使用它了。

參考連接:


本文系OneAPM工程師原創文章。OneAPM是中國基礎軟件領域的新興領軍企業,能幫助企業用戶和開發者輕鬆實現:緩慢的程序代碼和SQL語句的實時抓取。想閱讀更多技術文章,請訪問OneAPM官方技術博客

相關文章
相關標籤/搜索