Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions lib/rubygems.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,10 +268,17 @@ def self.find_spec_for_exe(name, exec_name, requirements)

return loaded if loaded && dep.matches_spec?(loaded)

spec = dep.spec_for_exe(exec_name)
specs = dep.matching_specs(true)

unless spec
specs = specs.find_all do |spec|
spec.executables.include? exec_name
end if exec_name

unless spec = specs.first
msg = "can't find gem #{dep} with executable #{exec_name}"
if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
msg = bundler_message
end
raise Gem::GemNotFoundException, msg
end

Expand Down
7 changes: 3 additions & 4 deletions lib/rubygems/bundler_version_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ def self.compatible?(spec)
spec.version.segments.first == bundler_version.segments.first
end

def self.prioritize!(specs)
match_index = specs.find_index { |spec| compatible?(spec) }
return unless match_index
def self.filter!(specs)
return unless bundler_version = self.bundler_version

specs.unshift(specs.delete_at(match_index))
specs.reject! { |spec| spec.version.segments.first != bundler_version.segments.first }
end

def self.bundle_update_bundler_version
Expand Down
35 changes: 6 additions & 29 deletions lib/rubygems/dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def matching_specs(platform_only = false)
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
end.map(&:to_spec)

Gem::BundlerVersionFinder.prioritize!(matches) if name == "bundler".freeze
Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze

if platform_only
matches.reject! do |spec|
Expand Down Expand Up @@ -325,36 +325,13 @@ def to_spec
active = matches.find { |spec| spec.activated? }
return active if active

unless prerelease?
# Move prereleases to the end of the list for >= 0 requirements
pre, matches = matches.partition { |spec| spec.version.prerelease? }
matches += pre if requirement == Gem::Requirement.default
end

select_first(matches)
end

def spec_for_exe(exec_name)
matches = matching_specs(true)

matches = matches.find_all do |spec|
spec.executables.include? exec_name
end if exec_name
return matches.first if prerelease?

select_first(matches)
end

private

def select_first(matches)
spec = matches.first
return unless spec

if !Gem::BundlerVersionFinder.compatible?(spec)
warn Gem::BundlerVersionFinder.missing_version_message
end
# Move prereleases to the end of the list for >= 0 requirements
pre, matches = matches.partition { |spec| spec.version.prerelease? }
matches += pre if requirement == Gem::Requirement.default

spec
matches.first
end

end
3 changes: 3 additions & 0 deletions lib/rubygems/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ def initialize(name, requirement, specs)
private

def build_message
if name == "bundler" && message = Gem::BundlerVersionFinder.missing_version_message
return message
end
names = specs.map(&:full_name)
"Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n"
end
Expand Down
10 changes: 5 additions & 5 deletions test/rubygems/test_gem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,14 @@ def test_activate_bin_path_gives_proper_error_for_bundler

File.open("Gemfile", "w") { |f| f.puts('source "https://rubygems.org"') }

_, err = capture_io do
e = assert_raises Gem::GemNotFoundException do
load Gem.activate_bin_path("bundler", "bundle", ">= 0.a")
end

assert_includes err, "Could not find 'bundler' (9999) required by your #{File.expand_path("Gemfile.lock")}."
assert_includes err, "To update to the latest version installed on your system, run `bundle update --bundler`."
assert_includes err, "To install the missing version, run `gem install bundler:9999`"
refute_includes err, "can't find gem bundler (>= 0.a) with executable bundle"
assert_includes e.message, "Could not find 'bundler' (9999) required by your #{File.expand_path("Gemfile.lock")}."
assert_includes e.message, "To update to the latest version installed on your system, run `bundle update --bundler`."
assert_includes e.message, "To install the missing version, run `gem install bundler:9999`"
refute_includes e.message, "can't find gem bundler (>= 0.a) with executable bundle"
end

def test_self_bin_path_no_exec_name
Expand Down
20 changes: 10 additions & 10 deletions test/rubygems/test_gem_bundler_version_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,33 +100,33 @@ def test_compatible
end
end

def test_prioritize
def test_filter
versions = %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1]
specs = versions.map { |v| util_spec("bundler", v) }

assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)

bvf.stub(:bundler_version, v("2.1.1.1")) do
assert_equal %w[2 1 1.0 1.0.1.1 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[2 2.a 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
end
bvf.stub(:bundler_version, v("1.1.1.1")) do
assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
end
bvf.stub(:bundler_version, v("1")) do
assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
end
bvf.stub(:bundler_version, v("2.a")) do
assert_equal %w[2 1 1.0 1.0.1.1 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[2 2.a 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
end
bvf.stub(:bundler_version, v("3")) do
assert_equal %w[3 1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3.a 3.0 3.1.1], util_prioritize_specs(specs)
assert_equal %w[3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s)
end
end

def util_prioritize_specs(specs)
def util_filter_specs(specs)
specs = specs.dup
bvf.prioritize!(specs)
specs.map(&:version).map(&:to_s)
bvf.filter!(specs)
specs
end

end
10 changes: 7 additions & 3 deletions test/rubygems/test_gem_dependency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,16 @@ def test_to_specs_respects_bundler_version

assert_equal [b, b_1], dep.to_specs

Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1.16", "reason"]) do
assert_equal [b_1, b], dep.to_specs
Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["3.5", "reason"]) do
e = assert_raises Gem::MissingSpecVersionError do
dep.to_specs
end

assert_match "Could not find 'bundler' (3.5) required by reason.\nTo update to the latest version installed on your system, run `bundle update --bundler`.\nTo install the missing version, run `gem install bundler:3.5`\n", e.message
end

Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["2.0.0.pre.1", "reason"]) do
assert_equal [b, b_1], dep.to_specs
assert_equal [b], dep.to_specs
end
end

Expand Down
4 changes: 2 additions & 2 deletions test/rubygems/test_kernel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ def test_gem_bundler_missing_bundler_version
quick_gem 'bundler', '1'
quick_gem 'bundler', '2.a'

_, e = capture_io do
e = assert_raises Gem::MissingSpecVersionError do
gem('bundler')
end
assert_match "Could not find 'bundler' (55) required by reason.", e
assert_match "Could not find 'bundler' (55) required by reason.", e.message
end
end

Expand Down
4 changes: 2 additions & 2 deletions test/rubygems/test_require.rb
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,10 @@ def test_require_bundler_missing_bundler_version
b2a = util_spec('bundler', '2.a', nil, "lib/bundler/setup.rb")
install_specs b1, b2a

_, e = capture_io do
e = assert_raises Gem::MissingSpecVersionError do
gem('bundler')
end
assert_match "Could not find 'bundler' (55) required by reason.", e
assert_match "Could not find 'bundler' (55) required by reason.", e.message
end
end

Expand Down