rubygems-update 1.8.30 → 2.0.0.preview2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubygems-update might be problematic. Click here for more details.

Files changed (241) hide show
  1. checksums.yaml +6 -6
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -0
  4. data/.autotest +6 -3
  5. data/History.txt +137 -63
  6. data/LICENSE.txt +1 -5
  7. data/Manifest.txt +69 -32
  8. data/README.rdoc +11 -9
  9. data/Rakefile +24 -38
  10. data/bin/gem +0 -9
  11. data/bin/update_rubygems +1 -0
  12. data/lib/rubygems.rb +193 -405
  13. data/lib/rubygems/available_set.rb +95 -0
  14. data/lib/rubygems/command.rb +88 -45
  15. data/lib/rubygems/command_manager.rb +67 -40
  16. data/lib/rubygems/commands/build_command.rb +5 -23
  17. data/lib/rubygems/commands/cert_command.rb +199 -57
  18. data/lib/rubygems/commands/check_command.rb +14 -39
  19. data/lib/rubygems/commands/cleanup_command.rb +9 -1
  20. data/lib/rubygems/commands/contents_command.rb +30 -12
  21. data/lib/rubygems/commands/dependency_command.rb +3 -8
  22. data/lib/rubygems/commands/environment_command.rb +13 -8
  23. data/lib/rubygems/commands/fetch_command.rb +3 -16
  24. data/lib/rubygems/commands/generate_index_command.rb +7 -47
  25. data/lib/rubygems/commands/help_command.rb +1 -1
  26. data/lib/rubygems/commands/install_command.rb +69 -36
  27. data/lib/rubygems/commands/list_command.rb +6 -4
  28. data/lib/rubygems/commands/lock_command.rb +1 -1
  29. data/lib/rubygems/commands/mirror_command.rb +17 -0
  30. data/lib/rubygems/commands/outdated_command.rb +6 -3
  31. data/lib/rubygems/commands/owner_command.rb +13 -5
  32. data/lib/rubygems/commands/pristine_command.rb +19 -4
  33. data/lib/rubygems/commands/push_command.rb +12 -1
  34. data/lib/rubygems/commands/query_command.rb +43 -27
  35. data/lib/rubygems/commands/rdoc_command.rb +23 -28
  36. data/lib/rubygems/commands/search_command.rb +4 -18
  37. data/lib/rubygems/commands/server_command.rb +1 -1
  38. data/lib/rubygems/commands/setup_command.rb +124 -38
  39. data/lib/rubygems/commands/sources_command.rb +16 -16
  40. data/lib/rubygems/commands/specification_command.rb +11 -13
  41. data/lib/rubygems/commands/uninstall_command.rb +24 -7
  42. data/lib/rubygems/commands/unpack_command.rb +7 -3
  43. data/lib/rubygems/commands/update_command.rb +22 -36
  44. data/lib/rubygems/commands/yank_command.rb +98 -0
  45. data/lib/rubygems/compatibility.rb +51 -0
  46. data/lib/rubygems/config_file.rb +82 -54
  47. data/lib/rubygems/core_ext/kernel_gem.rb +53 -0
  48. data/lib/rubygems/core_ext/kernel_require.rb +119 -0
  49. data/lib/rubygems/defaults.rb +10 -21
  50. data/lib/rubygems/dependency.rb +61 -10
  51. data/lib/rubygems/dependency_installer.rb +157 -69
  52. data/lib/rubygems/dependency_list.rb +11 -19
  53. data/lib/rubygems/dependency_resolver.rb +562 -0
  54. data/lib/rubygems/deprecate.rb +40 -40
  55. data/lib/rubygems/errors.rb +77 -24
  56. data/lib/rubygems/exceptions.rb +25 -7
  57. data/lib/rubygems/ext/builder.rb +20 -23
  58. data/lib/rubygems/ext/configure_builder.rb +2 -2
  59. data/lib/rubygems/ext/ext_conf_builder.rb +5 -45
  60. data/lib/rubygems/ext/rake_builder.rb +2 -2
  61. data/lib/rubygems/gem_runner.rb +3 -16
  62. data/lib/rubygems/gemcutter_utilities.rb +22 -7
  63. data/lib/rubygems/indexer.rb +6 -159
  64. data/lib/rubygems/install_message.rb +12 -0
  65. data/lib/rubygems/install_update_options.rb +56 -18
  66. data/lib/rubygems/installer.rb +244 -134
  67. data/lib/rubygems/installer_test_case.rb +71 -19
  68. data/lib/rubygems/mock_gem_ui.rb +17 -0
  69. data/lib/rubygems/name_tuple.rb +110 -0
  70. data/lib/rubygems/package.rb +514 -43
  71. data/lib/rubygems/package/digest_io.rb +64 -0
  72. data/lib/rubygems/package/old.rb +147 -0
  73. data/lib/rubygems/package/tar_header.rb +18 -55
  74. data/lib/rubygems/package/tar_reader.rb +20 -3
  75. data/lib/rubygems/package/tar_writer.rb +63 -7
  76. data/lib/rubygems/package_task.rb +3 -4
  77. data/lib/rubygems/path_support.rb +14 -7
  78. data/lib/rubygems/platform.rb +19 -26
  79. data/lib/rubygems/rdoc.rb +316 -0
  80. data/lib/rubygems/remote_fetcher.rb +117 -54
  81. data/lib/rubygems/request_set.rb +182 -0
  82. data/lib/rubygems/requirement.rb +63 -26
  83. data/lib/rubygems/security.rb +295 -555
  84. data/lib/rubygems/security/policies.rb +115 -0
  85. data/lib/rubygems/security/policy.rb +227 -0
  86. data/lib/rubygems/security/signer.rb +136 -0
  87. data/lib/rubygems/security/trust_dir.rb +104 -0
  88. data/lib/rubygems/server.rb +45 -55
  89. data/lib/rubygems/source.rb +144 -0
  90. data/lib/rubygems/source_list.rb +87 -0
  91. data/lib/rubygems/source_local.rb +92 -0
  92. data/lib/rubygems/source_specific_file.rb +28 -0
  93. data/lib/rubygems/spec_fetcher.rb +116 -184
  94. data/lib/rubygems/specification.rb +731 -335
  95. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot.pem +88 -30
  96. data/lib/rubygems/ssl_certs/Entrust_net-Secure-Server-Certification-Authority.pem +90 -0
  97. data/lib/rubygems/ssl_certs/VerisignClass3PublicPrimaryCertificationAuthority-G2.pem +57 -0
  98. data/lib/rubygems/syck_hack.rb +2 -0
  99. data/lib/rubygems/test_case.rb +199 -109
  100. data/lib/rubygems/test_utilities.rb +25 -5
  101. data/lib/rubygems/uninstaller.rb +62 -20
  102. data/lib/rubygems/user_interaction.rb +10 -0
  103. data/lib/rubygems/validator.rb +33 -40
  104. data/lib/rubygems/version.rb +19 -8
  105. data/setup.rb +8 -1
  106. data/test/rubygems/alternate_cert.pem +9 -0
  107. data/test/rubygems/alternate_cert_32.pem +9 -0
  108. data/test/rubygems/alternate_key.pem +9 -0
  109. data/test/rubygems/bad_rake.rb +1 -0
  110. data/test/rubygems/child_cert.pem +9 -0
  111. data/test/rubygems/child_cert_32.pem +9 -0
  112. data/test/rubygems/child_key.pem +9 -0
  113. data/test/rubygems/data/null-type.gemspec.rz +0 -0
  114. data/test/rubygems/expired_cert.pem +9 -0
  115. data/test/rubygems/future_cert.pem +9 -0
  116. data/test/rubygems/future_cert_32.pem +9 -0
  117. data/test/rubygems/good_rake.rb +1 -0
  118. data/test/rubygems/grandchild_cert.pem +9 -0
  119. data/test/rubygems/grandchild_cert_32.pem +9 -0
  120. data/test/rubygems/grandchild_key.pem +9 -0
  121. data/test/rubygems/invalid_issuer_cert.pem +9 -0
  122. data/test/rubygems/invalid_issuer_cert_32.pem +9 -0
  123. data/test/rubygems/invalid_key.pem +9 -0
  124. data/test/rubygems/invalid_signer_cert.pem +9 -0
  125. data/test/rubygems/invalid_signer_cert_32.pem +9 -0
  126. data/test/rubygems/invalidchild_cert.pem +9 -0
  127. data/test/rubygems/invalidchild_cert_32.pem +9 -0
  128. data/test/rubygems/invalidchild_key.pem +9 -0
  129. data/test/rubygems/plugin/exception/rubygems_plugin.rb +1 -1
  130. data/test/rubygems/plugin/standarderror/rubygems_plugin.rb +1 -1
  131. data/test/rubygems/private_key.pem +7 -25
  132. data/test/rubygems/public_cert.pem +8 -18
  133. data/test/rubygems/public_cert_32.pem +10 -0
  134. data/test/rubygems/public_key.pem +4 -0
  135. data/test/rubygems/rubygems/commands/crash_command.rb +1 -1
  136. data/test/rubygems/test_config.rb +4 -6
  137. data/test/rubygems/test_deprecate.rb +76 -0
  138. data/test/rubygems/test_gem.rb +318 -83
  139. data/test/rubygems/test_gem_available_set.rb +106 -0
  140. data/test/rubygems/test_gem_command.rb +10 -0
  141. data/test/rubygems/test_gem_command_manager.rb +55 -9
  142. data/test/rubygems/test_gem_commands_build_command.rb +11 -19
  143. data/test/rubygems/test_gem_commands_cert_command.rb +441 -42
  144. data/test/rubygems/test_gem_commands_cleanup_command.rb +29 -1
  145. data/test/rubygems/test_gem_commands_contents_command.rb +23 -0
  146. data/test/rubygems/test_gem_commands_dependency_command.rb +5 -0
  147. data/test/rubygems/test_gem_commands_fetch_command.rb +19 -20
  148. data/test/rubygems/test_gem_commands_generate_index_command.rb +2 -83
  149. data/test/rubygems/test_gem_commands_help_command.rb +2 -1
  150. data/test/rubygems/test_gem_commands_install_command.rb +647 -48
  151. data/test/rubygems/test_gem_commands_mirror.rb +32 -0
  152. data/test/rubygems/test_gem_commands_owner_command.rb +4 -8
  153. data/test/rubygems/test_gem_commands_pristine_command.rb +99 -4
  154. data/test/rubygems/test_gem_commands_push_command.rb +62 -8
  155. data/test/rubygems/test_gem_commands_query_command.rb +51 -0
  156. data/test/rubygems/test_gem_commands_search_command.rb +25 -0
  157. data/test/rubygems/test_gem_commands_setup_command.rb +45 -0
  158. data/test/rubygems/test_gem_commands_sources_command.rb +21 -6
  159. data/test/rubygems/test_gem_commands_specification_command.rb +33 -1
  160. data/test/rubygems/test_gem_commands_uninstall_command.rb +91 -31
  161. data/test/rubygems/test_gem_commands_unpack_command.rb +3 -3
  162. data/test/rubygems/test_gem_commands_update_command.rb +56 -38
  163. data/test/rubygems/test_gem_commands_which_command.rb +4 -4
  164. data/test/rubygems/test_gem_commands_yank_command.rb +97 -0
  165. data/test/rubygems/test_gem_config_file.rb +66 -21
  166. data/test/rubygems/test_gem_dependency.rb +46 -0
  167. data/test/rubygems/test_gem_dependency_installer.rb +228 -18
  168. data/test/rubygems/test_gem_dependency_list.rb +0 -9
  169. data/test/rubygems/test_gem_dependency_resolver.rb +327 -0
  170. data/test/rubygems/test_gem_ext_configure_builder.rb +4 -4
  171. data/test/rubygems/test_gem_ext_ext_conf_builder.rb +21 -49
  172. data/test/rubygems/test_gem_ext_rake_builder.rb +13 -13
  173. data/test/rubygems/test_gem_gem_runner.rb +27 -5
  174. data/test/rubygems/test_gem_gemcutter_utilities.rb +19 -0
  175. data/test/rubygems/test_gem_indexer.rb +14 -227
  176. data/test/rubygems/test_gem_install_update_options.rb +83 -3
  177. data/test/rubygems/test_gem_installer.rb +211 -236
  178. data/test/rubygems/test_gem_local_remote_options.rb +8 -2
  179. data/test/rubygems/test_gem_name_tuple.rb +15 -0
  180. data/test/rubygems/test_gem_package.rb +547 -0
  181. data/test/rubygems/test_gem_package_old.rb +37 -0
  182. data/test/rubygems/test_gem_package_tar_reader.rb +32 -0
  183. data/test/rubygems/test_gem_package_tar_writer.rb +84 -1
  184. data/test/rubygems/test_gem_path_support.rb +4 -30
  185. data/test/rubygems/test_gem_platform.rb +3 -6
  186. data/test/rubygems/test_gem_rdoc.rb +245 -0
  187. data/test/rubygems/test_gem_remote_fetcher.rb +51 -5
  188. data/test/rubygems/test_gem_request_set.rb +70 -0
  189. data/test/rubygems/test_gem_requirement.rb +53 -24
  190. data/test/rubygems/test_gem_security.rb +189 -43
  191. data/test/rubygems/test_gem_security_policy.rb +376 -0
  192. data/test/rubygems/test_gem_security_signer.rb +184 -0
  193. data/test/rubygems/test_gem_security_trust_dir.rb +94 -0
  194. data/test/rubygems/test_gem_server.rb +31 -36
  195. data/test/rubygems/test_gem_silent_ui.rb +2 -2
  196. data/test/rubygems/test_gem_source.rb +188 -0
  197. data/test/rubygems/test_gem_source_list.rb +87 -0
  198. data/test/rubygems/test_gem_source_local.rb +83 -0
  199. data/test/rubygems/test_gem_source_specific_file.rb +33 -0
  200. data/test/rubygems/test_gem_spec_fetcher.rb +91 -255
  201. data/test/rubygems/test_gem_specification.rb +293 -39
  202. data/test/rubygems/test_gem_uninstaller.rb +136 -13
  203. data/test/rubygems/test_gem_validator.rb +14 -41
  204. data/test/rubygems/test_gem_version.rb +15 -21
  205. data/test/rubygems/test_require.rb +193 -0
  206. data/test/rubygems/wrong_key_cert.pem +9 -0
  207. data/test/rubygems/wrong_key_cert_32.pem +9 -0
  208. metadata +171 -83
  209. metadata.gz.sig +1 -0
  210. data/CVE-2013-4287.txt +0 -36
  211. data/CVE-2013-4363.txt +0 -45
  212. data/ci_build.sh +0 -27
  213. data/cruise_config.rb +0 -32
  214. data/lib/rbconfig/datadir.rb +0 -13
  215. data/lib/rubygems/builder.rb +0 -99
  216. data/lib/rubygems/custom_require.rb +0 -69
  217. data/lib/rubygems/doc_manager.rb +0 -243
  218. data/lib/rubygems/format.rb +0 -82
  219. data/lib/rubygems/gem_openssl.rb +0 -90
  220. data/lib/rubygems/gem_path_searcher.rb +0 -172
  221. data/lib/rubygems/old_format.rb +0 -153
  222. data/lib/rubygems/package/f_sync_dir.rb +0 -23
  223. data/lib/rubygems/package/tar_input.rb +0 -234
  224. data/lib/rubygems/package/tar_output.rb +0 -146
  225. data/lib/rubygems/require_paths_builder.rb +0 -18
  226. data/lib/rubygems/source_index.rb +0 -406
  227. data/lib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem +0 -25
  228. data/lib/rubygems/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem +0 -14
  229. data/lib/rubygems/ssl_certs/DigiCertHighAssuranceEVRootCA.pem +0 -23
  230. data/lib/rubygems/ssl_certs/EntrustnetSecureServerCertificationAuthority.pem +0 -28
  231. data/lib/rubygems/ssl_certs/GeoTrustGlobalCA.pem +0 -20
  232. data/test/rubygems/test_bundled_ca.rb +0 -59
  233. data/test/rubygems/test_gem_builder.rb +0 -44
  234. data/test/rubygems/test_gem_doc_manager.rb +0 -32
  235. data/test/rubygems/test_gem_ext_builder.rb +0 -58
  236. data/test/rubygems/test_gem_format.rb +0 -88
  237. data/test/rubygems/test_gem_gem_path_searcher.rb +0 -94
  238. data/test/rubygems/test_gem_package_tar_input.rb +0 -129
  239. data/test/rubygems/test_gem_package_tar_output.rb +0 -101
  240. data/test/rubygems/test_gem_source_index.rb +0 -250
  241. data/util/update_bundled_ca_certificates.rb +0 -103
