diff options
author | Terence Lee <hone02@gmail.com> | 2011-10-03 18:59:50 -0500 |
---|---|---|
committer | Terence Lee <hone02@gmail.com> | 2011-10-03 18:59:50 -0500 |
commit | 544c74be6b9b3b50f0b4c6eee05bab41500fbbd3 (patch) | |
tree | 0de675590ade24a8112ba3868c8a3ce6cc671fe7 | |
parent | 75a9e488dbbd9467b4f0a303b850f097f27912dd (diff) | |
parent | 165dbfd58b8abe3057e0bdd2e8b434b34c240464 (diff) | |
download | bundler-544c74be6b9b3b50f0b4c6eee05bab41500fbbd3.tar.gz |
Merge pull request #1466 from carlhuda/bundler
---
This could produce issues like #1446, where the wrong gem (or no gem) would be found and installed.
-rw-r--r-- | Rakefile | 17 | ||||
-rw-r--r-- | lib/bundler.rb | 3 | ||||
-rw-r--r-- | lib/bundler/dep_proxy.rb | 35 | ||||
-rw-r--r-- | lib/bundler/gem_helpers.rb | 23 | ||||
-rw-r--r-- | lib/bundler/index.rb | 2 | ||||
-rw-r--r-- | lib/bundler/match_platform.rb | 13 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 35 | ||||
-rw-r--r-- | lib/bundler/rubygems_ext.rb | 72 | ||||
-rw-r--r-- | spec/realworld/edgecases_spec.rb | 9 | ||||
-rw-r--r-- | spec/spec_helper.rb | 6 |
10 files changed, 123 insertions, 92 deletions
@@ -34,6 +34,13 @@ begin rm_rf 'tmp' end + desc "Run the real-world spec suite (reequires internet)" + task :realworld => ["set_realworld", "spec"] + + task :set_realworld do + ENV['BUNDLER_REALWORLD_TESTS'] = '1' + end + desc "Run the spec suite with the sudo tests" task :sudo => ["set_sudo", "spec", "clean_sudo"] @@ -59,6 +66,7 @@ begin # Create tasks like spec:rubygems:v1.8.3:sudo to run the sudo specs namespace rg do task :sudo => ["set_sudo", rg, "clean_sudo"] + task :realworld => ["set_realworld", rg] end task "clone_rubygems_#{rg}" do @@ -97,7 +105,7 @@ begin end desc "Run the tests on Travis CI against a rubygem version (using ENV['RGV'])" - task "travis" do + task :travis do rg = ENV['RGV'] || 'master' puts "\n\e[1;33m[Travis CI] Running bundler specs against rubygems #{rg}\e[m\n\n" @@ -108,7 +116,12 @@ begin puts "\n\e[1;33m[Travis CI] Running bundler sudo specs against rubygems #{rg}\e[m\n\n" sudos = safe_task { Rake::Task["spec:rubygems:#{rg}:sudo"].invoke } - unless specs && sudos + Rake::Task["spec:rubygems:#{rg}"].reenable + + puts "\n\e[1;33m[Travis CI] Running bundler real world specs against rubygems #{rg}\e[m\n\n" + realworld = safe_task { Rake::Task["spec:rubygems:#{rg}:realworld"].invoke } + + unless specs && sudos && realworld fail "Bundler tests failed, please review the log for more information" end end diff --git a/lib/bundler.rb b/lib/bundler.rb index a719060993..6204079827 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -18,17 +18,20 @@ module Bundler autoload :Definition, 'bundler/definition' autoload :Dependency, 'bundler/dependency' + autoload :DepProxy, 'bundler/dep_proxy' autoload :Dsl, 'bundler/dsl' autoload :EndpointSpecification, 'bundler/endpoint_specification' autoload :Environment, 'bundler/environment' autoload :Fetcher, 'bundler/fetcher' autoload :GemHelper, 'bundler/gem_helper' + autoload :GemHelpers, 'bundler/gem_helpers' autoload :GemInstaller, 'bundler/gem_installer' autoload :Graph, 'bundler/graph' autoload :Index, 'bundler/index' autoload :Installer, 'bundler/installer' autoload :LazySpecification, 'bundler/lazy_specification' autoload :LockfileParser, 'bundler/lockfile_parser' + autoload :MatchPlatform, 'bundler/match_platform' autoload :RemoteSpecification, 'bundler/remote_specification' autoload :Resolver, 'bundler/resolver' autoload :Runtime, 'bundler/runtime' diff --git a/lib/bundler/dep_proxy.rb b/lib/bundler/dep_proxy.rb new file mode 100644 index 0000000000..a92282ba99 --- /dev/null +++ b/lib/bundler/dep_proxy.rb @@ -0,0 +1,35 @@ +module Bundler + class DepProxy + + 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? == + + def type + @dep.type + end + + def to_s + "#{name} (#{requirement}) #{__platform}" + end + + private + + def method_missing(*args) + @dep.send(*args) + end + + end +end diff --git a/lib/bundler/gem_helpers.rb b/lib/bundler/gem_helpers.rb new file mode 100644 index 0000000000..5eff233a56 --- /dev/null +++ b/lib/bundler/gem_helpers.rb @@ -0,0 +1,23 @@ +module Bundler + module GemHelpers + + GENERIC_CACHE = {} + GENERICS = [ + Gem::Platform.new('java'), + Gem::Platform.new('mswin32'), + Gem::Platform.new('x86-mingw32'), + Gem::Platform::RUBY + ] + + def generic(p) + return p if p == Gem::Platform::RUBY + + GENERIC_CACHE[p] ||= begin + found = GENERICS.find do |p2| + p2.is_a?(Gem::Platform) && p.os == p2.os + end + found || Gem::Platform::RUBY + end + end + end +end diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 07ea77df4a..b49d2c5c9f 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -130,7 +130,7 @@ module Bundler end def search_by_dependency(dependency, base = nil) - @cache[dependency.hash] ||= begin + @cache[dependency.hash^base.hash] ||= begin specs = specs_by_name(dependency.name) + (base || []) found = specs.select do |spec| if base # allow all platforms when searching from a lockfile diff --git a/lib/bundler/match_platform.rb b/lib/bundler/match_platform.rb new file mode 100644 index 0000000000..523dafbbd6 --- /dev/null +++ b/lib/bundler/match_platform.rb @@ -0,0 +1,13 @@ +require 'bundler/gem_helpers' + +module Bundler + module MatchPlatform + include GemHelpers + + def match_platform(p) + Gem::Platform::RUBY == platform or + platform.nil? or p == platform or + generic(Gem::Platform.new(platform)) == p + end + end +end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 46cf0551be..dde839636a 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -364,28 +364,25 @@ module Bundler d = dep.dep end - key = "#{d}-#{dep.__platform}" - return @deps_for[key] if @deps_for[key] - - index = @source_requirements[d.name] || @index - results = index.search(d, @base[d.name]) - - if results.any? - version = results.first.version - nested = [[]] - results.each do |spec| - if spec.version != version - nested << [] - version = spec.version + @deps_for[d.hash] ||= begin + index = @source_requirements[d.name] || @index + results = index.search(d, @base[d.name]) + + if results.any? + version = results.first.version + nested = [[]] + results.each do |spec| + if spec.version != version + nested << [] + version = spec.version + end + nested.last << spec end - nested.last << spec + deps = nested.map{|a| SpecGroup.new(a) }.select{|sg| sg.for?(dep.__platform) } + else + deps = [] end - deps = nested.map{|a| SpecGroup.new(a) }.select{|sg| sg.for?(dep.__platform) } - else - deps = [] end - - @deps_for[key] = deps end def clean_req(req) diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index 0eb179e866..a68fb0a03a 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -7,6 +7,7 @@ end require 'rubygems' require 'rubygems/specification' +require 'bundler/match_platform' module Gem @loaded_stacks = Hash.new { |h,k| h[k] = [] } @@ -143,79 +144,10 @@ module Gem alias eql? == end - -end - -module Bundler - class DepProxy - - 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? == - - def type - @dep.type - end - - def to_s - "#{name} (#{requirement}) #{__platform}" - end - - private - - def method_missing(*args) - @dep.send(*args) - end - - end - - module GemHelpers - - GENERIC_CACHE = {} - GENERICS = [ - Gem::Platform::JAVA, - Gem::Platform::MSWIN, - Gem::Platform::MINGW, - Gem::Platform::RUBY - ] - - def generic(p) - return p if p == Gem::Platform::RUBY - - GENERIC_CACHE[p] ||= begin - found = GENERICS.find do |p2| - p2.is_a?(Gem::Platform) && p.os == p2.os - end - found || Gem::Platform::RUBY - end - end - end - - module MatchPlatform - include GemHelpers - - def match_platform(p) - Gem::Platform::RUBY == platform or - platform.nil? or p == platform or - generic(Gem::Platform.new(platform)) == p - end - end end module Gem class Specification - include Bundler::MatchPlatform + include ::Bundler::MatchPlatform end end diff --git a/spec/realworld/edgecases_spec.rb b/spec/realworld/edgecases_spec.rb new file mode 100644 index 0000000000..9d369d38a8 --- /dev/null +++ b/spec/realworld/edgecases_spec.rb @@ -0,0 +1,9 @@ +describe "real world edgecases", :realworld => true do + it "ignores extra gems with bad platforms" do + install_gemfile <<-G + source :rubygems + gem "linecache", "0.46" + G + err.should eq("") + end +end
\ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 41377f0631..5b4b4870c1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -53,6 +53,12 @@ RSpec.configure do |config| config.filter_run_excluding :sudo => true end + if ENV['BUNDLER_REALWORLD_TESTS'] + config.filter_run :realworld => true + else + config.filter_run_excluding :realworld => true + end + config.filter_run :focused => true unless ENV['CI'] config.run_all_when_everything_filtered = true config.alias_example_to :fit, :focused => true |