summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrismo <chrismo@clabs.org>2016-06-16 07:30:52 -0500
committerchrismo <chrismo@clabs.org>2016-07-08 19:35:57 -0500
commit100c3bbdf937e1efd423556957a79de84af11f37 (patch)
tree830bc09f82facbe2e388e1990eb91fd1240f20ad
parenta404dad1e3804fbde807a40a1c2a370e72a96c23 (diff)
downloadbundler-100c3bbdf937e1efd423556957a79de84af11f37.tar.gz
minor/patch resolution code invokable.
Prior commit added in the code but it only worked in the default :major case by staying out of the way, so it at least didn't break existing functionality. But the GemsToPatch class hadn't been brought over from bundler-patch yet, so none of the patch/minor code could work as it was referencing an ivar that didn't exist yet. Bundler-patch not only will handle an update to whatever is the latest patch/minor version, but will also handle an update to a version specified in an advisory from ruby-advisory-db. At this point I don't believe we'll be adding the advisory behavior to Bundler proper, so this commit can bring over simply the array of gem names being updated without the GemsToPatch class or the extra sorting code that takes a specific version number into account. With these simplifications, the starter update_spec can run without exception, though for some reason it's behaving as if the :minor level were specified, instead of :patch. Rather than keep debugging from an integration level, it's time to start bringing over resolver tests.
-rw-r--r--lib/bundler/cli/update.rb3
-rw-r--r--lib/bundler/definition.rb4
-rw-r--r--lib/bundler/resolver.rb27
-rw-r--r--spec/commands/update_spec.rb2
4 files changed, 18 insertions, 18 deletions
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index aae08a7366..5e2d6b3389 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -39,7 +39,8 @@ module Bundler
Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby])
end
- Bundler.definition.update_opts.level = [:major, :minor, :patch].detect { |v| options.keys.include?(v) }
+ patch_level = [:major, :minor, :patch].detect { |v| options.keys.include?(v.to_s) }
+ Bundler.definition.update_opts.level = patch_level
Bundler::Fetcher.disable_endpoint = options["full-index"]
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index f5c31adaaf..d1ed4e0a44 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -83,8 +83,6 @@ module Bundler
@locked_sources = []
end
- @update_opts = Resolver::UpdateOptions.new(@locked_specs)
-
@unlock[:gems] ||= []
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && @locked_ruby_version
@@ -96,6 +94,8 @@ module Bundler
end
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
+ @update_opts = Resolver::UpdateOptions.new(@locked_specs, @unlock[:gems])
+
current_platform = Bundler.rubygems.platforms.map {|p| generic(p) }.compact.last
add_platform(current_platform)
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 7961140134..08d4fd04eb 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -372,12 +372,17 @@ module Bundler
class UpdateOptions
attr_accessor :level, :strict, :minimal
- def initialize(locked_specs)
+ def initialize(locked_specs=SpecSet.new([]), unlock_gems=[])
@level_default = :major
@level = @level_default
@strict = false
@minimal = false
@locked_specs = locked_specs
+ @unlock_gems = unlock_gems
+ end
+
+ def unlocking_gem?(gem_name)
+ @unlock_gems.empty? || @unlock_gems.include?(gem_name)
end
def level=(value)
@@ -414,7 +419,7 @@ module Bundler
def debug_format_result(dep, res)
a = [dep.to_s,
res.map { |sg| [sg.version, sg.dependencies_for_activated_platforms.map { |dp| [dp.name, dp.requirement.to_s] }] }]
- [a.first, a.last.map { |sg_data| [sg_data.first.version, sg_data.last.map { |aa| aa.join(' ') }] }]
+ [a.first, a.last.map { |sg_data| [sg_data.first.version, sg_data.last.map { |aa| aa.join(' ') }] }, @level]
end
def filter_dep_specs(specs, locked_spec)
@@ -440,6 +445,8 @@ module Bundler
end
# reminder: sort still filters anything older than locked version
+ # :major bundle update behavior can move a gem to an older version
+ # in order to satisfy the dependency tree.
def sort_dep_specs(specs, locked_spec)
return specs unless locked_spec
gem_name = locked_spec.name
@@ -450,29 +457,21 @@ module Bundler
filtered.sort do |a, b|
a_ver = a.first.version
b_ver = b.first.version
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
- new_version = gem_patch ? gem_patch.new_version : nil
case
when a_ver.segments[0] != b_ver.segments[0]
b_ver <=> a_ver
when !@level == :minor && (a_ver.segments[1] != b_ver.segments[1])
b_ver <=> a_ver
- when @minimal && !@gems_to_update.unlocking_gem?(gem_name)
+ when @minimal && !unlocking_gem?(gem_name)
b_ver <=> a_ver
- when @minimal && @gems_to_update.unlocking_gem?(gem_name) &&
- (![a_ver, b_ver].include?(locked_version) &&
- (!new_version || (new_version && a_ver >= new_version && b_ver >= new_version)))
+ when @minimal && unlocking_gem?(gem_name) &&
+ (![a_ver, b_ver].include?(locked_version)) # MODO: revisit this case
b_ver <=> a_ver
else
a_ver <=> b_ver
end
end.tap do |result|
- if @gems_to_update.unlocking_gem?(gem_name)
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
- if gem_patch && gem_patch.new_version && @minimal
- move_version_to_end(specs, gem_patch.new_version, result)
- end
- else
+ unless unlocking_gem?(gem_name)
move_version_to_end(specs, locked_version, result)
end
end
diff --git a/spec/commands/update_spec.rb b/spec/commands/update_spec.rb
index 566aaaa5f6..303f58baf5 100644
--- a/spec/commands/update_spec.rb
+++ b/spec/commands/update_spec.rb
@@ -443,7 +443,7 @@ describe "bundle update conservative" do
gem 'foo'
G
- bundle "update --patch"
+ bundle "update --patch foo", {:env => {'DEBUG_PATCH_RESOLVER' => true}}
should_be_installed "foo 1.0.1"
end