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'
+
+
+
=
+
+
+