Use Searchable module.

This commit is contained in:
Markus Reiter 2018-06-05 15:39:09 +02:00
parent 46e0de1762
commit 717032d86d
7 changed files with 32 additions and 40 deletions

View File

@ -30,9 +30,10 @@ 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.join(" ") elsif !ARGV.named.empty?
regex = query_regexp(arg) arg = ARGV.named.join(" ")
results = Descriptions.search(regex, search_type.first) string_or_regex = query_regexp(arg)
results = Descriptions.search(string_or_regex, search_type.first)
results.print results.print
else else
odie "You must provide a search term." odie "You must provide a search term."

View File

@ -68,14 +68,16 @@
#: creating patches to the software. #: creating patches to the software.
require "missing_formula" require "missing_formula"
require "cmd/search"
require "formula_installer" require "formula_installer"
require "development_tools" require "development_tools"
require "install" require "install"
require "search"
module Homebrew module Homebrew
module_function module_function
extend Search
def install def install
raise FormulaUnspecifiedError if ARGV.named.empty? raise FormulaUnspecifiedError if ARGV.named.empty?
@ -261,10 +263,8 @@ module Homebrew
return return
end end
regex = query_regexp(e.name)
ohai "Searching for similarly named formulae..." ohai "Searching for similarly named formulae..."
formulae_search_results = search_formulae(regex) formulae_search_results = search_formulae(e.name)
case formulae_search_results.length case formulae_search_results.length
when 0 when 0
ofail "No similarly named formulae found." ofail "No similarly named formulae found."

View File

@ -55,9 +55,9 @@ module Homebrew
if args.remaining.empty? if args.remaining.empty?
puts Formatter.columns(Formula.full_names.sort) puts Formatter.columns(Formula.full_names.sort)
elsif args.desc? elsif args.desc?
query = args.remaining.first query = args.remaining.join(" ")
regex = query_regexp(query) string_or_regex = query_regexp(query)
Descriptions.search(regex, :desc).print Descriptions.search(string_or_regex, :desc).print
elsif args.remaining.first =~ HOMEBREW_TAP_FORMULA_REGEX elsif args.remaining.first =~ HOMEBREW_TAP_FORMULA_REGEX
query = args.remaining.first query = args.remaining.first
@ -71,9 +71,9 @@ module Homebrew
puts Formatter.columns(results) unless results.empty? puts Formatter.columns(results) unless results.empty?
else else
query = args.remaining.first query = args.remaining.join(" ")
regex = query_regexp(query) string_or_regex = query_regexp(query)
local_results = search_formulae(regex) local_results = search_formulae(string_or_regex)
puts Formatter.columns(local_results.sort) unless local_results.empty? puts Formatter.columns(local_results.sort) unless local_results.empty?
tap_results = search_taps(query).flatten.sort tap_results = search_taps(query).flatten.sort

View File

@ -1,6 +1,7 @@
require "formula" require "formula"
require "formula_versions" require "formula_versions"
require "search" require "search"
require "searchable"
class Descriptions class Descriptions
extend Homebrew::Search extend Homebrew::Search
@ -97,16 +98,18 @@ class Descriptions
end end
# Given a regex, find all formulae whose specified fields contain a match. # Given a regex, find all formulae whose specified fields contain a match.
def self.search(regex, field = :either) def self.search(string_or_regex, field = :either)
ensure_cache ensure_cache
@cache.extend(Searchable)
results = case field results = case field
when :name when :name
@cache.select { |name, _| simplify_string(name).match?(regex) } @cache.search(string_or_regex) { |name, _| name }
when :desc when :desc
@cache.select { |_, desc| simplify_string(desc).match?(regex) } @cache.search(string_or_regex) { |_, desc| desc }
when :either when :either
@cache.select { |name, desc| simplify_string(name).match?(regex) || simplify_string(desc).match?(regex) } @cache.search(string_or_regex)
end end
new(results) new(results)

View File

@ -1,14 +1,12 @@
require "searchable"
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(simplify_string(query), Regexp::IGNORECASE) query
end end
rescue RegexpError rescue RegexpError
raise "#{query} is not a valid regex." raise "#{query} is not a valid regex."
@ -47,13 +45,14 @@ module Homebrew
[[], []] [[], []]
end end
def search_formulae(regex) def search_formulae(string_or_regex)
# Use stderr to avoid breaking parsed output # Use stderr to avoid breaking parsed output
$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) results = (Formula.full_names + aliases)
.select { |name| simplify_string(name).match?(regex) } .extend(Searchable)
.search(string_or_regex)
.sort .sort
results.map do |name| results.map do |name|

View File

@ -3,6 +3,7 @@ require_relative "shared_examples/invalid_option"
describe Hbc::CLI::Search, :cask do describe Hbc::CLI::Search, :cask do
before do before do
allow(Tty).to receive(:width).and_return(0) allow(Tty).to receive(:width).and_return(0)
ENV.delete("HOMEBREW_NO_GITHUB_API")
end end
it_behaves_like "a command that handles invalid options" it_behaves_like "a command that handles invalid options"
@ -51,6 +52,8 @@ describe Hbc::CLI::Search, :cask do
end end
it "doesn't output anything to non-TTY stdout when there are no matches" do it "doesn't output anything to non-TTY stdout when there are no matches" do
allow(GitHub).to receive(:search_code).and_return([])
expect { Hbc::CLI::Search.run("foo-bar-baz") } expect { Hbc::CLI::Search.run("foo-bar-baz") }
.to not_to_output.to_stdout .to not_to_output.to_stdout
.and not_to_output.to_stderr .and not_to_output.to_stderr

View File

@ -49,27 +49,13 @@ 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 "returns the original string if it is not a regex query" do
expect(mod.query_regexp("query")).to eq(/query/i) expect(mod.query_regexp("query")).to eq("query")
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