diff --git a/Library/Homebrew/cask/lib/hbc/cli/search.rb b/Library/Homebrew/cask/lib/hbc/cli/search.rb index 4fbecccbf6..addc35c98c 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/search.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/search.rb @@ -1,8 +1,10 @@ -require "cmd/search" +require "search" module Hbc class CLI class Search < AbstractCommand + extend Homebrew::Search + def run if args.empty? puts Formatter.columns(CLI.nice_listing(Cask.map(&:qualified_token))) @@ -34,7 +36,7 @@ module Hbc partial_matches = simplified_tokens.grep(/#{simplified_search_term}/i) { |t| all_tokens[simplified_tokens.index(t)] } end - _, remote_matches = Homebrew.search_taps(search_term, silent: true) + _, remote_matches = search_taps(search_term, silent: true) [partial_matches, remote_matches, search_term] end diff --git a/Library/Homebrew/cmd/search.rb b/Library/Homebrew/cmd/search.rb index 5ed4c201c9..4290b077e8 100644 --- a/Library/Homebrew/cmd/search.rb +++ b/Library/Homebrew/cmd/search.rb @@ -17,10 +17,13 @@ require "formula" require "missing_formula" require "descriptions" require "cli_parser" +require "search" module Homebrew module_function + extend Search + PACKAGE_MANAGERS = { macports: ->(query) { "https://www.macports.org/ports.php?by=name&substr=#{query}" }, fink: ->(query) { "http://pdb.finkproject.org/pdb/browse.php?summary=#{query}" }, @@ -106,74 +109,4 @@ module Homebrew Surround your query with /slashes/ to search locally by regex. EOS end - - def query_regexp(query) - if m = query.match(%r{^/(.*)/$}) - Regexp.new(m[1]) - else - /.*#{Regexp.escape(query)}.*/i - end - rescue RegexpError - raise "#{query} is not a valid regex." - end - - def search_taps(query, silent: false) - return [], [] if ENV["HOMEBREW_NO_GITHUB_API"] - - unless silent - # Use stderr to avoid breaking parsed output - $stderr.puts Formatter.headline("Searching taps on GitHub...", color: :blue) - end - - matches = GitHub.search_code( - user: "Homebrew", - path: ["Formula", "Casks", "."], - filename: query, - extension: "rb", - ) - - matches.inject([[], []]) do |(formulae, casks), match| - name = File.basename(match["path"], ".rb") - tap = Tap.fetch(match["repository"]["full_name"]) - full_name = "#{tap.name}/#{name}" - - if tap.installed? - [formulae, casks] - elsif match["path"].start_with?("Casks/") - [formulae, [*casks, full_name].sort] - else - [[*formulae, full_name].sort, casks] - end - end - rescue GitHub::Error => error - opoo "Error searching on GitHub: #{error}\n" - [[], []] - end - - def search_formulae(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).grep(regex).sort - - results.map do |name| - begin - formula = Formulary.factory(name) - canonical_name = formula.name - canonical_full_name = formula.full_name - rescue - canonical_name = canonical_full_name = name - end - - # Ignore aliases from results when the full name was also found - next if aliases.include?(name) && results.include?(canonical_full_name) - - if (HOMEBREW_CELLAR/canonical_name).directory? - pretty_installed(name) - else - name - end - end.compact - end end diff --git a/Library/Homebrew/search.rb b/Library/Homebrew/search.rb new file mode 100644 index 0000000000..e00826506f --- /dev/null +++ b/Library/Homebrew/search.rb @@ -0,0 +1,73 @@ +module Homebrew + module Search + def query_regexp(query) + if m = query.match(%r{^/(.*)/$}) + Regexp.new(m[1]) + else + /.*#{Regexp.escape(query)}.*/i + end + rescue RegexpError + raise "#{query} is not a valid regex." + end + + def search_taps(query, silent: false) + return [], [] if ENV["HOMEBREW_NO_GITHUB_API"] + + unless silent + # Use stderr to avoid breaking parsed output + $stderr.puts Formatter.headline("Searching taps on GitHub...", color: :blue) + end + + matches = GitHub.search_code( + user: "Homebrew", + path: ["Formula", "Casks", "."], + filename: query, + extension: "rb", + ) + + matches.inject([[], []]) do |(formulae, casks), match| + name = File.basename(match["path"], ".rb") + tap = Tap.fetch(match["repository"]["full_name"]) + full_name = "#{tap.name}/#{name}" + + if tap.installed? + [formulae, casks] + elsif match["path"].start_with?("Casks/") + [formulae, [*casks, full_name].sort] + else + [[*formulae, full_name].sort, casks] + end + end + rescue GitHub::Error => error + opoo "Error searching on GitHub: #{error}\n" + [[], []] + end + + def search_formulae(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).grep(regex).sort + + results.map do |name| + begin + formula = Formulary.factory(name) + canonical_name = formula.name + canonical_full_name = formula.full_name + rescue + canonical_name = canonical_full_name = name + end + + # Ignore aliases from results when the full name was also found + next if aliases.include?(name) && results.include?(canonical_full_name) + + if (HOMEBREW_CELLAR/canonical_name).directory? + pretty_installed(name) + else + name + end + end.compact + end + end +end diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb index 9e77fc6b61..556c863ca2 100644 --- a/Library/Homebrew/test/cmd/search_spec.rb +++ b/Library/Homebrew/test/cmd/search_spec.rb @@ -65,18 +65,4 @@ describe "brew search", :integration_test do .and be_a_success end end - - describe "::query_regexp" do - it "correctly parses a regex query" do - expect(Homebrew.query_regexp("/^query$/")).to eq(/^query$/) - end - - it "correctly converts a query string to a regex" do - expect(Homebrew.query_regexp("query")).to eq(/.*query.*/i) - end - - it "raises an error if the query is an invalid regex" do - expect { Homebrew.query_regexp("/+/") }.to raise_error(/not a valid regex/) - end - end end diff --git a/Library/Homebrew/test/cmd/search_remote_tap_spec.rb b/Library/Homebrew/test/search_spec.rb similarity index 58% rename from Library/Homebrew/test/cmd/search_remote_tap_spec.rb rename to Library/Homebrew/test/search_spec.rb index 41acc5a690..26236af472 100644 --- a/Library/Homebrew/test/cmd/search_remote_tap_spec.rb +++ b/Library/Homebrew/test/search_spec.rb @@ -1,6 +1,12 @@ -require "cmd/search" +require "search" + +describe Homebrew::Search do + subject(:mod) { Object.new } + + before do + mod.extend(described_class) + end -describe Homebrew do describe "#search_taps" do before do ENV.delete("HOMEBREW_NO_GITHUB_API") @@ -8,13 +14,13 @@ describe Homebrew do it "does not raise if `HOMEBREW_NO_GITHUB_API` is set" do ENV["HOMEBREW_NO_GITHUB_API"] = "1" - expect(described_class.search_taps("some-formula")).to match([[], []]) + expect(mod.search_taps("some-formula")).to match([[], []]) end it "does not raise if the network fails" do allow(GitHub).to receive(:open_api).and_raise(GitHub::Error) - expect(described_class.search_taps("some-formula")) + expect(mod.search_taps("some-formula")) .to match([[], []]) end @@ -38,8 +44,22 @@ describe Homebrew do allow(GitHub).to receive(:open_api).and_yield(json_response) - expect(described_class.search_taps("some-formula")) + expect(mod.search_taps("some-formula")) .to match([["homebrew/foo/some-formula"], ["homebrew/bar/some-cask"]]) 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 "raises an error if the query is an invalid regex" do + expect { mod.query_regexp("/+/") }.to raise_error(/not a valid regex/) + end + end end