forked from Homebrew/brew
/
search.rb
134 lines (111 loc) · 4.1 KB
/
search.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true
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}" },
opensuse: ->(query) { "https://software.opensuse.org/search?q=#{query}" },
fedora: ->(query) { "https://apps.fedoraproject.org/packages/s/#{query}" },
debian: lambda { |query|
"https://packages.debian.org/search?keywords=#{query}&searchon=names&suite=all§ion=all"
},
ubuntu: lambda { |query|
"https://packages.ubuntu.com/search?keywords=#{query}&searchon=names&suite=all§ion=all"
},
}.freeze
def search_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
`search` [<options>] [<text>|`/`<text>`/`]
Perform a substring search of cask tokens and formula names for <text>. If <text>
is flanked by slashes, it is interpreted as a regular expression.
The search for <text> is extended online to `homebrew/core` and `homebrew/cask`.
If no <text> is provided, list all locally available formulae (including tapped ones).
No online search is performed.
EOS
switch "--casks",
description: "List all locally available casks (including tapped ones). "\
"No online search is performed."
switch "--desc",
description: "Search for formulae with a description matching <text> and casks with "\
"a name matching <text>."
package_manager_switches = PACKAGE_MANAGERS.keys.map { |name| "--#{name}" }
package_manager_switches.each do |s|
switch s,
description: "Search for <text> in the given package manager's list."
end
switch :verbose
switch :debug
conflicts(*package_manager_switches)
end
end
def search
search_args.parse
if package_manager = PACKAGE_MANAGERS.find { |name,| args[:"#{name}?"] }
_, url = package_manager
exec_browser url.call(URI.encode_www_form_component(args.remaining.join(" ")))
return
end
if args.remaining.empty?
if args.casks?
puts Formatter.columns(Cask::Cask.to_a.map(&:full_name).sort)
else
puts Formatter.columns(Formula.full_names.sort)
end
return
end
query = args.remaining.join(" ")
string_or_regex = query_regexp(query)
if args.desc?
search_descriptions(string_or_regex)
else
remote_results = search_taps(query, silent: true)
local_formulae = search_formulae(string_or_regex)
remote_formulae = remote_results[:formulae]
all_formulae = local_formulae + remote_formulae
local_casks = search_casks(string_or_regex)
remote_casks = remote_results[:casks]
all_casks = local_casks + remote_casks
if all_formulae.any?
ohai "Formulae"
puts Formatter.columns(all_formulae)
end
if all_casks.any?
puts if all_formulae.any?
ohai "Casks"
puts Formatter.columns(all_casks)
end
if $stdout.tty?
count = all_formulae.count + all_casks.count
if reason = MissingFormula.reason(query, silent: true) && !local_casks.include?(query)
if count.positive?
puts
puts "If you meant #{query.inspect} specifically:"
end
puts reason
elsif count.zero?
puts "No formula or cask found for #{query.inspect}."
GitHub.print_pull_requests_matching(query)
end
end
end
return unless $stdout.tty?
return if args.remaining.empty?
metacharacters = %w[\\ | ( ) [ ] { } ^ $ * + ?].freeze
return unless metacharacters.any? do |char|
args.remaining.any? do |arg|
arg.include?(char) && !arg.start_with?("/")
end
end
opoo <<~EOS
Did you mean to perform a regular expression search?
Surround your query with /slashes/ to search locally by regex.
EOS
end
end