aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/bundler/definition.rb4
-rw-r--r--lib/bundler/dependency.rb2
-rw-r--r--lib/bundler/resolver.rb19
-rw-r--r--lib/bundler/rubygems_ext.rb41
-rw-r--r--lib/bundler/spec_set.rb60
-rw-r--r--spec/install/gems/platform_spec.rb2
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