Skip to content

Commit

Permalink
Merge pull request #13033 from EricFromCanada/cask-search-descriptions
Browse files Browse the repository at this point in the history
desc, search: also search cask descriptions
  • Loading branch information
EricFromCanada authored Mar 30, 2022
2 parents b2f3081 + 2fdc70c commit b533b38
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 34 deletions.
38 changes: 29 additions & 9 deletions Library/Homebrew/cmd/desc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ def desc_args
switch "-d", "--description",
description: "Search just descriptions for <text>. If <text> is flanked by slashes, "\
"it is interpreted as a regular expression."
switch "--formula", "--formulae",
description: "Treat all named arguments as formulae."
switch "--cask", "--casks",
description: "Treat all named arguments as casks."

conflicts "--search", "--name", "--description"

named_args [:formula, :text_or_regex], min: 1
named_args [:formula, :cask, :text_or_regex], min: 1
end
end

Expand All @@ -48,19 +52,35 @@ def desc
:desc
end

results = if search_type.nil?
if search_type.blank?
desc = {}
args.named.to_formulae.each { |f| desc[f.full_name] = f.desc }
Descriptions.new(desc)
args.named.to_formulae_and_casks.each do |formula_or_cask|
if formula_or_cask.is_a? Formula
desc[formula_or_cask.full_name] = formula_or_cask.desc
else
description = formula_or_cask.desc.presence || Formatter.warning("[no description]")
desc[formula_or_cask.full_name] = "(#{formula_or_cask.name.join(", ")}) #{description}"
end
end
Descriptions.new(desc).print
else
query = args.named.join(" ")
string_or_regex = query_regexp(query)
CacheStoreDatabase.use(:descriptions) do |db|
cache_store = DescriptionCacheStore.new(db)
Descriptions.search(string_or_regex, search_type, cache_store)
unless args.cask?
ohai "Formulae"
CacheStoreDatabase.use(:descriptions) do |db|
cache_store = DescriptionCacheStore.new(db)
Descriptions.search(string_or_regex, search_type, cache_store).print
end
end
unless args.formula?
puts unless args.cask?
ohai "Casks"
CacheStoreDatabase.use(:cask_descriptions) do |db|
cache_store = CaskDescriptionCacheStore.new(db)
Descriptions.search(string_or_regex, search_type, cache_store).print
end
end
end

results.print
end
end
2 changes: 1 addition & 1 deletion Library/Homebrew/cmd/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def search_args
description: "Search online and locally for casks."
switch "--desc",
description: "Search for formulae with a description matching <text> and casks with "\
"a name matching <text>."
"a name or description matching <text>."
switch "--pull-request",
description: "Search for GitHub pull requests containing <text>."
switch "--open",
Expand Down
4 changes: 4 additions & 0 deletions Library/Homebrew/cmd/update-report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ def output_update_report
DescriptionCacheStore.new(db)
.update_from_report!(hub)
end
CacheStoreDatabase.use(:cask_descriptions) do |db|
CaskDescriptionCacheStore.new(db)
.update_from_report!(hub)
end

if !args.preinstall? && !args.quiet?
outdated_formulae = Formula.installed.count(&:outdated?)
Expand Down
51 changes: 49 additions & 2 deletions Library/Homebrew/description_cache_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
require "searchable"

#
# {DescriptionCacheStore} provides methods to fetch and mutate linkage-specific data used
# by the `brew linkage` command.
# {DescriptionCacheStore} provides methods to fetch and mutate formula descriptions used
# by the `brew desc` and `brew search` commands.
#
class DescriptionCacheStore < CacheStore
include Searchable
Expand Down Expand Up @@ -81,6 +81,7 @@ def delete_from_formula_names!(formula_names)

formula_names.each(&method(:delete!))
end
alias delete_from_cask_tokens! delete_from_formula_names!

private

Expand All @@ -89,3 +90,49 @@ def select(&block)
database.select(&block)
end
end

#
# {CaskDescriptionCacheStore} provides methods to fetch and mutate cask descriptions used
# by the `brew desc` and `brew search` commands.
#
class CaskDescriptionCacheStore < DescriptionCacheStore
# If the database is empty `update!` it with all known casks.
#
# @return [nil]
def populate_if_empty!
return unless database.empty?

