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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
require 'formula'
require 'blacklist'
require 'utils'
require 'thread'
module Homebrew
SEARCH_ERROR_QUEUE = Queue.new
def search
if ARGV.include? '--macports'
exec_browser "https://www.macports.org/ports.php?by=name&substr=#{ARGV.next}"
elsif ARGV.include? '--fink'
exec_browser "http://pdb.finkproject.org/pdb/browse.php?summary=#{ARGV.next}"
elsif ARGV.include? '--debian'
exec_browser "https://packages.debian.org/search?keywords=#{ARGV.next}&searchon=names&suite=all§ion=all"
elsif ARGV.include? '--opensuse'
exec_browser "https://software.opensuse.org/search?q=#{ARGV.next}"
elsif ARGV.include? '--fedora'
exec_browser "https://admin.fedoraproject.org/pkgdb/packages/%2A#{ARGV.next}%2A/"
elsif ARGV.include? '--ubuntu'
exec_browser "http://packages.ubuntu.com/search?keywords=#{ARGV.next}&searchon=names&suite=all§ion=all"
elsif ARGV.empty?
puts_columns Formula.names
elsif ARGV.first =~ HOMEBREW_TAP_FORMULA_REGEX
query = ARGV.first
user, repo, name = query.split("/", 3)
begin
result = Formulary.factory(query).name
rescue FormulaUnavailableError
result = search_tap(user, repo, name)
end
puts_columns Array(result)
else
query = ARGV.first
rx = query_regexp(query)
local_results = search_formulae(rx)
puts_columns(local_results)
if not query.empty? and $stdout.tty? and msg = blacklisted?(query)
unless local_results.empty?
puts
puts "If you meant #{query.inspect} precisely:"
puts
end
puts msg
end
tap_results = search_taps(rx)
puts_columns(tap_results)
count = local_results.length + tap_results.length
if count == 0 and not blacklisted? query
puts "No formula found for #{query.inspect}."
begin
GitHub.print_pull_requests_matching(query)
rescue GitHub::Error => e
SEARCH_ERROR_QUEUE << e
end
end
end
metacharacters = %w[\\ | ( ) [ ] { } ^ $ * + ? .]
bad_regex = metacharacters.any? do |char|
ARGV.any? do |arg|
arg.include?(char) && !arg.start_with?('/')
end
end
if ARGV.any? && bad_regex
ohai "Did you mean to perform a regular expression search?"
ohai "Surround your query with /slashes/ to search by regex."
end
raise SEARCH_ERROR_QUEUE.pop unless SEARCH_ERROR_QUEUE.empty?
end
SEARCHABLE_TAPS = [
%w{Homebrew nginx},
%w{Homebrew apache},
%w{Homebrew versions},
%w{Homebrew dupes},
%w{Homebrew games},
%w{Homebrew science},
%w{Homebrew completions},
%w{Homebrew binary},
%w{Homebrew python},
%w{Homebrew php},
%w{Homebrew tex},
%w{Homebrew x11},
%w{Caskroom cask},
]
def query_regexp(query)
case query
when %r{^/(.*)/$} then Regexp.new($1)
else /.*#{Regexp.escape(query)}.*/i
end
end
def search_taps(rx)
SEARCHABLE_TAPS.map do |user, repo|
Thread.new { search_tap(user, repo, rx) }
end.inject([]) do |results, t|
results.concat(t.value)
end
end
def search_tap user, repo, rx
if (HOMEBREW_LIBRARY/"Taps/#{user.downcase}/homebrew-#{repo.downcase}").directory? && \
"#{user}/#{repo}" != "Caskroom/cask"
return []
end
results = []
tree = {}
GitHub.open "https://api.github.com/repos/#{user}/homebrew-#{repo}/git/trees/HEAD?recursive=1" do |json|
user = user.downcase if user == "Homebrew" # special handling for the Homebrew organization
json["tree"].each do |object|
next unless object["type"] == "blob"
subtree, file = File.split(object["path"])
if File.extname(file) == ".rb"
tree[subtree] ||= []
tree[subtree] << file
end
end
end
paths = tree["Formula"] || tree["HomebrewFormula"] || tree["Casks"] || tree["."] || []
paths.each do |path|
name = File.basename(path, ".rb")
results << "#{user}/#{repo}/#{name}" if rx === name
end
rescue GitHub::HTTPNotFoundError => e
opoo "Failed to search tap: #{user}/#{repo}. Please run `brew update`"
[]
rescue GitHub::Error => e
SEARCH_ERROR_QUEUE << e
[]
else
results
end
def search_formulae rx
aliases = Formula.aliases
results = (Formula.names+aliases).grep(rx).sort
# Filter out aliases when the full name was also found
results.reject do |name|
canonical_name = Formulary.canonical_name(name)
aliases.include?(name) && results.include?(canonical_name)
end
end
end
|