Skip to content

Commit 9711b0c

Browse files
authored
Merge pull request #3857 from austinpray/levenshtein-dym-bundler
Use DidYouMean::SpellChecker for gem suggestions in Bundler
2 parents 2ea8ebc + ab7d0fc commit 9711b0c

File tree

6 files changed

+46
-71
lines changed

6 files changed

+46
-71
lines changed

Manifest.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ bundler/lib/bundler/settings.rb
190190
bundler/lib/bundler/settings/validator.rb
191191
bundler/lib/bundler/setup.rb
192192
bundler/lib/bundler/shared_helpers.rb
193-
bundler/lib/bundler/similarity_detector.rb
194193
bundler/lib/bundler/source.rb
195194
bundler/lib/bundler/source/gemspec.rb
196195
bundler/lib/bundler/source/git.rb

bundler/lib/bundler/cli/common.rb

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,14 @@ def self.ask_for_spec_from(specs)
9494
end
9595

9696
def self.gem_not_found_message(missing_gem_name, alternatives)
97-
require_relative "../similarity_detector"
9897
message = "Could not find gem '#{missing_gem_name}'."
9998
alternate_names = alternatives.map {|a| a.respond_to?(:name) ? a.name : a }
100-
suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
101-
message += "\nDid you mean #{suggestions}?" if suggestions
99+
if alternate_names.include?(missing_gem_name.downcase)
100+
message += "\nDid you mean '#{missing_gem_name.downcase}'?"
101+
elsif defined?(DidYouMean::SpellChecker)
102+
suggestions = DidYouMean::SpellChecker.new(dictionary: alternate_names).correct(missing_gem_name)
103+
message += "\nDid you mean #{word_list(suggestions)}?" unless suggestions.empty?
104+
end
102105
message
103106
end
104107

@@ -134,5 +137,19 @@ def self.clean_after_install?
134137
clean &&= !Bundler.use_system_gems?
135138
clean
136139
end
140+
141+
def self.word_list(words)
142+
if words.empty?
143+
return ""
144+
end
145+
146+
words = words.map {|word| "'#{word}'" }
147+
148+
if words.length == 1
149+
return words[0]
150+
end
151+
152+
[words[0..-2].join(", "), words[-1]].join(" or ")
153+
end
137154
end
138155
end

bundler/lib/bundler/similarity_detector.rb

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/cli"
4+
5+
RSpec.describe Bundler::CLI::Common do
6+
describe "gem_not_found_message" do
7+
it "should suggest alternate gem names" do
8+
message = subject.gem_not_found_message("ralis", ["BOGUS"])
9+
expect(message).to match("Could not find gem 'ralis'.$")
10+
message = subject.gem_not_found_message("ralis", ["rails"])
11+
expect(message).to match("Did you mean 'rails'?")
12+
message = subject.gem_not_found_message("Rails", ["rails"])
13+
expect(message).to match("Did you mean 'rails'?")
14+
message = subject.gem_not_found_message("meail", %w[email fail eval])
15+
expect(message).to match("Did you mean 'email'?")
16+
message = subject.gem_not_found_message("nokogri", %w[nokogiri rails sidekiq dog])
17+
expect(message).to match("Did you mean 'nokogiri'?")
18+
message = subject.gem_not_found_message("methosd", %w[method methods bogus])
19+
expect(message).to match(/Did you mean 'method(|s)' or 'method(|s)'?/)
20+
end
21+
end
22+
end

bundler/spec/commands/open_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
it "suggests alternatives for similar-sounding gems" do
5151
bundle "open Rails", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
52-
expect(err).to match(/did you mean rails\?/i)
52+
expect(err).to match(/did you mean 'rails'\?/i)
5353
end
5454

5555
it "opens the gem with short words" do
@@ -80,12 +80,12 @@
8080

8181
it "suggests alternatives for similar-sounding gems when using subpath" do
8282
bundle "open Rails --path README.md", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
83-
expect(err).to match(/did you mean rails\?/i)
83+
expect(err).to match(/did you mean 'rails'\?/i)
8484
end
8585

8686
it "suggests alternatives for similar-sounding gems when using deep subpath" do
8787
bundle "open Rails --path some/path/here", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, raise_on_error: false
88-
expect(err).to match(/did you mean rails\?/i)
88+
expect(err).to match(/did you mean 'rails'\?/i)
8989
end
9090

9191
it "opens subpath of the short worded gem" do

bundler/spec/commands/update_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193
end
194194
it "should suggest alternatives" do
195195
bundle "update platformspecific", raise_on_error: false
196-
expect(err).to include "Did you mean platform_specific?"
196+
expect(err).to include "Did you mean 'platform_specific'?"
197197
end
198198
end
199199

0 commit comments

Comments
 (0)