# TODO: 3.6.0: consider if we want to actually read all contents of all casks or odeprecate.
Cask::Cask.all.each { |c| update!(c.full_name, [c.name.join(", "), c.desc.presence]) }
end

# Use an update report to update the {CaskDescriptionCacheStore}.
#
# @param report [Report] an update report generated by cmd/update.rb
# @return [nil]
def update_from_report!(report)
return populate_if_empty! if database.empty?
return if report.empty?

alterations = report.select_formula(:AC) +
report.select_formula(:MC)

update_from_cask_tokens!(alterations)
delete_from_cask_tokens!(report.select_formula(:DC))
end

# Use an array of cask tokens to update the {CaskDescriptionCacheStore}.
#
# @param cask_tokens [Array] the casks to update
# @return [nil]
def update_from_cask_tokens!(cask_tokens)
return populate_if_empty! if database.empty?

cask_tokens.each do |token|
c = Cask::CaskLoader.load(token)
update!(c.full_name, [c.name.join(", "), c.desc.presence])
rescue Cask::CaskUnavailableError, *FormulaVersions::IGNORED_EXCEPTIONS
delete!(c.full_name) if c.present?
end
end
end
8 changes: 7 additions & 1 deletion Library/Homebrew/descriptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ def print
full_name
end
description = @descriptions[full_name] || blank
puts "#{Tty.bold}#{printed_name}:#{Tty.reset} #{description}"
if description.is_a?(Array)
names = description[0]
description = description[1] || blank
puts "#{Tty.bold}#{printed_name}:#{Tty.reset} (#{names}) #{description}"
else
puts "#{Tty.bold}#{printed_name}:#{Tty.reset} #{description}"
end
end
end

Expand Down
14 changes: 6 additions & 8 deletions Library/Homebrew/extend/os/mac/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ module Extension
def search_descriptions(string_or_regex, args)
super

puts

return if args.formula?

puts unless args.cask?
ohai "Casks"
Cask::Cask.all.extend(Searchable)
.search(string_or_regex, &:name)
.each do |cask|
puts "#{Tty.bold}#{cask.token}:#{Tty.reset} #{cask.name.join(", ")}"
CacheStoreDatabase.use(:cask_descriptions) do |db|
cache_store = CaskDescriptionCacheStore.new(db)
Descriptions.search(string_or_regex, :desc, cache_store).print
end
end

Expand All @@ -42,9 +40,9 @@ def search_casks(string_or_regex)
results.sort.map do |name|
cask = Cask::CaskLoader.load(name)
if cask.installed?
pretty_installed(cask.token)
pretty_installed(cask.full_name)
else
cask.token
cask.full_name
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1759,7 +1759,7 @@ def self.aliases
@aliases ||= (core_aliases + tap_aliases.map { |name| name.split("/").last }).uniq.sort
end

# an array of all aliases, , which the tap formulae have the fully-qualified name
# an array of all aliases as fully-qualified names
# @private
def self.alias_full_names
@alias_full_names ||= core_aliases + tap_aliases
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def search_formulae(string_or_regex)
.search(string_or_regex)
.sort

results |= Formula.fuzzy_search(string_or_regex)
results |= Formula.fuzzy_search(string_or_regex).map { |n| Formulary.factory(n).full_name }

