diff --git a/Library/Homebrew/cmd/desc.rb b/Library/Homebrew/cmd/desc.rb index b704d08b85..1a75371a02 100644 --- a/Library/Homebrew/cmd/desc.rb +++ b/Library/Homebrew/cmd/desc.rb @@ -30,9 +30,10 @@ module Homebrew results.print elsif search_type.size > 1 odie "Pick one, and only one, of -s/--search, -n/--name, or -d/--description." - elsif arg = ARGV.named.join(" ") - regex = query_regexp(arg) - results = Descriptions.search(regex, search_type.first) + elsif !ARGV.named.empty? + arg = ARGV.named.join(" ") + string_or_regex = query_regexp(arg) + results = Descriptions.search(string_or_regex, search_type.first) results.print else odie "You must provide a search term." diff --git a/Library/Homebrew/cmd/install.rb b/Library/Homebrew/cmd/install.rb index 4b699474e1..5d2385b74d 100644 --- a/Library/Homebrew/cmd/install.rb +++ b/Library/Homebrew/cmd/install.rb @@ -68,14 +68,16 @@ #: creating patches to the software. require "missing_formula" -require "cmd/search" require "formula_installer" require "development_tools" require "install" +require "search" module Homebrew module_function + extend Search + def install raise FormulaUnspecifiedError if ARGV.named.empty? @@ -261,10 +263,8 @@ module Homebrew return end - regex = query_regexp(e.name) - ohai "Searching for similarly named formulae..." - formulae_search_results = search_formulae(regex) + formulae_search_results = search_formulae(e.name) case formulae_search_results.length when 0 ofail "No similarly named formulae found." diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb index 4290b077e8..6d8ffe169c 100644 --- a/Library/Homebrew/cmd/search.rb +++ b/Library/Homebrew/cmd/search.rb @@ -55,9 +55,9 @@ module Homebrew if args.remaining.empty? puts Formatter.columns(Formula.full_names.sort) elsif args.desc? - query = args.remaining.first - regex = query_regexp(query) - Descriptions.search(regex, :desc).print + query = args.remaining.join(" ") + string_or_regex = query_regexp(query) + Descriptions.search(string_or_regex, :desc).print elsif args.remaining.first =~ HOMEBREW_TAP_FORMULA_REGEX query = args.remaining.first @@ -71,9 +71,9 @@ module Homebrew puts Formatter.columns(results) unless results.empty? else - query = args.remaining.first - regex = query_regexp(query) - local_results = search_formulae(regex) + query = args.remaining.join(" ") + string_or_regex = query_regexp(query) + local_results = search_formulae(string_or_regex) puts Formatter.columns(local_results.sort) unless local_results.empty? tap_results = search_taps(query).flatten.sort diff --git a/Library/Homebrew/descriptions.rb b/Library/Homebrew/descriptions.rb index 9d7c16b636..b14833e3d0 100644 --- a/Library/Homebrew/descriptions.rb +++ b/Library/Homebrew/descriptions.rb @@ -1,6 +1,7 @@ require "formula" require "formula_versions" require "search" +require "searchable" class Descriptions extend Homebrew::Search @@ -97,16 +98,18 @@ class Descriptions end # 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 + @cache.extend(Searchable) + results = case field when :name - @cache.select { |name, _| simplify_string(name).match?(regex) } + @cache.search(string_or_regex) { |name, _| name } when :desc - @cache.select { |_, desc| simplify_string(desc).match?(regex) } + @cache.search(string_or_regex) { |_, desc| desc } when :either - @cache.select { |name, desc| simplify_string(name).match?(regex) || simplify_string(desc).match?(regex) } + @cache.search(string_or_regex) end new(results) diff --git a/Library/Homebrew/search.rb b/Library/Homebrew/search.rb index c94a5a61f8..6b97e1ad87 100644 --- a/Library/Homebrew/search.rb +++ b/Library/Homebrew/search.rb @@ -1,14 +1,12 @@ +require "searchable" + module Homebrew module Search - def simplify_string(string) - string.downcase.gsub(/[^a-z\d]/i, "") - end - def query_regexp(query) if m = query.match(%r{^/(.*)/$}) Regexp.new(m[1]) else - Regexp.new(simplify_string(query), Regexp::IGNORECASE) + query end rescue RegexpError raise "#{query} is not a valid regex." @@ -47,13 +45,14 @@ module Homebrew [[], []] end - def search_formulae(regex) + def search_formulae(string_or_regex) # Use stderr to avoid breaking parsed output $stderr.puts Formatter.headline("Searching local taps...", color: :blue) aliases = Formula.alias_full_names results = (Formula.full_names + aliases) - .select { |name| simplify_string(name).match?(regex) } + .extend(Searchable) + .search(string_or_regex) .sort results.map do |name| diff --git a/Library/Homebrew/test/cask/cli/search_spec.rb b/Library/Homebrew/test/cask/cli/search_spec.rb index 5500500b81..57e1206a0f 100644 --- a/Library/Homebrew/test/cask/cli/search_spec.rb +++ b/Library/Homebrew/test/cask/cli/search_spec.rb @@ -3,6 +3,7 @@ require_relative "shared_examples/invalid_option" describe Hbc::CLI::Search, :cask do before do allow(Tty).to receive(:width).and_return(0) + ENV.delete("HOMEBREW_NO_GITHUB_API") end it_behaves_like "a command that handles invalid options" @@ -51,6 +52,8 @@ describe Hbc::CLI::Search, :cask do end 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") } .to not_to_output.to_stdout .and not_to_output.to_stderr diff --git a/Library/Homebrew/test/search_spec.rb b/Library/Homebrew/test/search_spec.rb index 222ace3080..b64c4151b6 100644 --- a/Library/Homebrew/test/search_spec.rb +++ b/Library/Homebrew/test/search_spec.rb @@ -49,27 +49,13 @@ describe Homebrew::Search do 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 it "correctly parses a regex query" do expect(mod.query_regexp("/^query$/")).to eq(/^query$/) end - it "correctly converts a query string to a regex" do - 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) + it "returns the original string if it is not a regex query" do + expect(mod.query_regexp("query")).to eq("query") end it "raises an error if the query is an invalid regex" do