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
@@ -1,4 +1,5 @@
1
1
  ##
2
+ #
2
3
  # Gem::PathSupport facilitates the GEM_HOME and GEM_PATH environment settings
3
4
  # to the rest of RubyGems.
4
5
  #
@@ -42,16 +43,18 @@ class Gem::PathSupport
42
43
  # Set the Gem search path (as reported by Gem.path).
43
44
 
44
45
  def path=(gpaths)
45
- gem_path = [@home]
46
+ # FIX: it should be [home, *path], not [*path, home]
47
+
48
+ gem_path = []
46
49
 
47
50
  # FIX: I can't tell wtf this is doing.
48
51
  gpaths ||= (ENV['GEM_PATH'] || "").empty? ? nil : ENV["GEM_PATH"]
49
52
 
50
- if gpaths then
51
- if gpaths.kind_of?(Array) then
52
- gem_path.push(*gpaths)
53
+ if gpaths
54
+ if gpaths.kind_of?(Array)
55
+ gem_path = gpaths.dup
53
56
  else
54
- gem_path.push(*gpaths.split(File::PATH_SEPARATOR))
57
+ gem_path = gpaths.split(Gem.path_separator)
55
58
  end
56
59
 
57
60
  if File::ALT_SEPARATOR then
@@ -59,10 +62,14 @@ class Gem::PathSupport
59
62
  this_path.gsub File::ALT_SEPARATOR, File::SEPARATOR
60
63
  end
61
64
  end
65
+
66
+ gem_path << @home
62
67
  else
63
- gem_path.push(*Gem.default_path)
68
+ gem_path = Gem.default_path + [@home]
64
69
 
65
- gem_path << APPLE_GEM_HOME if defined?(APPLE_GEM_HOME)
70
+ if defined?(APPLE_GEM_HOME)
71
+ gem_path << APPLE_GEM_HOME
72
+ end
66
73
  end
67
74
 
68
75
  @path = gem_path.uniq
@@ -21,7 +21,8 @@ class Gem::Platform
21
21
 
22
22
  def self.match(platform)
23
23
  Gem.platforms.any? do |local_platform|
24
- platform.nil? or local_platform == platform or
24
+ platform.nil? or
25
+ local_platform == platform or
25
26
  (local_platform != Gem::Platform::RUBY and local_platform =~ platform)
26
27
  end
27
28
  end
@@ -65,28 +66,28 @@ class Gem::Platform
65
66
  @cpu, os = nil, cpu if os.nil? # legacy jruby
66
67
 
67
68
  @os, @version = case os
68
- when /aix(\d+)/ then [ 'aix', $1 ]
69
- when /cygwin/ then [ 'cygwin', nil ]
70
- when /darwin(\d+)?/ then [ 'darwin', $1 ]
71
- when /^macruby$/ then [ 'macruby', nil ]
72
- when /freebsd(\d+)/ then [ 'freebsd', $1 ]
73
- when /hpux(\d+)/ then [ 'hpux', $1 ]
74
- when /^java$/, /^jruby$/ then [ 'java', nil ]
75
- when /^java([\d.]*)/ then [ 'java', $1 ]
76
- when /^dotnet$/ then [ 'dotnet', nil ]
77
- when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
78
- when /linux/ then [ 'linux', $1 ]
79
- when /mingw32/ then [ 'mingw32', nil ]
69
+ when /aix(\d+)?/ then [ 'aix', $1 ]
70
+ when /cygwin/ then [ 'cygwin', nil ]
71
+ when /darwin(\d+)?/ then [ 'darwin', $1 ]
72
+ when /^macruby$/ then [ 'macruby', nil ]
73
+ when /freebsd(\d+)?/ then [ 'freebsd', $1 ]
74
+ when /hpux(\d+)?/ then [ 'hpux', $1 ]
75
+ when /^java$/, /^jruby$/ then [ 'java', nil ]
76
+ when /^java([\d.]*)/ then [ 'java', $1 ]
77
+ when /^dotnet$/ then [ 'dotnet', nil ]
78
+ when /^dotnet([\d.]*)/ then [ 'dotnet', $1 ]
79
+ when /linux/ then [ 'linux', $1 ]
80
+ when /mingw32/ then [ 'mingw32', nil ]
80
81
  when /(mswin\d+)(\_(\d+))?/ then
