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
|
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/source_info_cache'
class Gem::Commands::QueryCommand < Gem::Command
include Gem::LocalRemoteOptions
def initialize(name = 'query',
summary = 'Query gem information in local or remote repositories')
super name, summary,
:name => /.*/, :domain => :local, :details => false, :versions => true
add_option('-n', '--name-matches REGEXP',
'Name of gem(s) to query on matches the',
'provided REGEXP') do |value, options|
options[:name] = /#{value}/i
end
add_option('-d', '--[no-]details',
'Display detailed information of gem(s)') do |value, options|
options[:details] = value
end
add_option( '--[no-]versions',
'Display only gem names') do |value, options|
options[:versions] = value
options[:details] = false unless value
end
add_local_remote_options
end
def defaults_str # :nodoc:
"--local --name-matches '.*' --no-details --versions"
end
def execute
name = options[:name]
if local? then
say
say "*** LOCAL GEMS ***"
say
output_query_results Gem.cache.search(name)
end
if remote? then
say
say "*** REMOTE GEMS ***"
say
output_query_results Gem::SourceInfoCache.search(name)
end
end
private
def output_query_results(gemspecs)
output = []
gem_list_with_version = {}
gemspecs.flatten.each do |gemspec|
gem_list_with_version[gemspec.name] ||= []
gem_list_with_version[gemspec.name] << gemspec
end
gem_list_with_version = gem_list_with_version.sort_by do |name, spec|
name.downcase
end
gem_list_with_version.each do |gem_name, list_of_matching|
list_of_matching = list_of_matching.sort_by { |x| x.version.to_ints }.reverse
seen_versions = {}
list_of_matching.delete_if do |item|
if seen_versions[item.version] then
true
else
seen_versions[item.version] = true
false
end
end
entry = gem_name.dup
if options[:versions] then
entry << " (#{list_of_matching.map{|gem| gem.version.to_s}.join(", ")})"
end
entry << "\n" << format_text(list_of_matching[0].summary, 68, 4) if
options[:details]
output << entry
end
say output.join(options[:details] ? "\n\n" : "\n")
end
##
# Used for wrapping and indenting text
#
def format_text(text, wrap, indent=0)
result = []
work = text.dup
while work.length > wrap
if work =~ /^(.{0,#{wrap}})[ \n]/o then
result << $1
work.slice!(0, $&.length)
else
result << work.slice!(0, wrap)
end
end
result << work if work.length.nonzero?
result.join("\n").gsub(/^/, " " * indent)
end
end
|