什么是 RubyGem
RubyGem是Ruby语言的标准源码打包格式。
大家一直都在用gem
这个命令,但是很少有人知道这个东西是怎么来的,这里我从网上扒下一些资料汇总一下,分享给大家。最后面会有这些链接,想进一步了解的,可以点进去看看。Ruby语言深受其他几种脚本语言的影响,其中就有Perl,而Perl有个CPAN(Comprehensive Perl Archive Network),这个东西也就像是现在的RubyGems.org,但是当时Ruby是没有这样一个东西的。像CPAN和RubyGem,它们仅仅是定义好的一种源码的打包和安装方式,另外还有一些组织,会提供这种免费的公共的源码包的存储,这也就现在大家每天都要使用的安装方式:
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/gem
rubygems有默认的源,也可以更改,国内的基本就是https://rubygems.taobao.org
了,有些公司有自己的需求,也会搭建自己的私源。当前的官方源为https://rubygems.org
,这个源也是几经辗转,早期的Ruby用户都知道http://gems.rubyforge.org
和http://gemcutter.org
,甚至github都曾经作为源使用过,也就是http://gems.github.com
,这三个现在都已经弃用了。
看看,一个简单的gem install
历史还不少啊。
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分钟内学会。
如何制作一个自己的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中的FIXME
和TODO
,这个警告如果不解决是无法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应用中使用它了。
参考链接: