Rails源码阅读(11)Rails使用bundle保持多机器环境gem版本的一致性

 

Rails源码阅读(11)Rails使用bundle保持多机器环境gem版本的一致性

 

====rails3====

文件conf/book.rb

 

require 'rubygems'

# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

 

require 'rubygems' #这个ruby1。9后已经不需要了

后面的几句就是启动bundle,把gem包加载进来。

熟悉ruby包加载原理的,估计能猜出来bundle和Gemfile都做了啥,就是把用到的包路径加载进ruby寻找的路径中,从而在使用某个rb文件的时候,可以从某个路径下面找出来。

让我们验证一下吧。

 

文件bundler/setup

 

require 'bundler/shared_helpers'

if Bundler::SharedHelpers.in_bundle?
  require 'bundler'
  if STDOUT.tty?
    begin
      Bundler.setup
    rescue Bundler::BundlerError => e
      puts "\e[31m#{e.message}\e[0m"
      puts e.backtrace.join("\n") if ENV["DEBUG"]
      if Bundler::GemNotFound === e
        puts "\e[33mRun `bundle install` to install missing gems.\e[0m"
      end
      exit e.status_code
    end
  else
    Bundler.setup
  end

  # Add bundler to the load path after disabling system gems
  bundler_lib = File.expand_path("../..", __FILE__)
  $LOAD_PATH.unshift(bundler_lib) unless $LOAD_PATH.include?(bundler_lib)
end

 这个文件核心就这一句:Bundler.setup

 

文件bundler。rb 

。。。 。。。

    def setup(*groups)
      # Just return if all groups are already loaded
      return @setup if defined?(@setup)

      if groups.empty?
        # Load all groups, but only once
        @setup = load.setup
      else
        @completed_groups ||= []
        # Figure out which groups haven't been loaded yet
        unloaded = groups - @completed_groups
        # Record groups that are now loaded
        @completed_groups = groups
        unloaded.any? ? load.setup(*groups) : load
      end
    end

    def require(*groups)
      setup(*groups).require(*groups)
    end

    def load
      @load ||= Runtime.new(root, definition)
    end
。。。 。。。

 这个文件比较大,是用来加载Gemfile.lock中的gem的。详细的类太多了,先跳出吧。

 

看看加载的结果:

irb

1.9.3p194 :002 > puts $:

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/x86_64-linux

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby/1.9.1/x86_64-linux

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/x86_64-linux

 

1.9.3p194 :003 > require "./config/boot.rb"

 => true

 

1.9.3p194 :004 > puts $:

/usr/share/ruby-rvm/gems/[email protected]/gems/uglifier-2.1.2/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/thin-1.5.1/lib

... ...

/usr/share/ruby-rvm/gems/[email protected]/gems/activemodel-3.2.13/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/builder-3.0.4/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/activesupport-3.2.13/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/multi_json-1.7.9/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/i18n-0.6.1/lib

/usr/share/ruby-rvm/gems/[email protected]/gems/rake-10.1.0/lib

/usr/share/ruby-rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.5/lib

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/x86_64-linux

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby/1.9.1/x86_64-linux

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/vendor_ruby

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1

/usr/share/ruby-rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/x86_64-linux

 

看结果,都加载进来了,而且版本都是跟Gemfile.lock中一致的。

加载的时候,是必须有版本的,虽然Gemfile有很多gem我们不指定版本,或者不指定精确版本。

 

至此,rails是怎么使用bundle的,以及bundle大概干了什么事情,就清楚了。

从这些源码也可以扩展,如果我们的项目(不是rails项目),想用bundle来维持版本的一致性,怎么使用和价值bundle,自然跟这里类似了。

 

Bundle官网就介绍了使用,使用上跟上面的几乎一致。

http://bundler.io/

Inside your app, load up the bundled environment:
require 'rubygems' 

require 'bundler/setup'

 

+

+

+

=

+

+

+

 

你可能感兴趣的:(Bundle)