@@ -0,0 +1,95 @@
1
+ module Gem
2
+ class AvailableSet
3
+ Tuple = Struct.new(:spec, :source)
4
+
5
+ def initialize
6
+ @set = []
7
+ @sorted = nil
8
+ end
9
+
10
+ attr_reader :set
11
+
12
+ def add(spec, source)
13
+ @set << Tuple.new(spec, source)
14
+ @sorted = nil
15
+ self
16
+ end
17
+
18
+ def <<(o)
19
+ case o
20
+ when AvailableSet
21
+ s = o.set
22
+ when Array
23
+ s = o.map do |sp,so|
24
+ if !sp.kind_of?(Specification) or !so.kind_of?(Source)
25
+ raise TypeError, "Array must be in [[spec, source], ...] form"
26
+ end
27
+
28
+ Tuple.new(sp,so)
29
+ end
30
+ else
31
+ raise TypeError, "Must be an AvailableSet"
32
+ end
33
+
34
+ @set += s
35
+ @sorted = nil
36
+
37
+ self
38
+ end
39
+
40
+ def empty?
41
+ @set.empty?
42
+ end
43
+
44
+ def all_specs
45
+ @set.map { |t| t.spec }
46
+ end
47
+
48
+ def match_platform!
49
+ @set.reject! { |t| !Gem::Platform.match(t.spec.platform) }
50
+ @sorted = nil
51
+ self
52
+ end
53
+
54
+ def sorted
55
+ @sorted ||= @set.sort do |a,b|
56
+ i = b.spec <=> a.spec
57
+ i != 0 ? i : (a.source <=> b.source)
58
+ end
59
+ end
60
+
61
+ def size
62
+ @set.size
63
+ end
64
+
65
+ def source_for(spec)
66
+ f = @set.find { |t| t.spec == spec }
67
+ f.source
68
+ end
69
+
70
+ def pick_best!
71
+ return self if empty?
72
+
73
+ @set = [sorted.first]
74
+ @sorted = nil
75
+ self
76
+ end
77
+
78
+ def remove_installed!(dep)
79
+ @set.reject! do |t|
80
+ # already locally installed
81
+ Gem::Specification.any? do |installed_spec|
82
+ dep.name == installed_spec.name and
83
+ dep.requirement.satisfied_by? installed_spec.version
84
+ end
85
+ end
86
+
87
+ @sorted = nil
88
+ self
89
+ end
90
+
91
+ def inject_into_list(dep_list)
92
+ @set.each { |t| dep_list.add t.spec }
93
+ end
94
+ end
95
+ end
@@ -5,11 +5,12 @@
5
5
  #++
