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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
require 'rubygems/source_info_cache'
class Gem::Commands::DependencyCommand < Gem::Command
include Gem::LocalRemoteOptions
include Gem::VersionOption
def initialize
super 'dependency',
'Show the dependencies of an installed gem',
:version => Gem::Requirement.default, :domain => :local
add_version_option
add_platform_option
add_option('-R', '--[no-]reverse-dependencies',
'Include reverse dependencies in the output') do
|value, options|
options[:reverse_dependencies] = value
end
add_option('-p', '--pipe',
"Pipe Format (name --version ver)") do |value, options|
options[:pipe_format] = value
end
add_local_remote_options
end
def arguments # :nodoc:
"GEMNAME name of gem to show dependencies for"
end
def defaults_str # :nodoc:
"--local --version '#{Gem::Requirement.default}' --no-reverse-dependencies"
end
def usage # :nodoc:
"#{program_name} GEMNAME"
end
def execute
options[:args] << '' if options[:args].empty?
specs = {}
source_indexes = Hash.new do |h, source_uri|
h[source_uri] = Gem::SourceIndex.new
end
pattern = if options[:args].length == 1 and
options[:args].first =~ /\A\/(.*)\/(i)?\z/m then
flags = $2 ? Regexp::IGNORECASE : nil
Regexp.new $1, flags
else
/\A#{Regexp.union(*options[:args])}/
end
dependency = Gem::Dependency.new pattern, options[:version]
if options[:reverse_dependencies] and remote? and not local? then
alert_error 'Only reverse dependencies for local gems are supported.'
terminate_interaction 1
end
if local? then
Gem.source_index.search(dependency).each do |spec|
source_indexes[:local].add_spec spec
end
end
if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher
begin
fetcher.find_matching(dependency).each do |spec_tuple, source_uri|
spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
source_indexes[source_uri].add_spec spec
end
rescue Gem::RemoteFetcher::FetchError => e
raise unless fetcher.warn_legacy e do
require 'rubygems/source_info_cache'
specs = Gem::SourceInfoCache.search_with_source dependency, false
specs.each do |spec, source_uri|
source_indexes[source_uri].add_spec spec
end
end
end
end
if source_indexes.empty? then
patterns = options[:args].join ','
say "No gems found matching #{patterns} (#{options[:version]})" if
Gem.configuration.verbose
terminate_interaction 1
end
specs = {}
source_indexes.values.each do |source_index|
source_index.gems.each do |name, spec|
specs[spec.full_name] = [source_index, spec]
end
end
reverse = Hash.new { |h, k| h[k] = [] }
if options[:reverse_dependencies] then
specs.values.each do |_, spec|
reverse[spec.full_name] = find_reverse_dependencies spec
end
end
if options[:pipe_format] then
specs.values.sort_by { |_, spec| spec }.each do |_, spec|
unless spec.dependencies.empty?
spec.dependencies.each do |dep|
say "#{dep.name} --version '#{dep.version_requirements}'"
end
end
end
else
response = ''
specs.values.sort_by { |_, spec| spec }.each do |_, spec|
response << print_dependencies(spec)
unless reverse[spec.full_name].empty? then
response << " Used by\n"
reverse[spec.full_name].each do |sp, dep|
response << " #{sp} (#{dep})\n"
end
end
response << "\n"
end
say response
end
end
def print_dependencies(spec, level = 0)
response = ''
response << ' ' * level + "Gem #{spec.full_name}\n"
unless spec.dependencies.empty? then
spec.dependencies.each do |dep|
response << ' ' * level + " #{dep}\n"
end
end
response
end
# Retuns list of [specification, dep] that are satisfied by spec.
def find_reverse_dependencies(spec)
result = []
Gem.source_index.each do |name, sp|
sp.dependencies.each do |dep|
dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep
if spec.name == dep.name and
dep.version_requirements.satisfied_by?(spec.version) then
result << [sp.full_name, dep]
end
end
end
result
end
def find_gems(name, source_index)
specs = {}
spec_list = source_index.search name, options[:version]
spec_list.each do |spec|
specs[spec.full_name] = [source_index, spec]
end
specs
end
end
|