81
82
  os, version = $1, $3
82
83
  @cpu = 'x86' if @cpu.nil? and os =~ /32$/
83
84
  [os, version]
84
- when /netbsdelf/ then [ 'netbsdelf', nil ]
85
- when /openbsd(\d+\.\d+)/ then [ 'openbsd', $1 ]
86
- when /solaris(\d+\.\d+)/ then [ 'solaris', $1 ]
85
+ when /netbsdelf/ then [ 'netbsdelf', nil ]
86
+ when /openbsd(\d+\.\d+)?/ then [ 'openbsd', $1 ]
87
+ when /solaris(\d+\.\d+)?/ then [ 'solaris', $1 ]
87
88
  # test
88
- when /^(\w+_platform)(\d+)/ then [ $1, $2 ]
89
- else [ 'unknown', nil ]
89
+ when /^(\w+_platform)(\d+)?/ then [ $1, $2 ]
90
+ else [ 'unknown', nil ]
90
91
  end
91
92
  when Gem::Platform then
92
93
  @cpu = arch.cpu
@@ -109,10 +110,6 @@ class Gem::Platform
109
110
  to_a.compact.join '-'
110
111
  end
111
112
 
112
- def empty?
113
- to_s.empty?
114
- end
115
-
116
113
  ##
117
114
  # Is +other+ equal to this platform? Two platforms are equal if they have
118
115
  # the same CPU, OS and version.
@@ -186,9 +183,5 @@ class Gem::Platform
186
183
  # This will be replaced with Gem::Platform::local.
187
184
 
188
185
  CURRENT = 'current'
189
-
190
- extend Gem::Deprecate
191
-
192
- deprecate :empty?, :none, 2011, 11
193
186
  end
194
187
 