results.map do |name|
formula, canonical_full_name = begin
Expand Down
2 changes: 1 addition & 1 deletion Library/Homebrew/searchable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def search_string(string)
simplified_string = simplify_string(string)
select do |*args|
args = yield(*args) if block_given?
args = Array(args).compact
args = Array(args).flatten.compact
args.any? { |arg| simplify_string(arg).include?(simplified_string) }
end
end
Expand Down
8 changes: 8 additions & 0 deletions Library/Homebrew/tap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ def install(quiet: false, clone_target: nil, force_auto_update: nil, custom_remo
DescriptionCacheStore.new(db)
.update_from_formula_names!(formula_names)
end
CacheStoreDatabase.use(:cask_descriptions) do |db|
CaskDescriptionCacheStore.new(db)
.update_from_cask_tokens!(cask_tokens)
end

if official?
untapped = self.class.untapped_official_taps
Expand Down Expand Up @@ -411,6 +415,10 @@ def uninstall(manual: false)
DescriptionCacheStore.new(db)
.delete_from_formula_names!(formula_names)
end
CacheStoreDatabase.use(:cask_descriptions) do |db|
CaskDescriptionCacheStore.new(db)
.delete_from_cask_tokens!(cask_tokens)
end
Utils::Link.unlink_manpages(path)
Utils::Link.unlink_completions(path)
path.rmtree
Expand Down
30 changes: 30 additions & 0 deletions Library/Homebrew/test/description_cache_store_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,34 @@
cache_store.delete_from_formula_names!([formula_name])
end
end

describe CaskDescriptionCacheStore do
subject(:cache_store) { described_class.new(database) }

let(:database) { double("database") }

describe "#update_from_report!" do
let(:report) { double(select_formula: [], empty?: false) }

it "reads from the report" do
expect(database).to receive(:empty?).at_least(:once).and_return(false)
cache_store.update_from_report!(report)
end
end

describe "#update_from_cask_tokens!" do
it "sets the cask descriptions" do
c = Cask::Cask.new("cask-names-desc") do
url "url-1"
name "Name 1"
name "Name 2"
desc "description"
end
expect(Cask::CaskLoader).to receive(:load).with("cask-names-desc", any_args).and_return(c)
expect(database).to receive(:empty?).and_return(false)
expect(database).to receive(:set).with(c.full_name, [c.name.join(", "), c.desc.presence])
cache_store.update_from_cask_tokens!([c.token])
end
end
end
end
5 changes: 5 additions & 0 deletions Library/Homebrew/test/descriptions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@
EOS
).to_stdout
end

it "can print description for a cask" do
descriptions_hash["homebrew/cask/foo"] = ["Foo", "Cask foo"]
expect { descriptions.print }.to output("foo: (Foo) Cask foo\n").to_stdout
end
end
3 changes: 3 additions & 0 deletions completions/bash/brew
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,10 @@ _brew_desc() {
case "${cur}" in
-*)
__brewcomp "
--cask
--debug
--description
--formula
--help
--name
--quiet
Expand All @@ -754,6 +756,7 @@ _brew_desc() {
*)
esac
__brew_complete_formulae
__brew_complete_casks
}

