diff options
-rw-r--r-- | lib/bundler/definition.rb | 4 | ||||
-rw-r--r-- | lib/bundler/dependency.rb | 2 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 19 | ||||
-rw-r--r-- | lib/bundler/rubygems_ext.rb | 41 | ||||
-rw-r--r-- | lib/bundler/spec_set.rb | 60 | ||||
-rw-r--r-- | spec/install/gems/platform_spec.rb | 2 |
6 files changed, 72 insertions, 56 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index e6680310..9323069b 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -52,6 +52,10 @@ module Bundler current_platform = Gem.platforms.map { |p| p.to_generic }.compact.last @platforms |= [current_platform] + @dependencies.each do |dependency| + dependency.platforms.replace @platforms + end + converge end diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index 295c82b5..dacf991e 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -5,6 +5,7 @@ module Bundler class Dependency < Gem::Dependency attr_reader :autorequire attr_reader :groups + attr_reader :platforms def initialize(name, version, options = {}, &blk) super(name, version) @@ -12,6 +13,7 @@ module Bundler @autorequire = nil @groups = Array(options["group"] || :default).map { |g| g.to_sym } @source = options["source"] + @platforms = [] if options.key?('require') @autorequire = Array(options['require'] || []) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 3e2bc891..9bac572a 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -26,25 +26,6 @@ module Bundler Gem::Platform::MSWIN, Gem::Platform::MING] - class DepProxy - - undef to_s - undef type - - attr_reader :required_by, :__platform, :dep - - def initialize(dep, platform) - @dep, @__platform, @required_by = dep, platform, [] - end - - private - - def method_missing(*args) - @dep.send(*args) - end - - end - class SpecGroup < Array attr_reader :activated, :required_by diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index ceab69b9..a6ed2c86 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -5,14 +5,45 @@ unless defined? Gem require 'rubygems/specification' end +module Bundler + class DepProxy + + undef to_s + undef type + + attr_reader :required_by, :__platform, :dep + + def initialize(dep, platform) + @dep, @__platform, @required_by = dep, platform, [] + end + + def hash + @hash ||= dep.hash + end + + def ==(o) + dep == o.dep && __platform == o.__platform + end + + alias eql? == + + private + + def method_missing(*args) + @dep.send(*args) + end + + end +end + module Gem @loaded_stacks = Hash.new { |h,k| h[k] = [] } module MatchPlatform def match_platform(p) + Gem::Platform::RUBY == platform or platform.nil? or p == platform or - (p != Gem::Platform::RUBY and p =~ platform) or - Gem::Platform::RUBY == platform + Gem::Platform.new(platform).to_generic == p end end @@ -125,6 +156,8 @@ module Gem MSWIN = Gem::Platform.new('mswin32') MING = Gem::Platform.new('x86-mingw32') + GENERIC_CACHE = {} + class << RUBY def to_generic ; self ; end end @@ -132,13 +165,13 @@ module Gem GENERICS = [JAVA, MSWIN, MING, RUBY] def hash - Platform.hash + @cpu.hash + @os.hash + @version.hash end alias eql? == def to_generic - GENERICS.find { |p| self =~ p } || RUBY + GENERIC_CACHE[self] ||= GENERICS.find { |p| self =~ p } || RUBY end end end diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 13239ef0..6d7c229e 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -16,54 +16,47 @@ module Bundler @specs.length end - # TODO: Handle platform filtering - def for(deps, skip = [], platform_filter = false) - handled = {} - deps = deps.map { |d| d.respond_to?(:name) ? d.name : d } + def for(dependencies, skip = [], check = false) + handled, deps, specs = {}, [], [] + + dependencies.each do |d| + d.platforms.each do |p| + deps << DepProxy.new(d, p) + end + end until deps.empty? dep = deps.shift - next if handled[dep] || skip.include?(dep) - specs = lookup[dep] - next if specs.empty? + next if handled[dep] || skip.include?(dep.name) - if platform_filter - specs = specs.sort_by { |s| s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s }.reverse - specs = Array(specs.find { |s| Gem::Platform.match(s.platform) }) + spec = lookup[dep.name].find do |s| + s.match_platform(dep.__platform) end - specs.each do |s| - handled[s.name] ||= [] - handled[s.name] << s - s.dependencies.each do |d| + handled[dep] = true + + if spec + specs << spec + + spec.dependencies.each do |d| next if d.type == :development - deps << d.name + deps << DepProxy.new(d, dep.__platform) end + elsif check + return false end end - SpecSet.new(handled.values.flatten) + check ? true : SpecSet.new(specs) end def valid_for?(deps) - deps = deps.dup - handled = {} - - until deps.empty? - dep = deps.shift - unless dep.type == :development || handled[dep.name] - specs = lookup[dep.name] - return false unless specs.any? - handled[dep.name] = true - specs.each { |s| deps.concat s.dependencies } - end - end - true + self.for(deps, [], true) end def [](key) key = key.name if key.respond_to?(:name) - lookup[key].sort_by { |s| s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s } + lookup[key].reverse end def to_a @@ -75,7 +68,7 @@ module Bundler end def materialize(type, deps) - materialized = self.for(deps, [], true).to_a + materialized = self.for(deps, []).to_a materialized.map! do |s| next s unless s.is_a?(LazySpecification) s.__materialize__(s.source.send(type)) @@ -93,7 +86,10 @@ module Bundler def lookup @lookup ||= begin lookup = Hash.new { |h,k| h[k] = [] } - @specs.each do |s| + specs = @specs.sort_by do |s| + s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s + end + specs.reverse_each do |s| lookup[s.name] << s end lookup diff --git a/spec/install/gems/platform_spec.rb b/spec/install/gems/platform_spec.rb index 01409ed1..750a277a 100644 --- a/spec/install/gems/platform_spec.rb +++ b/spec/install/gems/platform_spec.rb @@ -69,7 +69,7 @@ describe "bundle install across platforms" do gem "nokogiri" G - should_be_installed "nokogiri 1.4.2 JAVA", "weakling 0.0.3" + should_be_installed "nokogiri 1.4.2 JAVA", "weakling 0.0.3", :platform => "java" simulate_new_machine |