@@ -0,0 +1,316 @@
1
+ require 'rubygems'
2
+ require 'rubygems/user_interaction'
3
+ require 'fileutils'
4
+
5
+ begin
6
+ gem 'rdoc'
7
+ rescue Gem::LoadError
8
+ # swallow
9
+ else
10
+ # This will force any deps that 'rdoc' might have
11
+ # (such as json) that are ambigious to be activated, which
12
+ # is important because we end up using Specification.reset
13
+ # and we don't want the warning it pops out.
14
+ Gem.finish_resolve
15
+ end
16
+
17
+ loaded_hook = false
18
+
19
+ begin
20
+ require 'rdoc/rubygems_hook'
21
+ loaded_hook = true
22
+ module Gem
23
+ RDoc = RDoc::RubygemsHook
24
+ end
25
+ rescue LoadError
26
+ end
27
+
28
+ ##
29
+ # Gem::RDoc provides methods to generate RDoc and ri data for installed gems.
30
+ # It works for RDoc 1.0.1 (in Ruby 1.8) up to RDoc 3.6.
31
+ #
32
+ # This implementation is considered obsolete. The RDoc project is the
33
+ # appropriate location to find this functionality. This file provides the
34
+ # hooks to load RDoc generation code from the "rdoc" gem and a fallback in
35
+ # case the installed version of RDoc does not have them.
36
+
37
+ class Gem::RDoc # :nodoc: all
38
+
39
+ include Gem::UserInteraction
40
+
41
+ @rdoc_version = nil
42
+ @specs = []
43
+
44
+ ##
45
+ # Force installation of documentation?
46
+
47
+ attr_accessor :force
48
+
49
+ ##
50
+ # Generate rdoc?
51
+
52
+ attr_accessor :generate_rdoc
53
+
54
+ ##
55
+ # Generate ri data?
56
+
57
+ attr_accessor :generate_ri
58
+
59
+ class << self
60
+
61
+ ##
62
+ # Loaded version of RDoc. Set by ::load_rdoc
63
+
64
+ attr_reader :rdoc_version
65
+
66
+ end
67
+
68
+ ##
69
+ # Post installs hook that generates documentation for each specification in
70
+ # +specs+
71
+
72
+ def self.generation_hook installer, specs
73
+ types = installer.document
74
+
75
+ generate_rdoc = types.include? 'rdoc'
76
+ generate_ri = types.include? 'ri'
77
+
78
+ specs.each do |spec|
79
+ new(spec, generate_rdoc, generate_ri).generate
80
+ end
81
+ end
82
+
83
+ ##
84
+ # Loads the RDoc generator
85
+
86
+ def self.load_rdoc
87
+ return if @rdoc_version
88
+
89
+ begin
90
+ require 'rdoc/rdoc'
91
+
92
+ @rdoc_version = if ::RDoc.const_defined? :VERSION then
93
+ Gem::Version.new ::RDoc::VERSION
94
+ else
95
+ Gem::Version.new '1.0.1'
96
+ end
97
+
98
+ rescue LoadError => e
99
+ raise Gem::DocumentError, "RDoc is not installed: #{e}"
100
+ end
101
+ end
102
+
103
+ ##
104
+ # Creates a new documentation generator for +spec+. RDoc and ri data
105
+ # generation can be enabled or disabled through +generate_rdoc+ and
106
+ # +generate_ri+ respectively.
107
+ #
108
+ # Only +generate_ri+ is enabled by default.
109
+
110
+ def initialize spec, generate_rdoc = false, generate_ri = true
111
+ @doc_dir = spec.doc_dir
112
+ @file_info = nil
113
+ @force = false
114
+ @rdoc = nil
115
+ @spec = spec
116
+
117
+ @generate_rdoc = generate_rdoc
118
+ @generate_ri = generate_ri
119
+
120
+ @rdoc_dir = spec.doc_dir 'rdoc'
121
+ @ri_dir = spec.doc_dir 'ri'
122
+ end
123
+
124
+ ##
125
+ # Removes legacy rdoc arguments from +args+
126
+
127
+ def delete_legacy_args args
128
+ args.delete '--inline-source'
129
+ args.delete '--promiscuous'
130
+ args.delete '-p'
131
+ args.delete '--one-file'
132
+ end
133
+
134
+ ##
135
+ # Generates documentation using the named +generator+ ("darkfish" or "ri")
136
+ # and following the given +options+.
137
+ #
138
+ # Documentation will be generated into +destination+
139
+
140
+ def document generator, options, destination
141
+ options = options.dup
142
+ options.exclude ||= [] # TODO maybe move to RDoc::Options#finish
143
+ options.setup_generator generator
144
+ options.op_dir = destination
145
+ options.finish
146
+
147
+ @rdoc.options = options
148
+ @rdoc.generator = options.generator.new options
149
+
150
+ say "Installing #{generator} documentation for #{@spec.full_name}"
151
+
152
+ FileUtils.mkdir_p options.op_dir
153
+
154
+ Dir.chdir options.op_dir do
155
+ begin
156
+ @rdoc.class.current = @rdoc
157
+ @rdoc.generator.generate @file_info
158
+ ensure
159
+ @rdoc.class.current = nil
160
+ end
161
+ end
162
+ end
163
+
164
+ ##
165
+ # Generates RDoc and ri data
166
+
167
+ def generate
168
+ return unless @generate_ri or @generate_rdoc
169
+
170
+ setup
171
+
172
+ if Gem::Requirement.new('< 3').satisfied_by? self.class.rdoc_version then
173
+ generate_legacy
174
+ else
175
+ ::RDoc::TopLevel.reset # TODO ::RDoc::RDoc.reset
176
+ ::RDoc::Parser::C.reset
177
+
178
+ options = ::RDoc::Options.new
179
+ options.default_title = "#{@spec.full_name} Documentation"
180
+ options.files = []
181
+ options.files.push(*@spec.require_paths)
182
+ options.files.push(*@spec.extra_rdoc_files)
183
+
184
+ args = @spec.rdoc_options
185
+
186
+ case config_args = Gem.configuration[:rdoc]
187
+ when String then
188
+ args = args.concat config_args.split
189
+ when Array then
190
+ args = args.concat config_args
191
+ end
192
+
193
+ delete_legacy_args args
194
+ options.parse args
195
+ options.quiet = !Gem.configuration.really_verbose
196
+
197
+ @rdoc = new_rdoc
198
+ @rdoc.options = options
199
+
200
+ Dir.chdir @spec.full_gem_path do
201
+ @file_info = @rdoc.parse_files options.files
202
+ end
203
+
204
+ document 'ri', options, @ri_dir if
205
+ @generate_ri and (@force or not File.exist? @ri_dir)
206
+
207
+ document 'darkfish', options, @rdoc_dir if
208
+ @generate_rdoc and (@force or not File.exist? @rdoc_dir)
209
+ end
210
+ end
211
+
212
+ ##
213
+ # Generates RDoc and ri data for legacy RDoc versions. This method will not
214
+ # exist in future versions.
215
+
216
+ def generate_legacy
217
+ if @generate_rdoc then
218
+ FileUtils.rm_rf @rdoc_dir
219
+ say "Installing RDoc documentation for #{@spec.full_name}"
220
+ legacy_rdoc '--op', @rdoc_dir
221
+ end
222
+
223
+ if @generate_ri then
224
+ FileUtils.rm_rf @ri_dir
225
+ say "Installing ri documentation for #{@spec.full_name}"
226
+ legacy_rdoc '--ri', '--op', @ri_dir
227
+ end
228
+ end
229
+
230
+ ##
231
+ # Generates RDoc using a legacy version of RDoc from the ARGV-like +args+.
232
+ # This method will not exist in future versions.
233
+
234
+ def legacy_rdoc *args
235
+ args << @spec.rdoc_options
236
+ args << '--quiet'
237
+ args << @spec.require_paths.clone
238
+ args << @spec.extra_rdoc_files
239
+ args << '--title' << "#{@spec.full_name} Documentation"
240
+ args = args.flatten.map do |arg| arg.to_s end
241
+
242
+ delete_legacy_args args if
243
+ Gem::Requirement.new('>= 2.4.0') =~ self.class.rdoc_version
244
+
245
+ r = new_rdoc
246
+ say "rdoc #{args.join ' '}" if Gem.configuration.really_verbose
247
+
248
+ Dir.chdir @spec.full_gem_path do
249
+ begin
250
+ r.document args
251
+ rescue Errno::EACCES => e
252
+ dirname = File.dirname e.message.split("-")[1].strip
253
+ raise Gem::FilePermissionError, dirname
254
+ rescue Interrupt => e
255
+ raise e
256
+ rescue Exception => ex
257
+ alert_error "While generating documentation for #{@spec.full_name}"
258
+ ui.errs.puts "... MESSAGE: #{ex}"
259
+ ui.errs.puts "... RDOC args: #{args.join(' ')}"
260
+ ui.backtrace ex
261
+ ui.errs.puts "(continuing with the rest of the installation)"
262
+ ensure
263
+ end
264
+ end
265
+ end
266
+
267
+ ##
268
+ # #new_rdoc creates a new RDoc instance. This method is provided only to
269
+ # make testing easier.
270
+
271
+ def new_rdoc
272
+ ::RDoc::RDoc.new
273
+ end
274
+
275
+ ##
276
+ # Is rdoc documentation installed?
277
+
278
+ def rdoc_installed?
279
+ File.exist? @rdoc_dir
280
+ end
281
+
282
+ ##
283
+ # Removes generated RDoc and ri data
284
+
285
+ def remove
286
+ base_dir = @spec.base_dir
287
+
288
+ raise Gem::FilePermissionError, base_dir unless File.writable? base_dir
289
+
290
+ FileUtils.rm_rf @rdoc_dir
291
+ FileUtils.rm_rf @ri_dir
292
+ end
293
+
294
+ ##
295
+ # Is ri data installed?
296
+
297
+ def ri_installed?
298
+ File.exist? @ri_dir
299
+ end
300
+
301
+ ##
302
+ # Prepares the spec for documentation generation
303
+
304
+ def setup
305
+ self.class.load_rdoc
306
+
307
+ raise Gem::FilePermissionError, @doc_dir if
308
+ File.exist?(@doc_dir) and not File.writable?(@doc_dir)
309
+
310
+ FileUtils.mkdir_p @doc_dir unless File.exist? @doc_dir
311
+ end
312
+
313
+ end unless loaded_hook
314
+
315
+ Gem.done_installing(&Gem::RDoc.method(:generation_hook))
316
+
@@ -1,6 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'rubygems/user_interaction'
3
3
  require 'uri'
