Railsソース読解(11)Rails bundleを使用してマルチマシン環境gemバージョンの一貫性を維持

5576 ワード


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'#このruby 1.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("
") 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と似ています.
 
Bundle公式サイトでは使用を紹介しており、使用上は上記とほぼ一致しています.
http://bundler.io/
Inside your app, load up the bundled environment:
require 'rubygems' 

require 'bundler/setup'

 
+
+
+
=
+
+
+