diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2009-10-19 12:33:36 -0700 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2009-10-19 12:33:36 -0700 |
commit | a49c3b03650b3193cc9440a3b219ab7f19326297 (patch) | |
tree | dd68d637a074bc08d1328d780aeb092b2a4c8874 /railties/lib/rails/gem_dependency.rb | |
parent | 028911ad00e7f7733064a80393a1548401bba7af (diff) | |
parent | 1ac5cf478825391071d34ec3d7f294fe28c0fceb (diff) | |
download | rails-a49c3b03650b3193cc9440a3b219ab7f19326297.tar.gz rails-a49c3b03650b3193cc9440a3b219ab7f19326297.tar.bz2 rails-a49c3b03650b3193cc9440a3b219ab7f19326297.zip |
Merge branch 'master' of github.com:rails/rails
Diffstat (limited to 'railties/lib/rails/gem_dependency.rb')
-rw-r--r-- | railties/lib/rails/gem_dependency.rb | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/railties/lib/rails/gem_dependency.rb b/railties/lib/rails/gem_dependency.rb deleted file mode 100644 index 804bd75e55..0000000000 --- a/railties/lib/rails/gem_dependency.rb +++ /dev/null @@ -1,311 +0,0 @@ -require 'rails/vendor_gem_source_index' - -module Gem - def self.source_index=(index) - @@source_index = index - end -end - -module Rails - class GemDependency < Gem::Dependency - attr_accessor :lib, :source, :dep - - def self.unpacked_path - @unpacked_path ||= File.join(Rails.root, 'vendor', 'gems') - end - - @@framework_gems = {} - - def self.add_frozen_gem_path - @@paths_loaded ||= begin - source_index = Rails::VendorGemSourceIndex.new(Gem.source_index) - Gem.clear_paths - Gem.source_index = source_index - # loaded before us - we can't change them, so mark them - Gem.loaded_specs.each do |name, spec| - @@framework_gems[name] = spec - end - true - end - end - - def self.from_directory_name(directory_name, load_spec=true) - directory_name_parts = File.basename(directory_name).split('-') - name = directory_name_parts[0..-2].join('-') - version = directory_name_parts.last - result = self.new(name, :version => version) - spec_filename = File.join(directory_name, '.specification') - if load_spec - raise "Missing specification file in #{File.dirname(spec_filename)}. Perhaps you need to do a 'rake gems:refresh_specs'?" unless File.exists?(spec_filename) - spec = YAML::load_file(spec_filename) - result.specification = spec - end - result - rescue ArgumentError => e - raise "Unable to determine gem name and version from '#{directory_name}'" - end - - def initialize(name, options = {}) - require 'rubygems' unless Object.const_defined?(:Gem) - - if options[:requirement] - req = options[:requirement] - elsif options[:version] - req = Gem::Requirement.create(options[:version]) - else - req = Gem::Requirement.default - end - - @lib = options[:lib] - @source = options[:source] - @loaded = @frozen = @load_paths_added = false - - super(name, req) - end - - def add_load_paths - self.class.add_frozen_gem_path - return if @loaded || @load_paths_added - if framework_gem? - @load_paths_added = @loaded = @frozen = true - return - end - gem self - @spec = Gem.loaded_specs[name] - @frozen = @spec.loaded_from.include?(self.class.unpacked_path) if @spec - @load_paths_added = true - rescue Gem::LoadError - end - - def dependencies - return [] if framework_gem? - return [] unless installed? - specification.dependencies.reject do |dependency| - dependency.type == :development - end.map do |dependency| - GemDependency.new(dependency.name, :requirement => dependency.version_requirements) - end - end - - def specification - # code repeated from Gem.activate. Find a matching spec, or the currently loaded version. - # error out if loaded version and requested version are incompatible. - @spec ||= begin - matches = Gem.source_index.search(self) - matches << @@framework_gems[name] if framework_gem? - if Gem.loaded_specs[name] then - # This gem is already loaded. If the currently loaded gem is not in the - # list of candidate gems, then we have a version conflict. - existing_spec = Gem.loaded_specs[name] - unless matches.any? { |spec| spec.version == existing_spec.version } then - raise Gem::Exception, - "can't activate #{@dep}, already activated #{existing_spec.full_name}" - end - # we're stuck with it, so change to match - version_requirements = Gem::Requirement.create("=#{existing_spec.version}") - existing_spec - else - # new load - matches.last - end - end - end - - def specification=(s) - @spec = s - end - - def requirement - r = version_requirements - (r == Gem::Requirement.default) ? nil : r - end - - def built? - return false unless frozen? - - if vendor_gem? - specification.extensions.each do |ext| - makefile = File.join(unpacked_gem_directory, File.dirname(ext), 'Makefile') - return false unless File.exists?(makefile) - end - end - - true - end - - def framework_gem? - @@framework_gems.has_key?(name) - end - - def frozen? - @frozen ||= vendor_rails? || vendor_gem? - end - - def installed? - Gem.loaded_specs.keys.include?(name) - end - - def load_paths_added? - # always try to add load paths - even if a gem is loaded, it may not - # be a compatible version (ie random_gem 0.4 is loaded and a later spec - # needs >= 0.5 - gem 'random_gem' will catch this and error out) - @load_paths_added - end - - def loaded? - @loaded ||= begin - if vendor_rails? - true - elsif specification.nil? - false - else - # check if the gem is loaded by inspecting $" - # specification.files lists all the files contained in the gem - gem_files = specification.files - # select only the files contained in require_paths - typically in bin and lib - require_paths_regexp = Regexp.new("^(#{specification.require_paths*'|'})/") - gem_lib_files = gem_files.select { |f| require_paths_regexp.match(f) } - # chop the leading directory off - a typical file might be in - # lib/gem_name/file_name.rb, but it will be 'require'd as gem_name/file_name.rb - gem_lib_files.map! { |f| f.split('/', 2)[1] } - # if any of the files from the above list appear in $", the gem is assumed to - # have been loaded - !(gem_lib_files & $").empty? - end - end - end - - def vendor_rails? - Gem.loaded_specs.has_key?(name) && Gem.loaded_specs[name].loaded_from.empty? - end - - def vendor_gem? - specification && File.exists?(unpacked_gem_directory) - end - - def build(options={}) - require 'rails/gem_builder' - return if specification.nil? - if options[:force] || !built? - return unless File.exists?(unpacked_specification_filename) - spec = YAML::load_file(unpacked_specification_filename) - Rails::GemBuilder.new(spec, unpacked_gem_directory).build_extensions - puts "Built gem: '#{unpacked_gem_directory}'" - end - dependencies.each { |dep| dep.build(options) } - end - - def install - unless installed? - cmd = "#{gem_command} #{install_command.join(' ')}" - puts cmd - puts %x(#{cmd}) - end - end - - def load - return if @loaded || @load_paths_added == false - require(@lib || name) unless @lib == false - @loaded = true - rescue LoadError - puts $!.to_s - $!.backtrace.each { |b| puts b } - end - - def refresh - Rails::VendorGemSourceIndex.silence_spec_warnings = true - real_gems = Gem.source_index.installed_source_index - exact_dep = Gem::Dependency.new(name, "= #{specification.version}") - matches = real_gems.search(exact_dep) - installed_spec = matches.first - if frozen? - if installed_spec - # we have a real copy - # get a fresh spec - matches should only have one element - # note that there is no reliable method to check that the loaded - # spec is the same as the copy from real_gems - Gem.activate changes - # some of the fields - real_spec = Gem::Specification.load(matches.first.loaded_from) - write_specification(real_spec) - puts "Reloaded specification for #{name} from installed gems." - else - # the gem isn't installed locally - write out our current specs - write_specification(specification) - puts "Gem #{name} not loaded locally - writing out current spec." - end - else - if framework_gem? - puts "Gem directory for #{name} not found - check if it's loading before rails." - else - puts "Something bad is going on - gem directory not found for #{name}." - end - end - end - - def unpack(options={}) - unless frozen? || framework_gem? - FileUtils.mkdir_p unpack_base - Dir.chdir unpack_base do - Gem::GemRunner.new.run(unpack_command) - end - # Gem.activate changes the spec - get the original - real_spec = Gem::Specification.load(specification.loaded_from) - write_specification(real_spec) - end - dependencies.each { |dep| dep.unpack(options) } if options[:recursive] - end - - def write_specification(spec) - # copy the gem's specification into GEMDIR/.specification so that - # we can access information about the gem on deployment systems - # without having the gem installed - File.open(unpacked_specification_filename, 'w') do |file| - file.puts spec.to_yaml - end - end - - def ==(other) - self.name == other.name && self.requirement == other.requirement - end - alias_method :"eql?", :"==" - - private - - def gem_command - case RUBY_PLATFORM - when /win32/ - 'gem.bat' - when /java/ - 'jruby -S gem' - else - 'gem' - end - end - - def install_command - cmd = %w(install) << name - cmd << "--version" << %("#{requirement.to_s}") if requirement - cmd << "--source" << @source if @source - cmd - end - - def unpack_command - cmd = %w(unpack) << name - cmd << "--version" << "= "+specification.version.to_s if requirement - cmd - end - - def unpack_base - Rails::GemDependency.unpacked_path - end - - def unpacked_gem_directory - File.join(unpack_base, specification.full_name) - end - - def unpacked_specification_filename - File.join(unpacked_gem_directory, '.specification') - end - - end -end |