4
+ require 'resolv'
4
5
 
5
6
  ##
6
7
  # RemoteFetcher handles the details of fetching gems and gem information from
@@ -8,8 +9,6 @@ require 'uri'
8
9
 
9
10
  class Gem::RemoteFetcher
10
11
 
11
- BuiltinSSLCerts = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
12
-
13
12
  include Gem::UserInteraction
14
13
 
15
14
  ##
@@ -34,6 +33,13 @@ class Gem::RemoteFetcher
34
33
 
35
34
  end
36
35
 
36
+ ##
37
+ # A FetchError that indicates that the reason for not being
38
+ # able to fetch data was that the host could not be contacted
39
+
40
+ class UnknownHostError < FetchError
41
+ end
42
+
37
43
  @fetcher = nil
38
44
 
39
45
  ##
@@ -53,8 +59,11 @@ class Gem::RemoteFetcher
53
59
  # * nil: respect environment variables (HTTP_PROXY, HTTP_PROXY_USER,
54
60
  # HTTP_PROXY_PASS)
55
61
  # * <tt>:no_proxy</tt>: ignore environment variables and _don't_ use a proxy
62
+ #
63
+ # +dns+: An object to use for DNS resolution of the API endpoint.
64
+ # By default, use Resolv::DNS.
56
65
 