6
6
 
7
7
  require 'optparse'
8
+ require 'rubygems/requirement'
8
9
  require 'rubygems/user_interaction'
9
10
 
10
11
  ##
11
12
  # Base class for all Gem commands. When creating a new gem command, define
12
- # #new, #execute, #arguments, #defaults_str, #description and #usage
13
+ # #initialize, #execute, #arguments, #defaults_str, #description and #usage
13
14
  # (as appropriate). See the above mentioned methods for details.
14
15
  #
15
16
  # A very good example to look at is Gem::Commands::ContentsCommand
@@ -150,8 +151,9 @@ class Gem::Command
150
151
 
151
152
  def show_lookup_failure(gem_name, version, errors, domain)
152
153
  if errors and !errors.empty?
153
- alert_error "Could not find a valid gem '#{gem_name}' (#{version}), here is why:"
154
- errors.each { |x| say " #{x.wordy}" }
154
+ msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n"
155
+ errors.each { |x| msg << " #{x.wordy}\n" }
156
+ alert_error msg
155
157
  else
156
158
  alert_error "Could not find a valid gem '#{gem_name}' (#{version}) in any repository"
157
159
  end
@@ -179,6 +181,21 @@ class Gem::Command
179
181
  args.select { |arg| arg !~ /^-/ }
