如何开发一个本身的 RubyGem?

「如何测试你的 RubyGem?」的前导文章html

什么是 RubyGem

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 的基本使用方法

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分钟内学会。less

如何制做一个本身的 RubyGem

前几年仍是有这样那样的工具,如今用bundler就够了。ide

$ 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 官方技术博客

相关文章
相关标签/搜索