57
- def initialize(proxy = nil)
66
+ def initialize(proxy=nil, dns=Resolv::DNS.new)
58
67
  require 'net/http'
59
68
  require 'stringio'
60
69
  require 'time'
@@ -72,6 +81,27 @@ class Gem::RemoteFetcher
72
81
  else URI.parse(proxy)
73
82
  end
74
83
  @user_agent = user_agent
84
+ @env_no_proxy = get_no_proxy_from_env
85
+
86
+ @dns = dns
87
+ end
88
+
89
+ ##
90
+ #
91
+ # Given a source at +uri+, calculate what hostname to actually
92
+ # connect to query the data for it.
93
+
94
+ def api_endpoint(uri)
95
+ host = uri.host
96
+
97
+ begin
98
+ res = @dns.getresource "_rubygems._tcp.#{host}",
99
+ Resolv::DNS::Resource::IN::SRV
100
+ rescue Resolv::ResolvError
101
+ uri
102
+ else
103
+ URI.parse "#{res.target}#{uri.path}"
104
+ end
75
105
  end
76
106
 
77
107
  ##
@@ -82,14 +112,13 @@ class Gem::RemoteFetcher
82
112
  # larger, more emcompassing effort. -erikh
83
113
 
84
114
  def download_to_cache dependency
85
- found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
86
- dependency.prerelease?
115
+ found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency
87
116
 
88
117
  return if found.empty?
89
118
 
90
- spec, source_uri = found.sort_by { |(s,_)| s.version }.last
119
+ spec, source = found.sort_by { |(s,_)| s.version }.last
91
120
 
92
- download spec, source_uri
121
+ download spec, source.uri.to_s
93
122
  end
94
123
 
95
124
  ##
@@ -100,11 +129,14 @@ class Gem::RemoteFetcher
100
129
  def download(spec, source_uri, install_dir = Gem.dir)
101
130
  Gem.ensure_gem_subdirectories(install_dir) rescue nil
102
131
 
103
- if File.writable?(install_dir)
104
- cache_dir = File.join install_dir, "cache"
105
- else
106
- cache_dir = File.join Gem.user_dir, "cache"
107
- end
132
+ cache_dir =
133
+ if Dir.pwd == install_dir then # see fetch_command
134
+ install_dir
135
+ elsif File.writable? install_dir then
136
+ File.join install_dir, "cache"
137
+ else
138
+ File.join Gem.user_dir, "cache"
139
+ end
108
140
 
109
141
  gem_file_name = File.basename spec.cache_file
110
142
  local_gem_path = File.join cache_dir, gem_file_name
