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
157
158
159
160
161
162
163
164
165
166
167
|
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/source_info_cache'
require 'rubygems/version_option'
class Gem::Commands::QueryCommand < Gem::Command
include Gem::LocalRemoteOptions
include Gem::VersionOption
def initialize(name = 'query',
summary = 'Query gem information in local or remote repositories')
super name, summary,
:name => //, :domain => :local, :details => false, :versions => true,
:installed => false, :version => Gem::Requirement.default
add_option('-i', '--[no-]installed',
'Check for installed gem') do |value, options|
options[:installed] = value
end
add_version_option
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_option('-a', '--all',
'Display all gem versions') do |value, options|
options[:all] = value
end
add_local_remote_options
end
def defaults_str # :nodoc:
"--local --name-matches // --no-details --versions --no-installed"
end
def execute
exit_code = 0
name = options[:name]
if options[:installed] then
if name.source.empty? then
alert_error "You must specify a gem name"
exit_code |= 4
elsif installed? name.source, options[:version] then
say "true"
else
say "false"
exit_code |= 1
end
raise Gem::SystemExitException, exit_code
end
if local? then
say
say "*** LOCAL GEMS ***"
say
output_query_results Gem.source_index.search(name)
end
if remote? then
say
say "*** REMOTE GEMS ***"
say
begin
Gem::SourceInfoCache.cache.refresh options[:all]
rescue Gem::RemoteFetcher::FetchError
# no network
end
output_query_results Gem::SourceInfoCache.search(name, false, true)
end
end
private
##
# Check if gem +name+ version +version+ is installed.
def installed?(name, version = Gem::Requirement.default)
dep = Gem::Dependency.new name, version
!Gem.source_index.search(dep).empty?
end
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
versions = list_of_matching.map { |s| s.version }.uniq
entry << " (#{versions.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
|