_brew_developer() {
Expand Down
9 changes: 6 additions & 3 deletions completions/fish/brew.fish
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ __fish_brew_complete_arg '-S' -l cask -d 'Search online and locally for casks'
__fish_brew_complete_arg '-S' -l closed -d 'Search for only closed GitHub pull requests'
__fish_brew_complete_arg '-S' -l debian -d 'Search for text in the given database'
__fish_brew_complete_arg '-S' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg '-S' -l desc -d 'Search for formulae with a description matching text and casks with a name matching text'
__fish_brew_complete_arg '-S' -l desc -d 'Search for formulae with a description matching text and casks with a name or description matching text'
__fish_brew_complete_arg '-S' -l fedora -d 'Search for text in the given database'
__fish_brew_complete_arg '-S' -l fink -d 'Search for text in the given database'
__fish_brew_complete_arg '-S' -l formula -d 'Search online and locally for formulae'
Expand Down Expand Up @@ -578,14 +578,17 @@ __fish_brew_complete_arg 'deps; and not __fish_seen_argument -l formula -l formu


__fish_brew_complete_cmd 'desc' 'Display formula\'s name and one-line description'
__fish_brew_complete_arg 'desc' -l cask -d 'Treat all named arguments as casks'
__fish_brew_complete_arg 'desc' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'desc' -l description -d 'Search just descriptions for text. If text is flanked by slashes, it is interpreted as a regular expression'
__fish_brew_complete_arg 'desc' -l formula -d 'Treat all named arguments as formulae'
__fish_brew_complete_arg 'desc' -l help -d 'Show this message'
__fish_brew_complete_arg 'desc' -l name -d 'Search just names for text. If text is flanked by slashes, it is interpreted as a regular expression'
__fish_brew_complete_arg 'desc' -l quiet -d 'Make some output more quiet'
__fish_brew_complete_arg 'desc' -l search -d 'Search both names and descriptions for text. If text is flanked by slashes, it is interpreted as a regular expression'
__fish_brew_complete_arg 'desc' -l verbose -d 'Make some output more verbose'
__fish_brew_complete_arg 'desc' -a '(__fish_brew_suggest_formulae_all)'
__fish_brew_complete_arg 'desc; and not __fish_seen_argument -l cask -l casks' -a '(__fish_brew_suggest_formulae_all)'
__fish_brew_complete_arg 'desc; and not __fish_seen_argument -l formula -l formulae' -a '(__fish_brew_suggest_casks_all)'


__fish_brew_complete_cmd 'developer' 'Control Homebrew\'s developer mode'
Expand Down Expand Up @@ -1240,7 +1243,7 @@ __fish_brew_complete_arg 'search' -l cask -d 'Search online and locally for cask
__fish_brew_complete_arg 'search' -l closed -d 'Search for only closed GitHub pull requests'
__fish_brew_complete_arg 'search' -l debian -d 'Search for text in the given database'
__fish_brew_complete_arg 'search' -l debug -d 'Display any debugging information'
__fish_brew_complete_arg 'search' -l desc -d 'Search for formulae with a description matching text and casks with a name matching text'
__fish_brew_complete_arg 'search' -l desc -d 'Search for formulae with a description matching text and casks with a name or description matching text'
__fish_brew_complete_arg 'search' -l fedora -d 'Search for text in the given database'
__fish_brew_complete_arg 'search' -l fink -d 'Search for text in the given database'
__fish_brew_complete_arg 'search' -l formula -d 'Search online and locally for formulae'
Expand Down
10 changes: 7 additions & 3 deletions completions/zsh/_brew
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ _brew__s() {
'(--open)--closed[Search for only closed GitHub pull requests]' \
'(--repology --macports --fink --opensuse --fedora --archlinux --ubuntu)--debian[Search for text in the given database]' \
'--debug[Display any debugging information]' \
'(--pull-request)--desc[Search for formulae with a description matching text and casks with a name matching text]' \
'(--pull-request)--desc[Search for formulae with a description matching text and casks with a name or description matching text]' \
'(--repology --macports --fink --opensuse --archlinux --debian --ubuntu)--fedora[Search for text in the given database]' \
'(--repology --macports --opensuse --fedora --archlinux --debian --ubuntu)--fink[Search for text in the given database]' \
'--formula[Search online and locally for formulae]' \
Expand Down Expand Up @@ -717,7 +717,11 @@ _brew_desc() {
'(--name --description)--search[Search both names and descriptions for text. If text is flanked by slashes, it is interpreted as a regular expression]' \
'--verbose[Make some output more verbose]' \
- formula \
'*::formula:__brew_formulae'
'--formula[Treat all named arguments as formulae]' \
'*::formula:__brew_formulae' \
- cask \
'--cask[Treat all named arguments as casks]' \
'*::cask:__brew_casks'
}

# brew developer
Expand Down Expand Up @@ -1513,7 +1517,7 @@ _brew_search() {
'(--open)--closed[Search for only closed GitHub pull requests]' \
'(--repology --macports --fink --opensuse --fedora --archlinux --ubuntu)--debian[Search for text in the given database]' \
'--debug[Display any debugging information]' \
'(--pull-request)--desc[Search for formulae with a description matching text and casks with a name matching text]' \
'(--pull-request)--desc[Search for formulae with a description matching text and casks with a name or description matching text]' \
'(--repology --macports --fink --opensuse --archlinux --debian --ubuntu)--fedora[Search for text in the given database]' \
'(--repology --macports --opensuse --fedora --archlinux --debian --ubuntu)--fink[Search for text in the given database]' \
'--formula[Search online and locally for formulae]' \
Expand Down
Loading

0 comments on commit b533b38

Please sign in to comment.