@@ -123,6 +155,8 @@ class Gem::RemoteFetcher
123
155
  # URI.parse gets confused by MS Windows paths with forward slashes.
124
156
  scheme = nil if scheme =~ /^[a-z]$/i
125
157
 
158
+ # REFACTOR: split this up and dispatch on scheme (eg download_http)
159
+ # REFACTOR: be sure to clean up fake fetcher when you do this... cleaner
126
160
  case scheme
127
161
  when 'http', 'https' then
128
162
  unless File.exist? local_gem_path then
@@ -132,7 +166,7 @@ class Gem::RemoteFetcher
132
166
 
133
167
  remote_gem_path = source_uri + "gems/#{gem_file_name}"
134
168
 
135
- gem = self.fetch_path remote_gem_path
169
+ self.cache_update_path remote_gem_path, local_gem_path
136
170
  rescue Gem::RemoteFetcher::FetchError
137
171
  raise if spec.original_platform == spec.platform
138
172
 
@@ -143,11 +177,7 @@ class Gem::RemoteFetcher
143
177
 
144
178
  remote_gem_path = source_uri + "gems/#{alternate_name}"
145
179
 
146
- gem = self.fetch_path remote_gem_path
147
- end
148
-
149
- File.open local_gem_path, 'wb' do |fp|
150
- fp.write gem
180
+ self.cache_update_path remote_gem_path, local_gem_path
151
181
  end
152
182
  end
153
183
  when 'file' then
@@ -184,7 +214,7 @@ class Gem::RemoteFetcher
184
214
  say "Using local gem #{local_gem_path}" if
185
215
  Gem.configuration.really_verbose
186
216
  else
187
- raise Gem::InstallError, "unsupported URI scheme #{source_uri.scheme}"
217
+ raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}"
188
218
  end
189
219
 
190
220
  local_gem_path
@@ -232,18 +262,54 @@ class Gem::RemoteFetcher
232
262
  uri = URI.parse uri unless URI::Generic === uri
233
263
 
234
264
  raise ArgumentError, "bad uri: #{uri}" unless uri
235
- raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}" unless
236
- uri.scheme
265
+
266
+ unless uri.scheme
267
+ raise ArgumentError, "uri scheme is invalid: #{uri.scheme.inspect}"
268
+ end
237
269
 
238
270
  data = send "fetch_#{uri.scheme}", uri, mtime, head
239
- data = Gem.gunzip data if data and not head and uri.to_s =~ /gz$/
271
+
272
+ if data and !head and uri.to_s =~ /gz$/
273
+ begin
274
+ data = Gem.gunzip data
275
+ rescue Zlib::GzipFile::Error
276
+ raise FetchError.new("server did not return a valid file", uri.to_s)
277
+ end
278
+ end
279
+
240
280
  data
241
281
  rescue FetchError
242
282
  raise
243
283
  rescue Timeout::Error
244
- raise FetchError.new('timed out', uri.to_s)
284
+ raise UnknownHostError.new('timed out', uri.to_s)
245
285
  rescue IOError, SocketError, SystemCallError => e
246
- raise FetchError.new("#{e.class}: #{e}", uri.to_s)
286
+ if e.message =~ /getaddrinfo/
287
+ raise UnknownHostError.new('no such name', uri.to_s)
288
+ else
289
+ raise FetchError.new("#{e.class}: #{e}", uri.to_s)
290
+ end
291
+ end
292
+
293
+ ##
294
+ # Downloads +uri+ to +path+ if necessary. If no path is given, it just
295
+ # passes the data.
296
+
297
+ def cache_update_path(uri, path = nil)
298
+ mtime = path && File.stat(path).mtime rescue nil
299
+
300
+ if mtime && Net::HTTPNotModified === fetch_path(uri, mtime, true)
301
+ Gem.read_binary(path)
302
+ else
303
+ data = fetch_path(uri)
304
+
305
+ if path
306
+ open(path, 'wb') do |io|
307
+ io.write data
308
+ end
309
+ end
310
+
311
+ data
312
+ end
247
313
  end
248
314
 
249
315
  ##
@@ -273,6 +339,17 @@ class Gem::RemoteFetcher
273
339
  URI
274
340
  end
