diff options
author | Samuel Giddins <segiddins@segiddins.me> | 2016-08-03 18:43:24 -0500 |
---|---|---|
committer | Samuel Giddins <segiddins@segiddins.me> | 2016-08-25 11:16:40 -0500 |
commit | a7163e32c3045b25c7bf2b90329971f3788da358 (patch) | |
tree | 806d10f9ec7df71df758f13c611fb0a269684157 /lib | |
parent | 8513ed1481dde5b47eead96dd0a1cfe3d77c4c84 (diff) | |
download | bundler-a7163e32c3045b25c7bf2b90329971f3788da358.tar.gz |
Resolve for specific platforms
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bundler/definition.rb | 14 | ||||
-rw-r--r-- | lib/bundler/dependency.rb | 2 | ||||
-rw-r--r-- | lib/bundler/gem_helpers.rb | 33 | ||||
-rw-r--r-- | lib/bundler/lazy_specification.rb | 2 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 35 | ||||
-rw-r--r-- | lib/bundler/runtime.rb | 3 | ||||
-rw-r--r-- | lib/bundler/source.rb | 1 | ||||
-rw-r--r-- | lib/bundler/spec_set.rb | 14 |
8 files changed, 75 insertions, 29 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index dc3b4690d7..705576c5fc 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -70,7 +70,8 @@ module Bundler if lockfile && File.exist?(lockfile) @lockfile_contents = Bundler.read_file(lockfile) @locked_gems = LockfileParser.new(@lockfile_contents) - @platforms = @locked_gems.platforms + @locked_platforms = @locked_gems.platforms + @platforms = @locked_platforms.dup @locked_bundler_version = @locked_gems.bundler_version @locked_ruby_version = @locked_gems.ruby_version @@ -91,6 +92,7 @@ module Bundler @locked_deps = [] @locked_specs = SpecSet.new([]) @locked_sources = [] + @locked_platforms = [] end @unlock[:gems] ||= [] @@ -102,8 +104,9 @@ module Bundler @gem_version_promoter = create_gem_version_promoter - current_platform = Bundler.rubygems.platforms.map {|p| generic(p) }.compact.last - add_platform(current_platform) + current_platform = Bundler.rubygems.platforms.last + add_platform(current_platform) if Bundler.settings[:specific_platform] + add_platform(generic(current_platform)) @path_changes = converge_paths eager_unlock = expand_dependencies(@unlock[:gems]) @@ -414,6 +417,11 @@ module Bundler deleted = [] changed = [] + new_platforms = @platforms - @locked_platforms + deleted_platforms = @locked_platforms - @platforms + added.concat new_platforms.map {|p| "* platform: #{p}" } + deleted.concat deleted_platforms.map {|p| "* platform: #{p}" } + gemfile_sources = sources.lock_sources new_sources = gemfile_sources - @locked_sources diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index 1b1808b40a..66162d741a 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -52,7 +52,7 @@ module Bundler :x64_mingw_20 => Gem::Platform::X64_MINGW, :x64_mingw_21 => Gem::Platform::X64_MINGW, :x64_mingw_22 => Gem::Platform::X64_MINGW, - :x64_mingw_23 => Gem::Platform::X64_MINGW + :x64_mingw_23 => Gem::Platform::X64_MINGW, }.freeze REVERSE_PLATFORM_MAP = {}.tap do |reverse_platform_map| diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb index 5c824ffefc..03c1f33fe2 100644 --- a/lib/bundler/gem_helpers.rb +++ b/lib/bundler/gem_helpers.rb @@ -28,5 +28,38 @@ module Bundler generic(Gem::Platform.local) end module_function :generic_local_platform + + def platform_specificity_match(spec_platform, user_platform) + spec_platform = Gem::Platform.new(spec_platform) + return [-1, -1, -1] if spec_platform == user_platform + return [5, 5, 5] if spec_platform.nil? || spec_platform == Gem::Platform::RUBY || user_platform == Gem::Platform::RUBY + + [ + if spec_platform.os == user_platform.os + 0 + else + 1 + end, + + if spec_platform.cpu == user_platform.cpu + 0 + elsif spec_platform.cpu == "arm" && user_platform.cpu.to_s.start_with?("arm") + 0 + elsif spec_platform.cpu.nil? || spec_platform.cpu == "universal" + 1 + else + 2 + end, + + if spec_platform.version == user_platform.version + 0 + elsif spec_platform.version.nil? + 1 + else + 2 + end, + ] + end + module_function :platform_specificity_match end end diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb index 36ff5c59ed..0c7b4f2c3d 100644 --- a/lib/bundler/lazy_specification.rb +++ b/lib/bundler/lazy_specification.rb @@ -55,7 +55,7 @@ module Bundler end def __materialize__ - @specification = source.specs.search(Gem::Dependency.new(name, version)).last + @specification = source.specs.search(self).last end def respond_to?(*args) diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 3ab4ae6f38..62a9215f66 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -66,8 +66,6 @@ module Bundler end end - ALL = Bundler::Dependency::PLATFORM_MAP.values.uniq.freeze - class SpecGroup < Array include GemHelpers @@ -78,10 +76,9 @@ module Bundler @required_by = [] @activated_platforms = [] @dependencies = nil - @specs = {} - - ALL.each do |p| - @specs[p] = reverse.find {|s| s.match_platform(p) } + @specs = Hash.new do |specs, platform| + specs[platform] = select {|spec| spec.match_platform(platform) }. + min_by {|spec| platform_specificity_match(spec.platform, platform) } end end @@ -92,18 +89,12 @@ module Bundler end def to_specs - specs = {} - - @activated_platforms.each do |p| + @activated_platforms.map do |p| next unless s = @specs[p] - platform = generic(Gem::Platform.new(s.platform)) - next if specs[platform] - - lazy_spec = LazySpecification.new(name, version, platform, source) + lazy_spec = LazySpecification.new(name, version, s.platform, source) lazy_spec.dependencies.replace s.dependencies - specs[platform] = lazy_spec - end - specs.values + lazy_spec + end.compact end def activate_platform!(platform) @@ -148,17 +139,15 @@ module Bundler private def __dependencies - @dependencies ||= begin - dependencies = {} - ALL.each do |p| - next unless spec = @specs[p] - dependencies[p] = [] + @dependencies = Hash.new do |dependencies, platform| + dependencies[platform] = [] + if spec = @specs[platform] spec.dependencies.each do |dep| next if dep.type == :development - dependencies[p] << DepProxy.new(dep, p) + dependencies[platform] << DepProxy.new(dep, platform) end end - dependencies + dependencies[platform] end end diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index fda499cf5a..45f445aec1 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -140,7 +140,8 @@ module Bundler Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}" - specs.each do |spec| + specs_to_cache = Bundler.settings[:cache_all_platforms] ? @definition.resolve.materialized_for_all_platforms : specs + specs_to_cache.each do |spec| next if spec.name == "bundler" next if spec.source.is_a?(Source::Gemspec) spec.source.send(:fetch_gem, spec) if Bundler.settings[:cache_all_platforms] && spec.source.respond_to?(:fetch_gem, true) diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb index afa7d91838..e18d8ba1cb 100644 --- a/lib/bundler/source.rb +++ b/lib/bundler/source.rb @@ -14,6 +14,7 @@ module Bundler def version_message(spec) message = "#{spec.name} #{spec.version}" + message += " (#{spec.platform})" if Bundler.ui.debug? && spec.platform != Gem::Platform::RUBY if Bundler.locked_gems locked_spec = Bundler.locked_gems.specs.find {|s| s.name == spec.name } diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index f2ccac4742..48699abfe4 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -99,6 +99,20 @@ module Bundler SpecSet.new(materialized.compact) end + # Materialize for all the specs in the spec set, regardless of what platform they're for + # This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform) + # @return [Array<Gem::Specification>] + def materialized_for_all_platforms + names = @specs.map(&:name).uniq + @specs.map do |s| + next s unless s.is_a?(LazySpecification) + s.source.dependency_names = names if s.source.respond_to?(:dependency_names=) + spec = s.__materialize__ + raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec + spec + end + end + def merge(set) arr = sorted.dup set.each do |s| |