libgems 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +5811 -0
- data/History.txt +887 -0
- data/LICENSE.txt +51 -0
- data/README.md +87 -0
- data/Rakefile +113 -0
- data/lib/gauntlet_libgems.rb +50 -0
- data/lib/libgems.rb +1246 -0
- data/lib/libgems/builder.rb +102 -0
- data/lib/libgems/command.rb +534 -0
- data/lib/libgems/command_manager.rb +182 -0
- data/lib/libgems/commands/build_command.rb +53 -0
- data/lib/libgems/commands/cert_command.rb +86 -0
- data/lib/libgems/commands/check_command.rb +80 -0
- data/lib/libgems/commands/cleanup_command.rb +106 -0
- data/lib/libgems/commands/contents_command.rb +98 -0
- data/lib/libgems/commands/dependency_command.rb +195 -0
- data/lib/libgems/commands/environment_command.rb +133 -0
- data/lib/libgems/commands/fetch_command.rb +67 -0
- data/lib/libgems/commands/generate_index_command.rb +133 -0
- data/lib/libgems/commands/help_command.rb +172 -0
- data/lib/libgems/commands/install_command.rb +178 -0
- data/lib/libgems/commands/list_command.rb +35 -0
- data/lib/libgems/commands/lock_command.rb +110 -0
- data/lib/libgems/commands/mirror_command.rb +111 -0
- data/lib/libgems/commands/outdated_command.rb +33 -0
- data/lib/libgems/commands/owner_command.rb +75 -0
- data/lib/libgems/commands/pristine_command.rb +93 -0
- data/lib/libgems/commands/push_command.rb +56 -0
- data/lib/libgems/commands/query_command.rb +280 -0
- data/lib/libgems/commands/rdoc_command.rb +91 -0
- data/lib/libgems/commands/search_command.rb +31 -0
- data/lib/libgems/commands/server_command.rb +86 -0
- data/lib/libgems/commands/sources_command.rb +157 -0
- data/lib/libgems/commands/specification_command.rb +125 -0
- data/lib/libgems/commands/stale_command.rb +27 -0
- data/lib/libgems/commands/uninstall_command.rb +83 -0
- data/lib/libgems/commands/unpack_command.rb +121 -0
- data/lib/libgems/commands/update_command.rb +160 -0
- data/lib/libgems/commands/which_command.rb +86 -0
- data/lib/libgems/config_file.rb +345 -0
- data/lib/libgems/custom_require.rb +44 -0
- data/lib/libgems/defaults.rb +101 -0
- data/lib/libgems/dependency.rb +227 -0
- data/lib/libgems/dependency_installer.rb +286 -0
- data/lib/libgems/dependency_list.rb +208 -0
- data/lib/libgems/doc_manager.rb +242 -0
- data/lib/libgems/errors.rb +35 -0
- data/lib/libgems/exceptions.rb +91 -0
- data/lib/libgems/ext.rb +18 -0
- data/lib/libgems/ext/builder.rb +56 -0
- data/lib/libgems/ext/configure_builder.rb +25 -0
- data/lib/libgems/ext/ext_conf_builder.rb +24 -0
- data/lib/libgems/ext/rake_builder.rb +39 -0
- data/lib/libgems/format.rb +81 -0
- data/lib/libgems/gem_openssl.rb +92 -0
- data/lib/libgems/gem_path_searcher.rb +100 -0
- data/lib/libgems/gem_runner.rb +79 -0
- data/lib/libgems/gemcutter_utilities.rb +49 -0
- data/lib/libgems/indexer.rb +720 -0
- data/lib/libgems/install_update_options.rb +125 -0
- data/lib/libgems/installer.rb +604 -0
- data/lib/libgems/local_remote_options.rb +135 -0
- data/lib/libgems/old_format.rb +153 -0
- data/lib/libgems/package.rb +97 -0
- data/lib/libgems/package/f_sync_dir.rb +23 -0
- data/lib/libgems/package/tar_header.rb +266 -0
- data/lib/libgems/package/tar_input.rb +222 -0
- data/lib/libgems/package/tar_output.rb +144 -0
- data/lib/libgems/package/tar_reader.rb +106 -0
- data/lib/libgems/package/tar_reader/entry.rb +141 -0
- data/lib/libgems/package/tar_writer.rb +241 -0
- data/lib/libgems/package_task.rb +126 -0
- data/lib/libgems/platform.rb +183 -0
- data/lib/libgems/remote_fetcher.rb +414 -0
- data/lib/libgems/require_paths_builder.rb +18 -0
- data/lib/libgems/requirement.rb +153 -0
- data/lib/libgems/security.rb +814 -0
- data/lib/libgems/server.rb +872 -0
- data/lib/libgems/source_index.rb +597 -0
- data/lib/libgems/source_info_cache.rb +395 -0
- data/lib/libgems/source_info_cache_entry.rb +56 -0
- data/lib/libgems/spec_fetcher.rb +337 -0
- data/lib/libgems/specification.rb +1487 -0
- data/lib/libgems/test_utilities.rb +147 -0
- data/lib/libgems/text.rb +65 -0
- data/lib/libgems/uninstaller.rb +278 -0
- data/lib/libgems/user_interaction.rb +527 -0
- data/lib/libgems/validator.rb +240 -0
- data/lib/libgems/version.rb +316 -0
- data/lib/libgems/version_option.rb +65 -0
- data/lib/rbconfig/datadir.rb +20 -0
- data/test/bogussources.rb +8 -0
- data/test/data/gem-private_key.pem +27 -0
- data/test/data/gem-public_cert.pem +20 -0
- data/test/fake_certlib/openssl.rb +7 -0
- data/test/foo/discover.rb +0 -0
- data/test/gem_installer_test_case.rb +97 -0
- data/test/gem_package_tar_test_case.rb +132 -0
- data/test/gemutilities.rb +605 -0
- data/test/insure_session.rb +43 -0
- data/test/mockgemui.rb +56 -0
- data/test/plugin/exception/libgems_plugin.rb +2 -0
- data/test/plugin/load/libgems_plugin.rb +1 -0
- data/test/plugin/standarderror/libgems_plugin.rb +2 -0
- data/test/private_key.pem +27 -0
- data/test/public_cert.pem +20 -0
- data/test/rubygems_plugin.rb +21 -0
- data/test/simple_gem.rb +66 -0
- data/test/test_config.rb +12 -0
- data/test/test_gem.rb +780 -0
- data/test/test_gem_builder.rb +27 -0
- data/test/test_gem_command.rb +178 -0
- data/test/test_gem_command_manager.rb +207 -0
- data/test/test_gem_commands_build_command.rb +74 -0
- data/test/test_gem_commands_cert_command.rb +124 -0
- data/test/test_gem_commands_check_command.rb +18 -0
- data/test/test_gem_commands_contents_command.rb +156 -0
- data/test/test_gem_commands_dependency_command.rb +216 -0
- data/test/test_gem_commands_environment_command.rb +144 -0
- data/test/test_gem_commands_fetch_command.rb +76 -0
- data/test/test_gem_commands_generate_index_command.rb +135 -0
- data/test/test_gem_commands_install_command.rb +315 -0
- data/test/test_gem_commands_list_command.rb +36 -0
- data/test/test_gem_commands_lock_command.rb +68 -0
- data/test/test_gem_commands_mirror_command.rb +60 -0
- data/test/test_gem_commands_outdated_command.rb +40 -0
- data/test/test_gem_commands_owner_command.rb +105 -0
- data/test/test_gem_commands_pristine_command.rb +108 -0
- data/test/test_gem_commands_push_command.rb +81 -0
- data/test/test_gem_commands_query_command.rb +426 -0
- data/test/test_gem_commands_server_command.rb +59 -0
- data/test/test_gem_commands_sources_command.rb +209 -0
- data/test/test_gem_commands_specification_command.rb +139 -0
- data/test/test_gem_commands_stale_command.rb +38 -0
- data/test/test_gem_commands_uninstall_command.rb +83 -0
- data/test/test_gem_commands_unpack_command.rb +199 -0
- data/test/test_gem_commands_update_command.rb +207 -0
- data/test/test_gem_commands_which_command.rb +66 -0
- data/test/test_gem_config_file.rb +287 -0
- data/test/test_gem_dependency.rb +149 -0
- data/test/test_gem_dependency_installer.rb +661 -0
- data/test/test_gem_dependency_list.rb +230 -0
- data/test/test_gem_doc_manager.rb +31 -0
- data/test/test_gem_ext_configure_builder.rb +84 -0
- data/test/test_gem_ext_ext_conf_builder.rb +173 -0
- data/test/test_gem_ext_rake_builder.rb +81 -0
- data/test/test_gem_format.rb +70 -0
- data/test/test_gem_gem_path_searcher.rb +78 -0
- data/test/test_gem_gem_runner.rb +45 -0
- data/test/test_gem_gemcutter_utilities.rb +103 -0
- data/test/test_gem_indexer.rb +673 -0
- data/test/test_gem_install_update_options.rb +68 -0
- data/test/test_gem_installer.rb +857 -0
- data/test/test_gem_local_remote_options.rb +97 -0
- data/test/test_gem_package_tar_header.rb +130 -0
- data/test/test_gem_package_tar_input.rb +112 -0
- data/test/test_gem_package_tar_output.rb +97 -0
- data/test/test_gem_package_tar_reader.rb +46 -0
- data/test/test_gem_package_tar_reader_entry.rb +109 -0
- data/test/test_gem_package_tar_writer.rb +144 -0
- data/test/test_gem_package_task.rb +59 -0
- data/test/test_gem_platform.rb +264 -0
- data/test/test_gem_remote_fetcher.rb +740 -0
- data/test/test_gem_requirement.rb +292 -0
- data/test/test_gem_server.rb +356 -0
- data/test/test_gem_silent_ui.rb +113 -0
- data/test/test_gem_source_index.rb +461 -0
- data/test/test_gem_spec_fetcher.rb +410 -0
- data/test/test_gem_specification.rb +1334 -0
- data/test/test_gem_stream_ui.rb +218 -0
- data/test/test_gem_text.rb +43 -0
- data/test/test_gem_uninstaller.rb +146 -0
- data/test/test_gem_validator.rb +63 -0
- data/test/test_gem_version.rb +181 -0
- data/test/test_gem_version_option.rb +89 -0
- data/test/test_kernel.rb +59 -0
- metadata +402 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Module that defines the default UserInteraction. Any class including this
|
|
9
|
+
# module will have access to the +ui+ method that returns the default UI.
|
|
10
|
+
|
|
11
|
+
module LibGems::DefaultUserInteraction
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# The default UI is a class variable of the singleton class for this
|
|
15
|
+
# module.
|
|
16
|
+
|
|
17
|
+
@ui = nil
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Return the default UI.
|
|
21
|
+
|
|
22
|
+
def self.ui
|
|
23
|
+
@ui ||= LibGems::ConsoleUI.new
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Set the default UI. If the default UI is never explicitly set, a simple
|
|
28
|
+
# console based UserInteraction will be used automatically.
|
|
29
|
+
|
|
30
|
+
def self.ui=(new_ui)
|
|
31
|
+
@ui = new_ui
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Use +new_ui+ for the duration of +block+.
|
|
36
|
+
|
|
37
|
+
def self.use_ui(new_ui)
|
|
38
|
+
old_ui = @ui
|
|
39
|
+
@ui = new_ui
|
|
40
|
+
yield
|
|
41
|
+
ensure
|
|
42
|
+
@ui = old_ui
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# See DefaultUserInteraction::ui
|
|
47
|
+
|
|
48
|
+
def ui
|
|
49
|
+
LibGems::DefaultUserInteraction.ui
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# See DefaultUserInteraction::ui=
|
|
54
|
+
|
|
55
|
+
def ui=(new_ui)
|
|
56
|
+
LibGems::DefaultUserInteraction.ui = new_ui
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# See DefaultUserInteraction::use_ui
|
|
61
|
+
|
|
62
|
+
def use_ui(new_ui, &block)
|
|
63
|
+
LibGems::DefaultUserInteraction.use_ui(new_ui, &block)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# Make the default UI accessable without the "ui." prefix. Classes
|
|
70
|
+
# including this module may use the interaction methods on the default UI
|
|
71
|
+
# directly. Classes may also reference the ui and ui= methods.
|
|
72
|
+
#
|
|
73
|
+
# Example:
|
|
74
|
+
#
|
|
75
|
+
# class X
|
|
76
|
+
# include LibGems::UserInteraction
|
|
77
|
+
#
|
|
78
|
+
# def get_answer
|
|
79
|
+
# n = ask("What is the meaning of life?")
|
|
80
|
+
# end
|
|
81
|
+
# end
|
|
82
|
+
|
|
83
|
+
module LibGems::UserInteraction
|
|
84
|
+
|
|
85
|
+
include LibGems::DefaultUserInteraction
|
|
86
|
+
|
|
87
|
+
##
|
|
88
|
+
# :method: alert
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# :method: alert_error
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# :method: alert_warning
|
|
95
|
+
|
|
96
|
+
##
|
|
97
|
+
# :method: ask
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# :method: ask_yes_no
|
|
101
|
+
|
|
102
|
+
##
|
|
103
|
+
# :method: choose_from_list
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# :method: say
|
|
107
|
+
|
|
108
|
+
##
|
|
109
|
+
# :method: terminate_interaction
|
|
110
|
+
|
|
111
|
+
[:alert,
|
|
112
|
+
:alert_error,
|
|
113
|
+
:alert_warning,
|
|
114
|
+
:ask,
|
|
115
|
+
:ask_for_password,
|
|
116
|
+
:ask_yes_no,
|
|
117
|
+
:choose_from_list,
|
|
118
|
+
:say,
|
|
119
|
+
:terminate_interaction ].each do |methname|
|
|
120
|
+
class_eval %{
|
|
121
|
+
def #{methname}(*args)
|
|
122
|
+
ui.#{methname}(*args)
|
|
123
|
+
end
|
|
124
|
+
}, __FILE__, __LINE__
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
##
|
|
129
|
+
# LibGems::StreamUI implements a simple stream based user interface.
|
|
130
|
+
|
|
131
|
+
class LibGems::StreamUI
|
|
132
|
+
|
|
133
|
+
attr_reader :ins, :outs, :errs
|
|
134
|
+
|
|
135
|
+
def initialize(in_stream, out_stream, err_stream=STDERR)
|
|
136
|
+
@ins = in_stream
|
|
137
|
+
@outs = out_stream
|
|
138
|
+
@errs = err_stream
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
##
|
|
142
|
+
# Choose from a list of options. +question+ is a prompt displayed above
|
|
143
|
+
# the list. +list+ is a list of option strings. Returns the pair
|
|
144
|
+
# [option_name, option_index].
|
|
145
|
+
|
|
146
|
+
def choose_from_list(question, list)
|
|
147
|
+
@outs.puts question
|
|
148
|
+
|
|
149
|
+
list.each_with_index do |item, index|
|
|
150
|
+
@outs.puts " #{index+1}. #{item}"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
@outs.print "> "
|
|
154
|
+
@outs.flush
|
|
155
|
+
|
|
156
|
+
result = @ins.gets
|
|
157
|
+
|
|
158
|
+
return nil, nil unless result
|
|
159
|
+
|
|
160
|
+
result = result.strip.to_i - 1
|
|
161
|
+
return list[result], result
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
# Ask a question. Returns a true for yes, false for no. If not connected
|
|
166
|
+
# to a tty, raises an exception if default is nil, otherwise returns
|
|
167
|
+
# default.
|
|
168
|
+
|
|
169
|
+
def ask_yes_no(question, default=nil)
|
|
170
|
+
unless @ins.tty? then
|
|
171
|
+
if default.nil? then
|
|
172
|
+
raise LibGems::OperationNotSupportedError,
|
|
173
|
+
"Not connected to a tty and no default specified"
|
|
174
|
+
else
|
|
175
|
+
return default
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
qstr = case default
|
|
180
|
+
when nil
|
|
181
|
+
'yn'
|
|
182
|
+
when true
|
|
183
|
+
'Yn'
|
|
184
|
+
else
|
|
185
|
+
'yN'
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
result = nil
|
|
189
|
+
|
|
190
|
+
while result.nil?
|
|
191
|
+
result = ask("#{question} [#{qstr}]")
|
|
192
|
+
result = case result
|
|
193
|
+
when /^[Yy].*/
|
|
194
|
+
true
|
|
195
|
+
when /^[Nn].*/
|
|
196
|
+
false
|
|
197
|
+
when /^$/
|
|
198
|
+
default
|
|
199
|
+
else
|
|
200
|
+
nil
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
return result
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
##
|
|
208
|
+
# Ask a question. Returns an answer if connected to a tty, nil otherwise.
|
|
209
|
+
|
|
210
|
+
def ask(question)
|
|
211
|
+
return nil if not @ins.tty?
|
|
212
|
+
|
|
213
|
+
@outs.print(question + " ")
|
|
214
|
+
@outs.flush
|
|
215
|
+
|
|
216
|
+
result = @ins.gets
|
|
217
|
+
result.chomp! if result
|
|
218
|
+
result
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
##
|
|
222
|
+
# Ask for a password. Does not echo response to terminal.
|
|
223
|
+
|
|
224
|
+
def ask_for_password(question)
|
|
225
|
+
return nil if not @ins.tty?
|
|
226
|
+
|
|
227
|
+
@outs.print(question + " ")
|
|
228
|
+
@outs.flush
|
|
229
|
+
|
|
230
|
+
LibGems.win_platform? ? ask_for_password_on_windows : ask_for_password_on_unix
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
##
|
|
234
|
+
# Asks for a password that works on windows. Ripped from the Heroku gem.
|
|
235
|
+
|
|
236
|
+
def ask_for_password_on_windows
|
|
237
|
+
require "Win32API"
|
|
238
|
+
char = nil
|
|
239
|
+
password = ''
|
|
240
|
+
|
|
241
|
+
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
|
|
242
|
+
break if char == 10 || char == 13 # received carriage return or newline
|
|
243
|
+
if char == 127 || char == 8 # backspace and delete
|
|
244
|
+
password.slice!(-1, 1)
|
|
245
|
+
else
|
|
246
|
+
password << char.chr
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
puts
|
|
251
|
+
password
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
##
|
|
255
|
+
# Asks for a password that works on unix
|
|
256
|
+
|
|
257
|
+
def ask_for_password_on_unix
|
|
258
|
+
system "stty -echo"
|
|
259
|
+
password = @ins.gets
|
|
260
|
+
password.chomp! if password
|
|
261
|
+
system "stty echo"
|
|
262
|
+
password
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
##
|
|
266
|
+
# Display a statement.
|
|
267
|
+
|
|
268
|
+
def say(statement="")
|
|
269
|
+
@outs.puts statement
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
##
|
|
273
|
+
# Display an informational alert. Will ask +question+ if it is not nil.
|
|
274
|
+
|
|
275
|
+
def alert(statement, question=nil)
|
|
276
|
+
@outs.puts "INFO: #{statement}"
|
|
277
|
+
ask(question) if question
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
##
|
|
281
|
+
# Display a warning in a location expected to get error messages. Will
|
|
282
|
+
# ask +question+ if it is not nil.
|
|
283
|
+
|
|
284
|
+
def alert_warning(statement, question=nil)
|
|
285
|
+
@errs.puts "WARNING: #{statement}"
|
|
286
|
+
ask(question) if question
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
##
|
|
290
|
+
# Display an error message in a location expected to get error messages.
|
|
291
|
+
# Will ask +question+ if it is not nil.
|
|
292
|
+
|
|
293
|
+
def alert_error(statement, question=nil)
|
|
294
|
+
@errs.puts "ERROR: #{statement}"
|
|
295
|
+
ask(question) if question
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
##
|
|
299
|
+
# Display a debug message on the same location as error messages.
|
|
300
|
+
|
|
301
|
+
def debug(statement)
|
|
302
|
+
@errs.puts statement
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
##
|
|
306
|
+
# Terminate the application with exit code +status+, running any exit
|
|
307
|
+
# handlers that might have been defined.
|
|
308
|
+
|
|
309
|
+
def terminate_interaction(status = 0)
|
|
310
|
+
raise LibGems::SystemExitException, status
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
##
|
|
314
|
+
# Return a progress reporter object chosen from the current verbosity.
|
|
315
|
+
|
|
316
|
+
def progress_reporter(*args)
|
|
317
|
+
case LibGems.configuration.verbose
|
|
318
|
+
when nil, false
|
|
319
|
+
SilentProgressReporter.new(@outs, *args)
|
|
320
|
+
when true
|
|
321
|
+
SimpleProgressReporter.new(@outs, *args)
|
|
322
|
+
else
|
|
323
|
+
VerboseProgressReporter.new(@outs, *args)
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
##
|
|
328
|
+
# An absolutely silent progress reporter.
|
|
329
|
+
|
|
330
|
+
class SilentProgressReporter
|
|
331
|
+
attr_reader :count
|
|
332
|
+
|
|
333
|
+
def initialize(out_stream, size, initial_message, terminal_message = nil)
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def updated(message)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def done
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
##
|
|
344
|
+
# A basic dotted progress reporter.
|
|
345
|
+
|
|
346
|
+
class SimpleProgressReporter
|
|
347
|
+
|
|
348
|
+
include LibGems::DefaultUserInteraction
|
|
349
|
+
|
|
350
|
+
attr_reader :count
|
|
351
|
+
|
|
352
|
+
def initialize(out_stream, size, initial_message,
|
|
353
|
+
terminal_message = "complete")
|
|
354
|
+
@out = out_stream
|
|
355
|
+
@total = size
|
|
356
|
+
@count = 0
|
|
357
|
+
@terminal_message = terminal_message
|
|
358
|
+
|
|
359
|
+
@out.puts initial_message
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
##
|
|
363
|
+
# Prints out a dot and ignores +message+.
|
|
364
|
+
|
|
365
|
+
def updated(message)
|
|
366
|
+
@count += 1
|
|
367
|
+
@out.print "."
|
|
368
|
+
@out.flush
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
##
|
|
372
|
+
# Prints out the terminal message.
|
|
373
|
+
|
|
374
|
+
def done
|
|
375
|
+
@out.puts "\n#{@terminal_message}"
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
##
|
|
381
|
+
# A progress reporter that prints out messages about the current progress.
|
|
382
|
+
|
|
383
|
+
class VerboseProgressReporter
|
|
384
|
+
|
|
385
|
+
include LibGems::DefaultUserInteraction
|
|
386
|
+
|
|
387
|
+
attr_reader :count
|
|
388
|
+
|
|
389
|
+
def initialize(out_stream, size, initial_message,
|
|
390
|
+
terminal_message = 'complete')
|
|
391
|
+
@out = out_stream
|
|
392
|
+
@total = size
|
|
393
|
+
@count = 0
|
|
394
|
+
@terminal_message = terminal_message
|
|
395
|
+
|
|
396
|
+
@out.puts initial_message
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
##
|
|
400
|
+
# Prints out the position relative to the total and the +message+.
|
|
401
|
+
|
|
402
|
+
def updated(message)
|
|
403
|
+
@count += 1
|
|
404
|
+
@out.puts "#{@count}/#{@total}: #{message}"
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
##
|
|
408
|
+
# Prints out the terminal message.
|
|
409
|
+
|
|
410
|
+
def done
|
|
411
|
+
@out.puts @terminal_message
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
##
|
|
416
|
+
# Return a download reporter object chosen from the current verbosity
|
|
417
|
+
|
|
418
|
+
def download_reporter(*args)
|
|
419
|
+
case LibGems.configuration.verbose
|
|
420
|
+
when nil, false
|
|
421
|
+
SilentDownloadReporter.new(@outs, *args)
|
|
422
|
+
else
|
|
423
|
+
VerboseDownloadReporter.new(@outs, *args)
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
##
|
|
428
|
+
# An absolutely silent download reporter.
|
|
429
|
+
|
|
430
|
+
class SilentDownloadReporter
|
|
431
|
+
def initialize(out_stream, *args)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
def fetch(filename, filesize)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def update(current)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def done
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
##
|
|
445
|
+
# A progress reporter that prints out messages about the current progress.
|
|
446
|
+
|
|
447
|
+
class VerboseDownloadReporter
|
|
448
|
+
attr_reader :file_name, :total_bytes, :progress
|
|
449
|
+
|
|
450
|
+
def initialize(out_stream, *args)
|
|
451
|
+
@out = out_stream
|
|
452
|
+
@progress = 0
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def fetch(file_name, total_bytes)
|
|
456
|
+
@file_name = file_name
|
|
457
|
+
@total_bytes = total_bytes.to_i
|
|
458
|
+
@units = @total_bytes.zero? ? 'B' : '%'
|
|
459
|
+
|
|
460
|
+
update_display(false)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def update(bytes)
|
|
464
|
+
new_progress = if @units == 'B' then
|
|
465
|
+
bytes
|
|
466
|
+
else
|
|
467
|
+
((bytes.to_f * 100) / total_bytes.to_f).ceil
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
return if new_progress == @progress
|
|
471
|
+
|
|
472
|
+
@progress = new_progress
|
|
473
|
+
update_display
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def done
|
|
477
|
+
@progress = 100 if @units == '%'
|
|
478
|
+
update_display(true, true)
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
private
|
|
482
|
+
|
|
483
|
+
def update_display(show_progress = true, new_line = false)
|
|
484
|
+
return unless @out.tty?
|
|
485
|
+
|
|
486
|
+
if show_progress then
|
|
487
|
+
@out.print "\rFetching: %s (%3d%s)" % [@file_name, @progress, @units]
|
|
488
|
+
else
|
|
489
|
+
@out.print "Fetching: %s" % @file_name
|
|
490
|
+
end
|
|
491
|
+
@out.puts if new_line
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
##
|
|
497
|
+
# Subclass of StreamUI that instantiates the user interaction using STDIN,
|
|
498
|
+
# STDOUT, and STDERR.
|
|
499
|
+
|
|
500
|
+
class LibGems::ConsoleUI < LibGems::StreamUI
|
|
501
|
+
def initialize
|
|
502
|
+
super STDIN, STDOUT, STDERR
|
|
503
|
+
end
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
##
|
|
507
|
+
# SilentUI is a UI choice that is absolutely silent.
|
|
508
|
+
|
|
509
|
+
class LibGems::SilentUI < LibGems::StreamUI
|
|
510
|
+
|
|
511
|
+
def initialize
|
|
512
|
+
|
|
513
|
+
reader, writer = nil, nil
|
|
514
|
+
|
|
515
|
+
begin
|
|
516
|
+
reader = File.open('/dev/null', 'r')
|
|
517
|
+
writer = File.open('/dev/null', 'w')
|
|
518
|
+
rescue Errno::ENOENT => e
|
|
519
|
+
reader = File.open('nul', 'r')
|
|
520
|
+
writer = File.open('nul', 'w')
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
super reader, writer, writer
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
end
|
|
527
|
+
|