Gem 与 Bundler - Ruby项目依赖管理
(此文转载,抱歉忘记出处了)
gem与bundler是关于一个ruby项目的软件包依赖的, 它们是以一个ruby项目为中心的. 如果是跟项目无关的ruby运行环境的配置管理, 需要去了解
rvm 与 gemset.
gem:
gem就是ruby的软件包. 一个gem就是一个ruby软件.
- gem sources -l 查看gem的源
- 默认只有http://rubygems.org/
- gem sources --remove http://rubygems.org/
- 删除http://rubygems.org.源
- gem sources -a http://ruby.taobao.org
- 增加 http://ruby.taobao.org 源
- 通过上面的命令, 可以把gem的源设置为只有taobao的那个. 在中国境内访问的速度比原来官方默认那个要快很多.
- gem list
- 查看当前安装的gem软件包及其版本信息
- gem update --system 升级gem软件本身
- 安装gem软件包默认安装两种文档: ri 和 rdoc, 一般认为作用不大, 因为我们可以通过互联网来查看doc. 通过下面的步骤禁用doc的安装:
- 编辑 ~/.gemrc 文件(如果没有的话就创建), 添加两行
- install: --no-ri --no-rdoc
- update: --no-ri --no-rdoc
- 编辑 ~/.gemrc 文件(如果没有的话就创建), 添加两行
bundler:
这个命令也可以安装ruby软件. 比如用rails新创建一个项目的时候, 会在最后执行bundle install命令去安装软件. 这里是官网:
http://gembundler.com/
那么bundle install和gem install的区别是什么呢? 我的理解是: bundle是用来管理维护项目的软件包的; gem则是用来管理具体的每一个软件包的.
项目的根目录会有一个Gemfile, 里面定义了该项目的软件包依赖的相关事项. 发现它默认是从rubygems.org这个网站获取内容的. 我想把源换成taobao.org. 可以修改Gemfile文件. 把source那一行改成: source 'http://ruby.taobao.org/'
实际上Gemfile就相当于我之前写Python代码时写的requires.txt文件, 里面放的是当前软件所依赖的软件包. bundle install 这个命令会读取Gemfile中的内容并安装升级相应的软件(相当于python中的pip install -r requires.txt命令)
对软件包版本的控制
- 默认就是安装最新版: gem 'sqlite3'
- 可以显式地声明版本号: gem 'sqlite3', '1.3.5'
- 强制升级: gem 'sqlite3' '>= 1.3.5'
- 只升级小版本: gem 'sqlite3' '~> 1.3.5'
bundle install执行完之后, 会把当前的软件包环境做一个快照, 放到Gemfile.lock文件中. 如果不删除Gemfile.lock文件, 相关的gem是不会自动升级到最新版本的. 比如我一开始用的是rails 3.2.2, 当3.2.3出来之后, 要么我得在Gemfile中显式地声明版本号, 要么我就删除Gemfile.lock文件. 否则我就无法使用最新的rails. 我想这就是为什么这个文件被称为是.lock文件.
bundle exec [command] 表示使用Gemfile中的指定的软件来执行command. 比如bundle exec rake db:migrate. Ruby可以通过rvm和gemset来组织运行环境, 多个运行环境可以并存不冲突, 每个ruby项目也都可以定义自己需要的gem软件的版本. 为了不搞混掉, 可以明确地通过bundle exec来调用当前项目指定的软件命令.
如果不想每次都在前面加上bundle exec, 可以这样配置:
- chmod +x $rvm_path/hooks/after_cd_bundler
- 赋予 $rvm_path/hooks/after_cd_bundler 脚本可执行权限
- bundle --binstubs=./bundler_stubs
- 创建看了bundler_stubs目录, 把当前环境的可执行命令全都放到了这个目录
- 上面的两个命令结合起来, 就会非常神奇地保证每个命令都是在正确的环境下执行的.
- 不推荐将bundler_stubs文件签入版本控制, 所以最好把它加入.gitignore
- 如果项目中引入了新的可执行程序, 需要再次执行命令: bundle --binstubs=./bundler_stubs. 目的当然是把这个新的程序放入bundler_stubs目录
bundler配置文件:
- 项目特定配置文件, 放在项目根目录下的.bundle/config文件中.
- 全局的配置文件, 放在 ~/.bundle/config文件中.
比如你在当前项目运行bundle install --without production, 后面的参数"--withou production"会自动被保存到项目根目录的.bundle/config文件中. 下一次运行bundle install会自动为你加上参数.
一个gem包的特点
有一个xxx.gemspec文件, 里面有关于该软件包的一些信息, 比如依赖于哪些软件包的哪些版本