180
182
  end
181
183
 
184
+ ##
185
+ # Get all [gem, version] from the command line.
186
+ #
187
+ # An argument in the form gem:ver is pull apart into the gen name and version,
188
+ # respectively.
189
+ def get_all_gem_names_and_versions
190
+ get_all_gem_names.map do |name|
191
+ if /\A(.*):(#{Gem::Requirement::PATTERN_RAW})\z/ =~ name
192
+ [$1, $2]
193
+ else
194
+ [name]
195
+ end
196
+ end
197
+ end
198
+
182
199
  ##
183
200
  # Get a single gem name from the command line. Fail if there is no gem name
184
201
  # or if there is more than one gem name given.
@@ -268,8 +285,18 @@ class Gem::Command
268
285
  # Invoke the command with the given list of arguments.
269
286
 
270
287
  def invoke(*args)
288
+ invoke_with_build_args args, nil
289
+ end
290
+
291
+ ##
292
+ # Invoke the command with the given list of normal arguments
293
+ # and additional build arguments.
294
+
295
+ def invoke_with_build_args(args, build_args)
271
296
  handle_options args
272
297
 
298
+ options[:build_args] = build_args
299
+
273
300
  if options[:help] then
274
301
  show_help
275
302
  elsif @when_invoked then
@@ -344,7 +371,7 @@ class Gem::Command
344
371
 
345
372
  def handle_options(args)
346
373
  args = add_extra_args(args)
347
- @options = @defaults.clone
374
+ @options = Marshal.load Marshal.dump @defaults # deep copy
348
375
  parser.parse!(args)
349
376
  @options[:args] = args
350
377
  end
@@ -372,18 +399,23 @@ class Gem::Command
372
399
 
373
400
  private
374
401
 
375
- ##
376
- # Create on demand parser.
402
+ def add_parser_description # :nodoc:
403
+ return unless description
377
404
 
378
- def parser
379
- create_option_parser if @parser.nil?
380
- @parser
381
- end
405
+ formatted = description.split("\n\n").map do |chunk|
406
+ wrap chunk, 80 - 4
407
+ end.join "\n"
382
408
 
383
- def create_option_parser
384
- @parser = OptionParser.new
409
+ @parser.separator nil
410
+ @parser.separator " Description:"
411
+ formatted.split("\n").each do |line|
412
+ @parser.separator " #{line.rstrip}"
413
+ end
414
+ end
385
415
 
416
+ def add_parser_options # :nodoc:
386
417
  @parser.separator nil
418
+
387
419
  regular_options = @option_groups.delete :options
388
420
 
389
421
  configure_options "", regular_options
@@ -392,45 +424,56 @@ class Gem::Command
392
424
  @parser.separator nil
393
425
  configure_options group_name, option_list
394
426
  end
427
+ end
395
428
 
396
- @parser.separator nil
397
- configure_options "Common", Gem::Command.common_options
429
+ ##
430
+ # Adds a section with +title+ and +content+ to the parser help view. Used
431
+ # for adding command arguments and default arguments.
398
432
 
399
- unless arguments.empty?
400
- @parser.separator nil
401
- @parser.separator " Arguments:"
402
- arguments.split(/\n/).each do |arg_desc|
403
- @parser.separator " #{arg_desc}"
404
- end
405
- end
433
+ def add_parser_run_info title, content
434
+ return if content.empty?
406
435
 
407
- if @summary then
408
- @parser.separator nil
409
- @parser.separator " Summary:"
410
- wrap(@summary, 80 - 4).split("\n").each do |line|
411
- @parser.separator " #{line.strip}"
412
- end
436
+ @parser.separator nil
437
+ @parser.separator " #{title}:"
438
+ content.split(/\n/).each do |line|
439
+ @parser.separator " #{line}"
413
440
  end
441
+ end
414
442
 
415
- if description then
416
- formatted = description.split("\n\n").map do |chunk|
417
- wrap chunk, 80 - 4
418
- end.join "\n"
443
+ def add_parser_summary # :nodoc:
444
+ return unless @summary
419
445
 
420
- @parser.separator nil
421
- @parser.separator " Description:"
422
- formatted.split("\n").each do |line|
423
- @parser.separator " #{line.rstrip}"
424
- end
446
+ @parser.separator nil
447
+ @parser.separator " Summary:"
448
+ wrap(@summary, 80 - 4).split("\n").each do |line|
449
+ @parser.separator " #{line.strip}"
425
450
  end
451
+ end
426
452
 
427
- unless defaults_str.empty?
428
- @parser.separator nil
429
- @parser.separator " Defaults:"
430
- defaults_str.split(/\n/).each do |line|
431
- @parser.separator " #{line}"
432
- end
433
- end
453
+ ##
454
+ # Create on demand parser.
455
+
456
+ def parser
457
+ create_option_parser if @parser.nil?
458
+ @parser
459
+ end
460
+
461
+ ##
462
+ # Creates an option parser and fills it in with the help info for the
463
+ # command.
464
+
465
+ def create_option_parser
466
+ @parser = OptionParser.new
467
+
468
+ add_parser_options
469
+
470
+ @parser.separator nil
471
+ configure_options "Common", Gem::Command.common_options
472
+
473
+ add_parser_run_info "Arguments", arguments
474
+ add_parser_summary
475
+ add_parser_description
476
+ add_parser_run_info "Defaults", defaults_str
434
477
  end
435
478
 
436
479
  def configure_options(header, option_list)
@@ -521,7 +564,7 @@ basic help message containing pointers to more information.
521
564
  http://localhost:8808/
522
565
  with info about installed gems
523
566
  Further information:
524
- http://rubygems.rubyforge.org
567
+ http://guides.rubygems.org
525
568
  HELP
526
569
 
527
570
  # :startdoc:
@@ -529,7 +572,7 @@ basic help message containing pointers to more information.
529
572
  end
530
573
 
531
574
  ##
532
- # This is where Commands will be placed in the namespace
575
+ # \Commands will be placed in this namespace
533
576
 
534
577
  module Gem::Commands
535
578
  end
@@ -18,12 +18,15 @@ require 'rubygems/user_interaction'
18
18
  # # file rubygems_plugin.rb
19
19
  # require 'rubygems/command_manager'
20
20
  #
21
+ # Gem::CommandManager.instance.register_command :edit
22
+ #
23
+ # You should put the implementation of your command in rubygems/commands.
24
+ #
25
+ # # file rubygems/commands/edit_command.rb
21
26
  # class Gem::Commands::EditCommand < Gem::Command
22
27
  # # ...
23
28
  # end
24
29
  #
25
- # Gem::CommandManager.instance.register_command :edit
26
- #
27
30
  # See Gem::Command for instructions on writing gem commands.
28
31
 
29
32
  class Gem::CommandManager
@@ -37,6 +40,14 @@ class Gem::CommandManager
37
40
  @command_manager ||= new
38
41
  end
39
42
 
43
+ ##
44
+ # Returns self. Allows a CommandManager instance to stand
45
+ # in for the class itself.
46
+
47
+ def instance
48
+ self
49
+ end
50
+
40
51
  ##
41
52
  # Reset the authoritative instance of the command manager.
42
53
 
@@ -63,6 +74,7 @@ class Gem::CommandManager
63
74
  register_command :install
64
75
  register_command :list
65
76
  register_command :lock
77
+ register_command :mirror
66
78
  register_command :outdated
67
79
  register_command :owner
68
80
  register_command :pristine
@@ -78,13 +90,14 @@ class Gem::CommandManager
78
90
  register_command :unpack
79
91
  register_command :update
80
92
  register_command :which
93
+ register_command :yank
81
94
  end
82
95
 
83
96
  ##
84
97
  # Register the Symbol +command+ as a gem command.
85
98
 
86
- def register_command(command)
87
- @commands[command] = false
99
+ def register_command(command, obj=false)
100
+ @commands[command] = obj
88
101
  end
89
102
 
90
103
  ##
@@ -95,7 +108,7 @@ class Gem::CommandManager
95
108
  end
96
109
 
97
110
  ##
98
- # Return the registered command from the command name.
111
+ # Returns a Command instance for +command_name+
99
112
 
100
113
  def [](command_name)
101
114
  command_name = command_name.intern
@@ -104,56 +117,69 @@ class Gem::CommandManager
104
117
  end
105
118
 
106
119
  ##
107
- # Return a sorted list of all command names (as strings).
120
+ # Return a sorted list of all command names as strings.
108
121
 
109
122
  def command_names
110
123
  @commands.keys.collect {|key| key.to_s}.sort
111
124
  end
112
125
 
113
126
  ##
114
- # Run the config specified by +args+.
127
+ # Run the command specified by +args+.
115
128
 
116
- def run(args)
117
- process_args(args)
129
+ def run(args, build_args=nil)
130
+ process_args(args, build_args)
118
131
  rescue StandardError, Timeout::Error => ex
119
132
  alert_error "While executing gem ... (#{ex.class})\n #{ex.to_s}"
120
- ui.errs.puts "\t#{ex.backtrace.join "\n\t"}" if
121
- Gem.configuration.backtrace
133
+ ui.backtrace ex
134
+
135
+ if Gem.configuration.really_verbose and \
136
+ ex.kind_of?(Gem::Exception) and ex.source_exception
137
+ e = ex.source_exception
138
+
139
+ ui.errs.puts "Because of: (#{e.class})\n #{e.to_s}"
140
+ ui.backtrace e
141
+ end
142
+
122
143
  terminate_interaction(1)
123
144
  rescue Interrupt
124
145
  alert_error "Interrupted"
125
146
  terminate_interaction(1)
126
147
  end
127
148
 
128
- def process_args(args)
149
+ def process_args(args, build_args=nil)
129
150
  args = args.to_str.split(/\s+/) if args.respond_to?(:to_str)
130
- if args.size == 0
151
+
152
+ if args.empty? then
131
153
  say Gem::Command::HELP
132
- terminate_interaction(1)
154
+ terminate_interaction 1
133
155
  end
134
- case args[0]
135
- when '-h', '--help'
156
+
157
+ case args.first
158
+ when '-h', '--help' then
136
159
  say Gem::Command::HELP
137
- terminate_interaction(0)
138
- when '-v', '--version'
160
+ terminate_interaction 0
161
+ when '-v', '--version' then
139
162
  say Gem::VERSION
140
- terminate_interaction(0)
141
- when /^-/
142
- alert_error "Invalid option: #{args[0]}. See 'gem --help'."
143
- terminate_interaction(1)
163
+ terminate_interaction 0
164
+ when /^-/ then
165
+ alert_error "Invalid option: #{args.first}. See 'gem --help'."
166
+ terminate_interaction 1
144
167
  else
145
168
  cmd_name = args.shift.downcase
146
- cmd = find_command(cmd_name)
147
- cmd.invoke(*args)
169
+ cmd = find_command cmd_name
170
+ cmd.invoke_with_build_args args, build_args
148
171
  end
149
172
  end
150
173
 
151
174
  def find_command(cmd_name)
152
175
  possibilities = find_command_possibilities cmd_name
176
+
153
177
  if possibilities.size > 1 then
154
- raise "Ambiguous command #{cmd_name} matches [#{possibilities.join(', ')}]"
155
- elsif possibilities.size < 1 then
156
- raise "Unknown command #{cmd_name}"
178
+ raise Gem::CommandLineError,
179
+ "Ambiguous command #{cmd_name} " \
180
+ "matches [#{possibilities.join(', ')}]"
181
+ elsif possibilities.empty? then
182
+ raise Gem::CommandLineError, "Unknown command #{cmd_name}"
157
183
  end
158
184
 
159
185
  self[possibilities.first]
@@ -162,7 +188,11 @@ class Gem::CommandManager
162
188
  def find_command_possibilities(cmd_name)
163
189
  len = cmd_name.length
164
190
 
165
- command_names.select { |n| cmd_name == n[0, len] }
191
+ found = command_names.select { |name| cmd_name == name[0, len] }
192
+
193
+ exact = found.find { |name| name == cmd_name }
194
+
195
+ exact ? [exact] : found
166
196
  end
167
197
 
168
198
  private
@@ -170,23 +200,20 @@ class Gem::CommandManager
170
200
  def load_and_instantiate(command_name)
171
201
  command_name = command_name.to_s
172
202
  const_name = command_name.capitalize.gsub(/_(.)/) { $1.upcase } << "Command"
173
- commands = Gem::Commands
174
- retried = false
203
+ load_error = nil
175
204
 
176
205
  begin
177
- commands.const_get(const_name).new
178
- rescue NameError
179
- raise if retried
180
-
181
- retried = true
182
206
  begin
183
207
  require "rubygems/commands/#{command_name}_command"
184
- rescue Exception => e
185
- alert_error "Loading command: #{command_name} (#{e.class})\n #{e}"
186
- ui.errs.puts "\t#{e.backtrace.join "\n\t"}" if
187
- Gem.configuration.backtrace
208
+ rescue LoadError => e
209
+ load_error = e
188
210
  end
189
- retry
211
+ Gem::Commands.const_get(const_name).new
212
+ rescue Exception => e
213
+ e = load_error if load_error
214
+
215
+ alert_error "Loading command: #{command_name} (#{e.class})\n\t#{e}"
216
+ ui.backtrace e
190
217
  end
191
218
  end
192
219