275
341
 
342
+ ##
343
+ # Returns list of no_proxy entries (if any) from the environment
344
+
345
+ def get_no_proxy_from_env
346
+ env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
347
+
348
+ return [] if env_no_proxy.nil? or env_no_proxy.empty?
349
+
350
+ env_no_proxy.split(/\s*,\s*/)
351
+ end
352
+
276
353
  ##
277
354
  # Returns an HTTP proxy URI if one is set in the environment variables.
278
355
 
@@ -296,7 +373,7 @@ class Gem::RemoteFetcher
296
373
  # Normalize the URI by adding "http://" if it is missing.
297
374
 
298
375
  def normalize_uri(uri)
299
- (uri =~ /^(https?|ftp|file):/) ? uri : "http://#{uri}"
376
+ (uri =~ /^(https?|ftp|file):/i) ? uri : "http://#{uri}"
300
377
  end
301
378
 
302
379
  ##
@@ -306,7 +383,7 @@ class Gem::RemoteFetcher
306
383
  def connection_for(uri)
307
384
  net_http_args = [uri.host, uri.port]
308
385
 
309
- if @proxy_uri then
386
+ if @proxy_uri and not no_proxy?(uri.host) then
310
387
  net_http_args += [
311
388
  @proxy_uri.host,
312
389
  @proxy_uri.port,
@@ -319,37 +396,23 @@ class Gem::RemoteFetcher
319
396
  @connections[connection_id] ||= Net::HTTP.new(*net_http_args)
320
397
  connection = @connections[connection_id]
321
398
 
322
- if https?(uri) and !connection.started? then
399
+ if https?(uri) and not connection.started? then
323
400
  configure_connection_for_https(connection)
324
-
325
- # Don't refactor this with the else branch. We don't want the
326
- # http-only code path to not depend on anything in OpenSSL.
327
- #
328
- begin
329
- connection.start
330
- rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e
331
- raise FetchError.new(e.message, uri)
332
- end
333
- else
334
- begin
335
- connection.start unless connection.started?
336
- rescue Errno::EHOSTDOWN => e
337
- raise FetchError.new(e.message, uri)
338
- end
339
401
  end
340
402
 
403
+ connection.start unless connection.started?
404
+
341
405
  connection
406
+ rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e
407
+ raise FetchError.new(e.message, uri)
342
408
  end
343
409
 
344
410
  def configure_connection_for_https(connection)
345
411
  require 'net/https'
346
-
347
412
  connection.use_ssl = true
348
413
  connection.verify_mode =
349
414
  Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
350
-
351
415
  store = OpenSSL::X509::Store.new
352
-
353
416
  if Gem.configuration.ssl_ca_cert
354
417
  if File.directory? Gem.configuration.ssl_ca_cert
355
418
  store.add_path Gem.configuration.ssl_ca_cert
@@ -360,12 +423,12 @@ class Gem::RemoteFetcher
360
423
  store.set_default_paths
361
424
  add_rubygems_trusted_certs(store)
362
425
  end
363
-
364
426
  connection.cert_store = store
365
427
  end
366
428
 
367
429
  def add_rubygems_trusted_certs(store)
368
- Dir.glob(BuiltinSSLCerts).each do |ssl_cert_file|
430
+ pattern = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
431
+ Dir.glob(pattern).each do |ssl_cert_file|
369
432
  store.add_file ssl_cert_file
370
433
  end
371
434
  end
@@ -378,13 +441,13 @@ class Gem::RemoteFetcher
378
441
  end
379
442
  end
380
443
 
381
- ##
382
- # Read the data from the (source based) URI, but if it is a file:// URI,
383
- # read from the filesystem instead.
384
-
385
- def open_uri_or_path(uri, last_modified = nil, head = false, depth = 0)
386
- raise "NO: Use fetch_path instead"
387
- # TODO: deprecate for fetch_path
444
+ def no_proxy? host
445
+ host = host.downcase
446
+ @env_no_proxy.each do |pattern|
447
+ pattern = pattern.downcase
448
+ return true if host[-pattern.length, pattern.length ] == pattern
449
+ end
450
+ return false
388
451
  end
389
452
 
390
453
  ##