Simplify strings for search.

This commit is contained in:
Markus Reiter 2018-06-05 10:55:00 +02:00
parent 99e3135bfa
commit 6fcc5d14de
4 changed files with 34 additions and 24 deletions

View File

@ -9,11 +9,13 @@
#: first search, making that search slower than subsequent ones. #: first search, making that search slower than subsequent ones.
require "descriptions" require "descriptions"
require "cmd/search" require "search"
module Homebrew module Homebrew
module_function module_function
extend Search
def desc def desc
search_type = [] search_type = []
search_type << :either if ARGV.flag? "--search" search_type << :either if ARGV.flag? "--search"
@ -28,8 +30,8 @@ module Homebrew
results.print results.print
elsif search_type.size > 1 elsif search_type.size > 1
odie "Pick one, and only one, of -s/--search, -n/--name, or -d/--description." odie "Pick one, and only one, of -s/--search, -n/--name, or -d/--description."
elsif arg = ARGV.named.first elsif arg = ARGV.named.join(" ")
regex = Homebrew.query_regexp(arg) regex = query_regexp(arg)
results = Descriptions.search(regex, search_type.first) results = Descriptions.search(regex, search_type.first)
results.print results.print
else else

View File

@ -1,7 +1,10 @@
require "formula" require "formula"
require "formula_versions" require "formula_versions"
require "search"
class Descriptions class Descriptions
extend Homebrew::Search
CACHE_FILE = HOMEBREW_CACHE + "desc_cache.json" CACHE_FILE = HOMEBREW_CACHE + "desc_cache.json"
def self.cache def self.cache
@ -99,11 +102,11 @@ class Descriptions
results = case field results = case field
when :name when :name
@cache.select { |name, _| name =~ regex } @cache.select { |name, _| simplify_string(name).match?(regex) }
when :desc when :desc
@cache.select { |_, desc| desc =~ regex } @cache.select { |_, desc| simplify_string(desc).match?(regex) }
when :either when :either
@cache.select { |name, desc| (name =~ regex) || (desc =~ regex) } @cache.select { |name, desc| simplify_string(name).match?(regex) || simplify_string(desc).match?(regex) }
end end
new(results) new(results)

View File

@ -1,10 +1,14 @@
module Homebrew module Homebrew
module Search module Search
def simplify_string(string)
string.downcase.gsub(/[^a-z\d]/i, "")
end
def query_regexp(query) def query_regexp(query)
if m = query.match(%r{^/(.*)/$}) if m = query.match(%r{^/(.*)/$})
Regexp.new(m[1]) Regexp.new(m[1])
else else
Regexp.new(query.chars.join('[^a-z\d]*'), Regexp::IGNORECASE) Regexp.new(simplify_string(query), Regexp::IGNORECASE)
end end
rescue RegexpError rescue RegexpError
raise "#{query} is not a valid regex." raise "#{query} is not a valid regex."
@ -48,7 +52,9 @@ module Homebrew
$stderr.puts Formatter.headline("Searching local taps...", color: :blue) $stderr.puts Formatter.headline("Searching local taps...", color: :blue)
aliases = Formula.alias_full_names aliases = Formula.alias_full_names
results = (Formula.full_names + aliases).grep(regex).sort results = (Formula.full_names + aliases)
.select { |name| simplify_string(name).match?(regex) }
.sort
results.map do |name| results.map do |name|
begin begin

View File

@ -49,32 +49,31 @@ describe Homebrew::Search do
end end
end end
describe "#simplify_string" do
it "simplifies a query with dashes" do
expect(mod.query_regexp("que-ry")).to eq(/query/i)
end
it "simplifies a query with @ symbols" do
expect(mod.query_regexp("query@1")).to eq(/query1/i)
end
end
describe "#query_regexp" do describe "#query_regexp" do
it "correctly parses a regex query" do it "correctly parses a regex query" do
expect(mod.query_regexp("/^query$/")).to eq(/^query$/) expect(mod.query_regexp("/^query$/")).to eq(/^query$/)
end end
it "correctly converts a query string to a regex" do it "correctly converts a query string to a regex" do
expect(mod.query_regexp("query")).to eq(/q[^a-z\d]*u[^a-z\d]*e[^a-z\d]*r[^a-z\d]*y/i) expect(mod.query_regexp("query")).to eq(/query/i)
end
it "simplifies a query with special symbols" do
expect(mod.query_regexp("que-ry")).to eq(/query/i)
end end
it "raises an error if the query is an invalid regex" do it "raises an error if the query is an invalid regex" do
expect { mod.query_regexp("/+/") }.to raise_error(/not a valid regex/) expect { mod.query_regexp("/+/") }.to raise_error(/not a valid regex/)
end end
it "correctly matches with special symbols" do
regex = mod.query_regexp("oo-ba")
expect(regex).to match("foo-bar")
end
it "correctly matches without special symbols" do
regex = mod.query_regexp("ooba")
expect(regex).to match("foo-bar")
end
it "keeps special symbols" do
regex = mod.query_regexp("foo-bar")
expect(regex).not_to match("foobar")
end
end end
end end