diff options
Diffstat (limited to 'lib/bundler')
-rw-r--r-- | lib/bundler/definition.rb | 53 | ||||
-rw-r--r-- | lib/bundler/source.rb | 33 |
2 files changed, 75 insertions, 11 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index d0e03ddd..c2de990b 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -23,15 +23,18 @@ module Bundler if lockfile && File.exists?(lockfile) locked = LockfileParser.new(File.read(lockfile)) - @platforms = locked.platforms - @locked_deps = locked.dependencies - @locked_specs = SpecSet.new(locked.specs) - @sources = locked.sources + @platforms = locked.platforms + @locked_deps = locked.dependencies + @locked_specs = SpecSet.new(locked.specs) + @locked_sources = locked.sources else - @platforms = [] - @locked_deps = [] - @locked_specs = SpecSet.new([]) + @platforms = [] + @locked_deps = [] + @locked_specs = SpecSet.new([]) + @locked_sources = [] end + + converge end def unlock!(what_to_unlock) @@ -137,6 +140,24 @@ module Bundler private + def converge + common = @locked_sources & @sources + fresh = @sources - common + stale = @locked_sources - common + + @locked_specs.each do |s| + next unless stale.include?(s.source) + @unlock << s.name + end + + @sources = common + fresh + @dependencies.each do |dep| + if dep.source && source = @sources.find { |s| dep.source == s } + dep.source == source + end + end + end + def sorted_sources sources.sort_by do |s| # Place GEM at the top @@ -152,11 +173,11 @@ module Bundler # This allows us to add on the *new* requirements in the Gemfile and make # sure that the changes result in a conservative update to the Gemfile.lock. def locked_specs_as_deps - deps = @dependencies & @locked_deps - + deps = [] @dependencies.each do |dep| - next if deps.include?(dep) - deps << dep if @locked_specs.any? { |s| s.satisfies?(dep) } + if in_locked_deps?(dep) || satisfies_locked_spec?(dep) + deps << dep + end end @locked_specs.for(deps, @unlock).map do |s| @@ -168,6 +189,16 @@ module Bundler end end + def in_locked_deps?(dep) + @locked_deps.any? do |d| + dep == d && dep.source == d.source + end + end + + def satisfies_locked_spec?(dep) + @locked_specs.any? { |s| s.satisfies?(dep) } + end + def resolve(type, idx) source_requirements = {} resolver_dependencies.each do |dep| diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb index 681eb827..9afb4ce8 100644 --- a/lib/bundler/source.rb +++ b/lib/bundler/source.rb @@ -21,6 +21,16 @@ module Bundler @spec_fetch_map = {} end + def hash + Rubygems.hash + end + + def eql?(o) + Rubygems === o + end + + alias == eql? + # Not really needed, but it seems good to implement this method for interface # consistency. Source name is mostly used to identify Path & Git sources def name @@ -241,6 +251,19 @@ module Bundler "source at #{@path}" end + def hash + self.class.hash + end + + def eql?(o) + Path === o && + path == o.path && + name == o.name && + version == o.version + end + + alias == eql? + def name File.basename(@path.to_s) end @@ -405,6 +428,16 @@ module Bundler out << " specs:\n" end + def eql?(o) + Git === o && + uri == o.uri && + ref == o.ref && + name == o.name && + version == o.version + end + + alias == eql? + def to_s ref = @options["ref"] ? shortref_for(@options["ref"]) : @ref "#{@uri} (at #{ref})" |