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.
Files changed (177) hide show
  1. data/ChangeLog +5811 -0
  2. data/History.txt +887 -0
  3. data/LICENSE.txt +51 -0
  4. data/README.md +87 -0
  5. data/Rakefile +113 -0
  6. data/lib/gauntlet_libgems.rb +50 -0
  7. data/lib/libgems.rb +1246 -0
  8. data/lib/libgems/builder.rb +102 -0
  9. data/lib/libgems/command.rb +534 -0
  10. data/lib/libgems/command_manager.rb +182 -0
  11. data/lib/libgems/commands/build_command.rb +53 -0
  12. data/lib/libgems/commands/cert_command.rb +86 -0
  13. data/lib/libgems/commands/check_command.rb +80 -0
  14. data/lib/libgems/commands/cleanup_command.rb +106 -0
  15. data/lib/libgems/commands/contents_command.rb +98 -0
  16. data/lib/libgems/commands/dependency_command.rb +195 -0
  17. data/lib/libgems/commands/environment_command.rb +133 -0
  18. data/lib/libgems/commands/fetch_command.rb +67 -0
  19. data/lib/libgems/commands/generate_index_command.rb +133 -0
  20. data/lib/libgems/commands/help_command.rb +172 -0
  21. data/lib/libgems/commands/install_command.rb +178 -0
  22. data/lib/libgems/commands/list_command.rb +35 -0
  23. data/lib/libgems/commands/lock_command.rb +110 -0
  24. data/lib/libgems/commands/mirror_command.rb +111 -0
  25. data/lib/libgems/commands/outdated_command.rb +33 -0
  26. data/lib/libgems/commands/owner_command.rb +75 -0
  27. data/lib/libgems/commands/pristine_command.rb +93 -0
  28. data/lib/libgems/commands/push_command.rb +56 -0
  29. data/lib/libgems/commands/query_command.rb +280 -0
  30. data/lib/libgems/commands/rdoc_command.rb +91 -0
  31. data/lib/libgems/commands/search_command.rb +31 -0
  32. data/lib/libgems/commands/server_command.rb +86 -0
  33. data/lib/libgems/commands/sources_command.rb +157 -0
  34. data/lib/libgems/commands/specification_command.rb +125 -0
  35. data/lib/libgems/commands/stale_command.rb +27 -0
  36. data/lib/libgems/commands/uninstall_command.rb +83 -0
  37. data/lib/libgems/commands/unpack_command.rb +121 -0
  38. data/lib/libgems/commands/update_command.rb +160 -0
  39. data/lib/libgems/commands/which_command.rb +86 -0
  40. data/lib/libgems/config_file.rb +345 -0
  41. data/lib/libgems/custom_require.rb +44 -0
  42. data/lib/libgems/defaults.rb +101 -0
  43. data/lib/libgems/dependency.rb +227 -0
  44. data/lib/libgems/dependency_installer.rb +286 -0
  45. data/lib/libgems/dependency_list.rb +208 -0
  46. data/lib/libgems/doc_manager.rb +242 -0
  47. data/lib/libgems/errors.rb +35 -0
  48. data/lib/libgems/exceptions.rb +91 -0
  49. data/lib/libgems/ext.rb +18 -0
  50. data/lib/libgems/ext/builder.rb +56 -0
  51. data/lib/libgems/ext/configure_builder.rb +25 -0
  52. data/lib/libgems/ext/ext_conf_builder.rb +24 -0
  53. data/lib/libgems/ext/rake_builder.rb +39 -0
  54. data/lib/libgems/format.rb +81 -0
  55. data/lib/libgems/gem_openssl.rb +92 -0
  56. data/lib/libgems/gem_path_searcher.rb +100 -0
  57. data/lib/libgems/gem_runner.rb +79 -0
  58. data/lib/libgems/gemcutter_utilities.rb +49 -0
  59. data/lib/libgems/indexer.rb +720 -0
  60. data/lib/libgems/install_update_options.rb +125 -0
  61. data/lib/libgems/installer.rb +604 -0
  62. data/lib/libgems/local_remote_options.rb +135 -0
  63. data/lib/libgems/old_format.rb +153 -0
  64. data/lib/libgems/package.rb +97 -0
  65. data/lib/libgems/package/f_sync_dir.rb +23 -0
  66. data/lib/libgems/package/tar_header.rb +266 -0
  67. data/lib/libgems/package/tar_input.rb +222 -0
  68. data/lib/libgems/package/tar_output.rb +144 -0
  69. data/lib/libgems/package/tar_reader.rb +106 -0
  70. data/lib/libgems/package/tar_reader/entry.rb +141 -0
  71. data/lib/libgems/package/tar_writer.rb +241 -0
  72. data/lib/libgems/package_task.rb +126 -0
  73. data/lib/libgems/platform.rb +183 -0
  74. data/lib/libgems/remote_fetcher.rb +414 -0
  75. data/lib/libgems/require_paths_builder.rb +18 -0
  76. data/lib/libgems/requirement.rb +153 -0
  77. data/lib/libgems/security.rb +814 -0
  78. data/lib/libgems/server.rb +872 -0
  79. data/lib/libgems/source_index.rb +597 -0
  80. data/lib/libgems/source_info_cache.rb +395 -0
  81. data/lib/libgems/source_info_cache_entry.rb +56 -0
  82. data/lib/libgems/spec_fetcher.rb +337 -0
  83. data/lib/libgems/specification.rb +1487 -0
  84. data/lib/libgems/test_utilities.rb +147 -0
  85. data/lib/libgems/text.rb +65 -0
  86. data/lib/libgems/uninstaller.rb +278 -0
  87. data/lib/libgems/user_interaction.rb +527 -0
  88. data/lib/libgems/validator.rb +240 -0
  89. data/lib/libgems/version.rb +316 -0
  90. data/lib/libgems/version_option.rb +65 -0
  91. data/lib/rbconfig/datadir.rb +20 -0
  92. data/test/bogussources.rb +8 -0
  93. data/test/data/gem-private_key.pem +27 -0
  94. data/test/data/gem-public_cert.pem +20 -0
  95. data/test/fake_certlib/openssl.rb +7 -0
  96. data/test/foo/discover.rb +0 -0
  97. data/test/gem_installer_test_case.rb +97 -0
  98. data/test/gem_package_tar_test_case.rb +132 -0
  99. data/test/gemutilities.rb +605 -0
  100. data/test/insure_session.rb +43 -0
  101. data/test/mockgemui.rb +56 -0
  102. data/test/plugin/exception/libgems_plugin.rb +2 -0
  103. data/test/plugin/load/libgems_plugin.rb +1 -0
  104. data/test/plugin/standarderror/libgems_plugin.rb +2 -0
  105. data/test/private_key.pem +27 -0
  106. data/test/public_cert.pem +20 -0
  107. data/test/rubygems_plugin.rb +21 -0
  108. data/test/simple_gem.rb +66 -0
  109. data/test/test_config.rb +12 -0
  110. data/test/test_gem.rb +780 -0
  111. data/test/test_gem_builder.rb +27 -0
  112. data/test/test_gem_command.rb +178 -0
  113. data/test/test_gem_command_manager.rb +207 -0
  114. data/test/test_gem_commands_build_command.rb +74 -0
  115. data/test/test_gem_commands_cert_command.rb +124 -0
  116. data/test/test_gem_commands_check_command.rb +18 -0
  117. data/test/test_gem_commands_contents_command.rb +156 -0
  118. data/test/test_gem_commands_dependency_command.rb +216 -0
  119. data/test/test_gem_commands_environment_command.rb +144 -0
  120. data/test/test_gem_commands_fetch_command.rb +76 -0
  121. data/test/test_gem_commands_generate_index_command.rb +135 -0
  122. data/test/test_gem_commands_install_command.rb +315 -0
  123. data/test/test_gem_commands_list_command.rb +36 -0
  124. data/test/test_gem_commands_lock_command.rb +68 -0
  125. data/test/test_gem_commands_mirror_command.rb +60 -0
  126. data/test/test_gem_commands_outdated_command.rb +40 -0
  127. data/test/test_gem_commands_owner_command.rb +105 -0
  128. data/test/test_gem_commands_pristine_command.rb +108 -0
  129. data/test/test_gem_commands_push_command.rb +81 -0
  130. data/test/test_gem_commands_query_command.rb +426 -0
  131. data/test/test_gem_commands_server_command.rb +59 -0
  132. data/test/test_gem_commands_sources_command.rb +209 -0
  133. data/test/test_gem_commands_specification_command.rb +139 -0
  134. data/test/test_gem_commands_stale_command.rb +38 -0
  135. data/test/test_gem_commands_uninstall_command.rb +83 -0
  136. data/test/test_gem_commands_unpack_command.rb +199 -0
  137. data/test/test_gem_commands_update_command.rb +207 -0
  138. data/test/test_gem_commands_which_command.rb +66 -0
  139. data/test/test_gem_config_file.rb +287 -0
  140. data/test/test_gem_dependency.rb +149 -0
  141. data/test/test_gem_dependency_installer.rb +661 -0
  142. data/test/test_gem_dependency_list.rb +230 -0
  143. data/test/test_gem_doc_manager.rb +31 -0
  144. data/test/test_gem_ext_configure_builder.rb +84 -0
  145. data/test/test_gem_ext_ext_conf_builder.rb +173 -0
  146. data/test/test_gem_ext_rake_builder.rb +81 -0
  147. data/test/test_gem_format.rb +70 -0
  148. data/test/test_gem_gem_path_searcher.rb +78 -0
  149. data/test/test_gem_gem_runner.rb +45 -0
  150. data/test/test_gem_gemcutter_utilities.rb +103 -0
  151. data/test/test_gem_indexer.rb +673 -0
  152. data/test/test_gem_install_update_options.rb +68 -0
  153. data/test/test_gem_installer.rb +857 -0
  154. data/test/test_gem_local_remote_options.rb +97 -0
  155. data/test/test_gem_package_tar_header.rb +130 -0
  156. data/test/test_gem_package_tar_input.rb +112 -0
  157. data/test/test_gem_package_tar_output.rb +97 -0
  158. data/test/test_gem_package_tar_reader.rb +46 -0
  159. data/test/test_gem_package_tar_reader_entry.rb +109 -0
  160. data/test/test_gem_package_tar_writer.rb +144 -0
  161. data/test/test_gem_package_task.rb +59 -0
  162. data/test/test_gem_platform.rb +264 -0
  163. data/test/test_gem_remote_fetcher.rb +740 -0
  164. data/test/test_gem_requirement.rb +292 -0
  165. data/test/test_gem_server.rb +356 -0
  166. data/test/test_gem_silent_ui.rb +113 -0
  167. data/test/test_gem_source_index.rb +461 -0
  168. data/test/test_gem_spec_fetcher.rb +410 -0
  169. data/test/test_gem_specification.rb +1334 -0
  170. data/test/test_gem_stream_ui.rb +218 -0
  171. data/test/test_gem_text.rb +43 -0
  172. data/test/test_gem_uninstaller.rb +146 -0
  173. data/test/test_gem_validator.rb +63 -0
  174. data/test/test_gem_version.rb +181 -0
  175. data/test/test_gem_version_option.rb +89 -0
  176. data/test/test_kernel.rb +59 -0
  177. 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
+