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,6 +1,7 @@
1
1
  require 'rubygems/remote_fetcher'
2
2
 
3
3
  module Gem::GemcutterUtilities
4
+ # TODO: move to Gem::Command
4
5
  OptionParser.accept Symbol do |value|
5
6
  value.to_sym
6
7
  end
@@ -19,6 +20,8 @@ module Gem::GemcutterUtilities
19
20
  def api_key
20
21
  if options[:key] then
21
22
  verify_api_key options[:key]
23
+ elsif Gem.configuration.api_keys.key?(host)
24
+ Gem.configuration.api_keys[host]
22
25
  else
23
26
  Gem.configuration.rubygems_api_key
24
27
  end
@@ -44,12 +47,24 @@ module Gem::GemcutterUtilities
44
47
  end
45
48
  end
46
49
 
47
- def rubygems_api_request(method, path, host = Gem.host, &block)
50
+ attr_writer :host
51
+ def host
52
+ configured_host = Gem.host unless
53
+ Gem.configuration.disable_default_gem_server
54
+
55
+ @host ||= ENV['RUBYGEMS_HOST'] || configured_host
56
+ end
57
+
58
+ def rubygems_api_request(method, path, host = nil, &block)
48
59
  require 'net/http'
49
- host = ENV['RUBYGEMS_HOST'] if ENV['RUBYGEMS_HOST']
50
- uri = URI.parse "#{host}/#{path}"
51
60
 
52
- say "Pushing gem to #{host}..."
61
+ self.host = host if host
62
+ unless self.host
63
+ alert_error "You must specify a gem server"
64
+ terminate_interaction 1 # TODO: question this
65
+ end
66
+
67
+ uri = URI.parse "#{self.host}/#{path}"
53
68
 
54
69
  request_method = Net::HTTP.const_get method.to_s.capitalize
55
70
 
@@ -66,7 +81,7 @@ module Gem::GemcutterUtilities
66
81
  end
67
82
  else
68
83
  say resp.body
69
- terminate_interaction 1
84
+ terminate_interaction 1 # TODO: question this
70
85
  end
71
86
  end
72
87
 
@@ -74,8 +89,8 @@ module Gem::GemcutterUtilities
74
89
  if Gem.configuration.api_keys.key? key then
75
90
  Gem.configuration.api_keys[key]
76
91
  else
77
- alert_error "No such API key. You can add it with gem keys --add #{key}"
78
- terminate_interaction 1
92
+ alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)."
93
+ terminate_interaction 1 # TODO: question this
79
94
  end
80
95
  end
81
96
 
@@ -1,5 +1,5 @@
1
1
  require 'rubygems'
2
- require 'rubygems/format'
2
+ require 'rubygems/package'
3
3
  require 'time'
4
4
 
5
5
  begin
@@ -15,11 +15,6 @@ class Gem::Indexer
15
15
 
16
16
  include Gem::UserInteraction
17
17
 
18
- ##
19
- # Build indexes for RubyGems older than 1.2.0 when true
20
-
21
- attr_accessor :build_legacy
22
-
23
18
  ##
24
19
  # Build indexes for RubyGems 1.2.0 and newer when true
25
20
 
@@ -63,15 +58,10 @@ class Gem::Indexer
63
58
  "\n\tgem install builder"
64
59
  end
65
60
 
66
- options = { :build_legacy => true, :build_modern => true }.merge options
61
+ options = { :build_modern => true }.merge options
67
62
 
68
- @build_legacy = options[:build_legacy]
69
63
  @build_modern = options[:build_modern]
70
64
 
71
- @rss_title = options[:rss_title]
72
- @rss_host = options[:rss_host]
73
- @rss_gems_host = options[:rss_gems_host]
74
-
75
65
  @dest_directory = directory
76
66
  @directory = File.join(Dir.tmpdir, "gem_generate_index_#{$$}")
77
67
 
@@ -99,8 +89,6 @@ class Gem::Indexer
99
89
  @dest_prerelease_specs_index =
100
90
  File.join(@dest_directory, "prerelease_specs.#{Gem.marshal_version}")
101
91
 
102
- @rss_index = File.join @directory, 'index.rss'
103
-
104
92
  @files = []
105
93
  end
106
94
 
@@ -109,6 +97,8 @@ class Gem::Indexer
109
97
  # searching, downloading and related activities and do not need deployment
110
98
  # specific information (e.g. list of files). So we abbreviate the spec,
111
99
  # making it much smaller for quicker downloads.
100
+ #--
101
+ # TODO move to Gem::Specification
112
102
 
113
103
  def abbreviate(spec)
114
104
  spec.files = []
@@ -123,37 +113,15 @@ class Gem::Indexer
123
113
  # Build various indicies
124
114
 
125
115
  def build_indicies
126
- # Marshal gemspecs are used by both modern and legacy RubyGems
127
-
128
116
  Gem::Specification.dirs = []
129
117
  Gem::Specification.add_specs(*map_gems_to_specs(gem_file_list))
130
118
 
131
119
  build_marshal_gemspecs
132
- build_legacy_indicies if @build_legacy
133
120
  build_modern_indicies if @build_modern
134
- build_rss
135
121
 
136
122
  compress_indicies
137
123
  end
138
124
 
139
- ##
140
- # Builds indicies for RubyGems older than 1.2.x
141
-
142
- def build_legacy_indicies
143
- index = collect_specs
144
-
145
- say "Generating Marshal master index"
146
-
147
- Gem.time 'Generated Marshal master index' do
148
- open @marshal_index, 'wb' do |io|
149
- io.write index.dump
150
- end
151
- end
152
-
153
- @files << @marshal_index
154
- @files << "#{@marshal_index}.Z"
155
- end
156
-
157
125
  ##
158
126
  # Builds Marshal quick index gemspecs.
159
127
 
@@ -238,104 +206,6 @@ class Gem::Indexer
238
206
  "#{@prerelease_specs_index}.gz"]
239
207
  end
240
208
 
241
- ##
242
- # Builds an RSS feed for past two days gem releases according to the gem's
243
- # date.
244
-
245
- def build_rss
246
- if @rss_host.nil? or @rss_gems_host.nil? then
247
- if Gem.configuration.really_verbose then
248
- alert_warning "no --rss-host or --rss-gems-host, RSS generation disabled"
249
- end
250
- return
251
- end
252
-
253
- require 'cgi'
254
- require 'rubygems/text'
255
-
256
- extend Gem::Text
257
-
258
- Gem.time 'Generated rss' do
259
- open @rss_index, 'wb' do |io|
260
- rss_host = CGI.escapeHTML @rss_host
261
- rss_title = CGI.escapeHTML(@rss_title || 'gems')
262
-
263
- io.puts <<-HEADER
264
- <?xml version="1.0"?>
265
- <rss version="2.0">
266
- <channel>
267
- <title>#{rss_title}</title>
268
- <link>http://#{rss_host}</link>
269
- <description>Recently released gems from http://#{rss_host}</description>
270
- <generator>RubyGems v#{Gem::VERSION}</generator>
271
- <docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
272
- HEADER
273
-
274
- today = Gem::Specification::TODAY
275
- yesterday = today - 86400
276
-
277
- index = Gem::Specification.select do |spec|
278
- spec_date = spec.date
279
- # TODO: remove this and make YAML based specs properly normalized
280
- spec_date = Time.parse(spec_date.to_s) if Date === spec_date
281
-
282
- spec_date >= yesterday && spec_date <= today
283
- end
284
-
285
- index.sort_by { |spec| [-spec.date.to_i, spec] }.each do |spec|
286
- file_name = File.basename spec.cache_file
287
- gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{file_name}"
288
- size = File.stat(spec.loaded_from).size # rescue next
289
-
290
- description = spec.description || spec.summary || ''
291
- authors = Array spec.authors
292
- emails = Array spec.email
293
- authors = emails.zip(authors).map do |email, author|
294
- email += " (#{author})" if author and not author.empty?
295
- end.join ', '
296
-
297
- description = description.split(/\n\n+/).map do |chunk|
298
- format_text chunk, 78
299
- end
300
-
301
- description = description.join "\n\n"
302
-
303
- item = ''
304
-
305
- item << <<-ITEM
306
- <item>
307
- <title>#{CGI.escapeHTML spec.full_name}</title>
308
- <description>
309
- &lt;pre&gt;#{CGI.escapeHTML description.chomp}&lt;/pre&gt;
310
- </description>
311
- <author>#{CGI.escapeHTML authors}</author>
312
- <guid>#{CGI.escapeHTML spec.full_name}</guid>
313
- <enclosure url=\"#{gem_path}\"
314
- length=\"#{size}\" type=\"application/octet-stream\" />
315
- <pubDate>#{spec.date.rfc2822}</pubDate>
316
- ITEM
317
-
318
- item << <<-ITEM if spec.homepage
319
- <link>#{CGI.escapeHTML spec.homepage}</link>
320
- ITEM
321
-
322
- item << <<-ITEM
323
- </item>
324
- ITEM
325
-
326
- io.puts item
327
- end
328
-
329
- io.puts <<-FOOTER
330
- </channel>
331
- </rss>
332
- FOOTER
333
- end
334
- end
335
-
336
- @files << @rss_index
337
- end
338
-
339
209
  def map_gems_to_specs gems
340
210
  gems.map { |gemfile|
341
211
  if File.size(gemfile) == 0 then
@@ -344,7 +214,7 @@ class Gem::Indexer
344
214
  end
345
215
 
346
216
  begin
347
- spec = Gem::Format.from_file_by_path(gemfile).spec
217
+ spec = Gem::Package.new(gemfile).spec
348
218
  spec.loaded_from = gemfile
349
219
 
350
220
  # HACK: fuck this shit - borks all tests that use pl1
@@ -373,21 +243,6 @@ class Gem::Indexer
373
243
  }.compact
374
244
  end
375
245
 
376
- ##
377
- # Collect specifications from .gem files from the gem directory.
378
-
379
- def collect_specs(gems = gem_file_list)
380
- Gem::Deprecate.skip_during do
381
- index = Gem::SourceIndex.new
382
-
383
- map_gems_to_specs(gems).each do |spec|
384
- index.add_spec spec, spec.original_name
385
- end
386
-
387
- index
388
- end
389
- end
390
-
391
246
  ##
392
247
  # Compresses indicies on disk
393
248
  #--
@@ -397,11 +252,6 @@ class Gem::Indexer
397
252
  say "Compressing indicies"
398
253
 
399
254
  Gem.time 'Compressed indicies' do
400
- if @build_legacy then
401
- compress @marshal_index, 'Z'
402
- paranoid @marshal_index, 'Z'
403
- end
404
-
405
255
  if @build_modern then
406
256
  gzip @specs_index
407
257
  gzip @latest_specs_index
@@ -559,12 +409,9 @@ class Gem::Indexer
559
409
  end
560
410
 
561
411
  ##
562
- # Perform an in-place update of the repository from newly added gems. Only
563
- # works for modern indicies, and sets #build_legacy to false when run.
412
+ # Perform an in-place update of the repository from newly added gems.
564
413
 
565
414
  def update_index
566
- @build_legacy = false
567
-
568
415
  make_temp_directories
569
416
 
570
417
  specs_mtime = File.stat(@dest_specs_index).mtime
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rubygems/user_interaction'
3
+
4
+ ##
5
+ # A default post-install hook that displays "Successfully installed
6
+ # some_gem-1.0"
7
+
8
+ Gem.post_install do |installer|
9
+ ui = Gem::DefaultUserInteraction.ui
10
+ ui.say "Successfully installed #{installer.spec.full_name}"
11
+ end
12
+
@@ -22,6 +22,7 @@ module Gem::InstallUpdateOptions
22
22
  # Add the install/update options to the option parser.
23
23
 
24
24
  def add_install_update_options
25
+ # TODO: use @parser.accept
25
26
  OptionParser.accept Gem::Security::Policy do |value|
26
27
  require 'rubygems/security'
27
28
 
@@ -39,21 +40,49 @@ module Gem::InstallUpdateOptions
39
40
  end
40
41
 
41
42
  add_option(:"Install/Update", '-n', '--bindir DIR',
42
- 'Directory where binary files are',
43
- 'located') do |value, options|
43
+ 'Directory where binary files are',
44
+ 'located') do |value, options|
44
45
  options[:bin_dir] = File.expand_path(value)
45
46
  end
46
47
 
47
- add_option(:"Install/Update", '-d', '--[no-]rdoc',
48
- 'Generate RDoc documentation for the gem on',
49
- 'install') do |value, options|
50
- options[:generate_rdoc] = value
48
+ add_option(:"Install/Update", '--[no-]document [TYPES]', Array,
49
+ 'Generate documentation for installed gems',
50
+ 'List the documentation types you wish to',
51
+ 'generate. For example: rdoc,ri') do |value, options|
52
+ options[:document] = case value
53
+ when nil then %w[ri]
54
+ when false then []
55
+ else value
56
+ end
51
57
  end
52
58
 
53
- add_option(:"Install/Update", '--[no-]ri',
54
- 'Generate RI documentation for the gem on',
55
- 'install') do |value, options|
56
- options[:generate_ri] = value
59
+ add_option(:"Install/Update", '-N', '--no-document',
60
+ 'Disable documentation generation') do |value, options|
61
+ options[:document] = []
62
+ end
63
+
64
+ add_option(:Deprecated, '--[no-]rdoc',
65
+ 'Generate RDoc for installed gems',
66
+ 'Use --document instead') do |value, options|
67
+ if value then
68
+ options[:document] << 'rdoc'
69
+ else
70
+ options[:document].delete 'rdoc'
71
+ end
72
+
73
+ options[:document].uniq!
74
+ end
75
+
76
+ add_option(:Deprecated, '--[no-]ri',
77
+ 'Generate ri data for installed gems.',
78
+ 'Use --document instead') do |value, options|
79
+ if value then
80
+ options[:document] << 'ri'
81
+ else
82
+ options[:document].delete 'ri'
83
+ end
84
+
85
+ options[:document].uniq!
57
86
  end
58
87
 
59
88
  add_option(:"Install/Update", '-E', '--[no-]env-shebang',
@@ -85,12 +114,6 @@ module Gem::InstallUpdateOptions
85
114
  options[:ignore_dependencies] = value
86
115
  end
87
116
 
88
- add_option(:"Install/Update", '-y', '--include-dependencies',
89
- 'Unconditionally install the required',
90
- 'dependent gems') do |value, options|
91
- options[:include_dependencies] = value
92
- end
93
-
94
117
  add_option(:"Install/Update", '--[no-]format-executable',
95
118
  'Make installed executable names match ruby.',
96
119
  'If ruby is ruby18, foo_exec will be',
@@ -105,15 +128,30 @@ module Gem::InstallUpdateOptions
105
128
  end
106
129
 
107
130
  add_option(:"Install/Update", "--development",
108
- "Install any additional development",
131
+ "Install additional development",
109
132
  "dependencies") do |value, options|
110
133
  options[:development] = true
134
+ options[:dev_shallow] = true
135
+ end
136
+
137
+ add_option(:"Install/Update", "--development-all",
138
+ "Install development dependencies for all",
139
+ "gems (including dev deps themselves)") do |value, options|
140
+ options[:development] = true
141
+ options[:dev_shallow] = false
111
142
  end
112
143
 
113
144
  add_option(:"Install/Update", "--conservative",
114
145
  "Don't attempt to upgrade gems already",
115
146
  "meeting version requirement") do |value, options|
116
147
  options[:conservative] = true
148
+ options[:minimal_deps] = true
149
+ end
150
+
151
+ add_option(:"Install/Update", "--minimal-deps",
152
+ "Don't upgrade any dependencies that already",
153
+ "meet version requirements") do |value, options|
154
+ options[:minimal_deps] = true
117
155
  end
118
156
  end
119
157
 
@@ -121,7 +159,7 @@ module Gem::InstallUpdateOptions
121
159
  # Default options for the gem install command.
122
160
 
123
161
  def install_update_defaults_str
124
- '--rdoc --no-force --wrappers'
162
+ '--document=rdoc,ri --wrappers'
125
163
  end
126
164
 
127
165
  end
@@ -4,15 +4,13 @@
4
4
  # See LICENSE.txt for permissions.
5
5
  #++
6
6
 
7
- require 'rubygems/format'
8
7
  require 'rubygems/exceptions'
8
+ require 'rubygems/package'
9
9
  require 'rubygems/ext'
10
- require 'rubygems/require_paths_builder'
11
10
  require 'rubygems/user_interaction'
12
11
 
13
12
  ##
14
- # The installer class processes RubyGem .gem files and installs the files
15
- # contained in the .gem into the Gem.path.
13
+ # The installer installs the files contained in the .gem into the Gem.home.
16
14
  #
17
15
  # Gem::Installer does the work of putting files in all the right places on the
18
16
  # filesystem including unpacking the gem into its gem dir, installing the
@@ -39,8 +37,7 @@ class Gem::Installer
39
37
 
40
38
  include Gem::UserInteraction
41
39
 
42
- include Gem::RequirePathsBuilder if Gem::QUICKLOADER_SUCKAGE
43
-
40
+ # DOC: Missing docs or :nodoc:.
44
41
  attr_reader :gem
45
42
 
46
43
  ##
@@ -67,6 +64,7 @@ class Gem::Installer
67
64
 
68
65
  attr_accessor :path_warning
69
66
 
67
+ # DOC: Missing docs or :nodoc:.
70
68
  attr_writer :exec_format
71
69
 
72
70
  # Defaults to use Ruby's program prefix and suffix.
@@ -80,24 +78,36 @@ class Gem::Installer
80
78
  # Constructs an Installer instance that will install the gem located at
81
79
  # +gem+. +options+ is a Hash with the following keys:
82
80
  #
81
+ # :bin_dir:: Where to put a bin wrapper if needed.
82
+ # :development:: Whether or not development dependencies should be installed.
83
83
  # :env_shebang:: Use /usr/bin/env in bin wrappers.
84
84
  # :force:: Overrides all version checks and security policy checks, except
85
85
  # for a signed-gems-only policy.
86
- # :ignore_dependencies:: Don't raise if a dependency is missing.
87
- # :install_dir:: The directory to install the gem into.
88
86
  # :format_executable:: Format the executable the same as the ruby executable.
89
87
  # If your ruby is ruby18, foo_exec will be installed as
90
88
  # foo_exec18.
89
+ # :ignore_dependencies:: Don't raise if a dependency is missing.
90
+ # :install_dir:: The directory to install the gem into.
91
91
  # :security_policy:: Use the specified security policy. See Gem::Security
92
+ # :user_install:: Indicate that the gem should be unpacked into the users
93
+ # personal gem directory.
94
+ # :only_install_dir:: Only validate dependencies against what is in the
95
+ # install_dir
92
96
  # :wrappers:: Install wrappers if true, symlinks if false.
97
+ # :build_args:: An Array of arguments to pass to the extension builder
98
+ # process. If not set, then Gem::Command.build_args is used
93
99
 
94
100
  def initialize(gem, options={})
95
101
  require 'fileutils'
96
102
 
97
103
  @gem = gem
98
104
  @options = options
105
+ @package = Gem::Package.new @gem
106
+
99
107
  process_options
100
108
 
109
+ @package.security_policy = @security_policy
110
+
101
111
  if options[:user_install] and not options[:unpack] then
102
112
  @gem_home = Gem.user_dir
103
113
  check_that_user_bin_dir_is_in_path
@@ -105,28 +115,79 @@ class Gem::Installer
105
115
  end
106
116
 
107
117
  ##
108
- # Lazy accessor for the spec's gem directory.
118
+ # Checks if +filename+ exists in +@bin_dir+.
119
+ #
120
+ # If +@force+ is set +filename+ is overwritten.
121
+ #
122
+ # If +filename+ exists and is a RubyGems wrapper for different gem the user
123
+ # is consulted.
124
+ #
125
+ # If +filename+ exists and +@bin_dir+ is Gem.default_bindir (/usr/local) the
126
+ # user is consulted.
127
+ #
128
+ # Otherwise +filename+ is overwritten.
109
129
 
110
- def gem_dir
111
- @gem_dir ||= spec.gem_dir.dup.untaint
130
+ def check_executable_overwrite filename # :nodoc:
131
+ return if @force
132
+
133
+ generated_bin = File.join @bin_dir, filename
134
+
135
+ return unless File.exist? generated_bin
136
+
137
+ ruby_executable = false
138
+ existing = nil
139
+
140
+ open generated_bin, 'rb' do |io|
141
+ next unless io.gets =~ /^#!/ # shebang
142
+ io.gets # blankline
143
+
144
+ # TODO detect a specially formatted comment instead of trying
145
+ # to run a regexp against ruby code.
146
+ next unless io.gets =~ /This file was generated by RubyGems/
147
+
148
+ ruby_executable = true
149
+ existing = io.read.slice(/^gem (['"])(.*?)(\1),/, 2)
150
+ end
151
+
152
+ return if spec.name == existing
153
+
154
+ # somebody has written to RubyGems' directory, overwrite, too bad
155
+ return if Gem.default_bindir != @bin_dir and not ruby_executable
156
+
157
+ question = "#{spec.name}'s executable \"#{filename}\" conflicts with "
158
+
159
+ if ruby_executable then
160
+ question << existing
161
+
162
+ return if ask_yes_no "#{question}\nOverwrite the executable?", false
163
+
164
+ conflict = "installed executable from #{existing}"
165
+ else
166
+ question << generated_bin
167
+
168
+ return if ask_yes_no "#{question}\nOverwrite the executable?", false
169
+
170
+ conflict = generated_bin
171
+ end
172
+
173
+ raise Gem::InstallError,
174
+ "\"#{filename}\" from #{spec.name} conflicts with #{conflict}"
112
175
  end
113
176
 
114
177
  ##
115
- # Lazy accessor for the installer's Gem::Format instance.
178
+ # Lazy accessor for the spec's gem directory.
116
179
 
117
- def format
118
- begin
119
- @format ||= Gem::Format.from_file_by_path gem, @security_policy
120
- rescue Gem::Package::FormatError
121
- raise Gem::InstallError, "invalid gem format for #{gem}"
122
- end
180
+ def gem_dir
181
+ @gem_dir ||= File.join(gem_home, "gems", spec.full_name)
123
182
  end
124
183
 
125
184
  ##
126
185
  # Lazy accessor for the installer's spec.
127
186
 
128
187
  def spec
129
- @spec ||= format.spec
188
+ @spec ||= @package.spec
189
+ rescue Gem::Package::Error => e
190
+ raise Gem::InstallError, "invalid gem: #{e.message}"
130
191
  end
131
192
 
132
193
  ##
@@ -141,11 +202,7 @@ class Gem::Installer
141
202
  # specifications/<gem-version>.gemspec #=> the Gem::Specification
142
203
 
143
204
  def install
144
- current_home = Gem.dir
145
- current_path = Gem.paths.path
146
-
147
205
  verify_gem_home(options[:unpack])
148
- Gem.use_paths gem_home, current_path # HACK: shouldn't need Gem.paths.path
149
206
 
150
207
  # If we're forcing the install then disable security unless the security
151
208
  # policy says that we only install signed gems.
@@ -158,65 +215,96 @@ class Gem::Installer
158
215
  ensure_dependencies_met unless @ignore_dependencies
159
216
  end
160
217
 
161
- Gem.pre_install_hooks.each do |hook|
162
- result = hook.call self
163
-
164
- if result == false then
165
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
166
-
167
- message = "pre-install hook#{location} failed for #{spec.full_name}"
168
- raise Gem::InstallError, message
169
- end
170
- end
218
+ run_pre_install_hooks
171
219
 
172
220
  Gem.ensure_gem_subdirectories gem_home
173
221
 
174
222
  # Completely remove any previous gem files
175
- FileUtils.rm_rf(gem_dir) if File.exist? gem_dir
223
+ FileUtils.rm_rf(gem_dir)
176
224
 
177
225
  FileUtils.mkdir_p gem_dir
178
226
 
179
227
  extract_files
180
228
  build_extensions
181
229
 
182
- Gem.post_build_hooks.each do |hook|
183
- result = hook.call self
184
-
185
- if result == false then
186
- FileUtils.rm_rf gem_dir
230
+ run_post_build_hooks
187
231
 
188
- location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
232
+ generate_bin
233
+ write_spec
189
234
 
190
- message = "post-build hook#{location} failed for #{spec.full_name}"
191
- raise Gem::InstallError, message
235
+ unless @build_args.empty?
236
+ File.open spec.build_info_file, "w" do |f|
237
+ @build_args.each { |a| f.puts a }
192
238
  end
193
239
  end
194
240
 
195
- generate_bin
196
- write_spec
197
-
198
- write_require_paths_file_if_needed if Gem::QUICKLOADER_SUCKAGE
241
+ # TODO should be always cache the file? Other classes have options
242
+ # to controls if caching is done.
243
+ cache_file = File.join(gem_home, "cache", "#{spec.full_name}.gem")
199
244
 
200
- cache_file = spec.cache_file
201
245
  FileUtils.cp gem, cache_file unless File.exist? cache_file
202
246
 
203
247
  say spec.post_install_message unless spec.post_install_message.nil?
204
248
 
205
- spec.loaded_from = spec.spec_file
249
+ spec.loaded_from = spec_file
206
250
 
207
251
  Gem::Specification.add_spec spec unless Gem::Specification.include? spec
208
252
 
253
+ run_post_install_hooks
254
+
255
+ spec
256
+
257
+ # TODO This rescue is in the wrong place. What is raising this exception?
258
+ # move this rescue to arround the code that actually might raise it.
259
+ rescue Zlib::GzipFile::Error
260
+ raise Gem::InstallError, "gzip error installing #{gem}"
261
+ end
262
+
263
+ def run_pre_install_hooks # :nodoc:
264
+ Gem.pre_install_hooks.each do |hook|
265
+ if hook.call(self) == false then
266
+ location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
267
+
268
+ message = "pre-install hook#{location} failed for #{spec.full_name}"
269
+ raise Gem::InstallError, message
270
+ end
271
+ end
272
+ end
273
+
274
+ def run_post_build_hooks # :nodoc:
275
+ Gem.post_build_hooks.each do |hook|
276
+ if hook.call(self) == false then
277
+ FileUtils.rm_rf gem_dir
278
+
279
+ location = " at #{$1}" if hook.inspect =~ /@(.*:\d+)/
280
+
281
+ message = "post-build hook#{location} failed for #{spec.full_name}"
282
+ raise Gem::InstallError, message
283
+ end
284
+ end
285
+ end
286
+
287
+ def run_post_install_hooks # :nodoc:
209
288
  Gem.post_install_hooks.each do |hook|
210
289
  hook.call self
211
290
  end
291
+ end
212
292
 
213
- return spec
214
- rescue Zlib::GzipFile::Error
215
- raise Gem::InstallError, "gzip error installing #{gem}"
216
- ensure
217
- # conditional since we might be here because we're erroring out early.
218
- if current_path
219
- Gem.use_paths current_home, current_path
293
+ ##
294
+ #
295
+ # Return an Array of Specifications contained within the gem_home
296
+ # we'll be installing into.
297
+
298
+ def installed_specs
299
+ @specs ||= begin
300
+ specs = []
301
+
302
+ Dir[File.join(gem_home, "specifications", "*.gemspec")].each do |path|
303
+ spec = Gem::Specification.load path.untaint
304
+ specs << spec if spec
305
+ end
306
+
307
+ specs
220
308
  end
221
309
  end
222
310
 
@@ -235,9 +323,11 @@ class Gem::Installer
235
323
  end
236
324
 
237
325
  ##
238
- # True if the gems in the source_index satisfy +dependency+.
326
+ # True if the gems in the system satisfy +dependency+.
239
327
 
240
328
  def installation_satisfies_dependency?(dependency)
329
+ return true if installed_specs.detect { |s| dependency.matches_spec? s }
330
+ return false if @only_install_dir
241
331
  not dependency.matching_specs.empty?
242
332
  end
243
333
 
@@ -246,18 +336,23 @@ class Gem::Installer
246
336
 
247
337
  def unpack(directory)
248
338
  @gem_dir = directory
249
- @format = Gem::Format.from_file_by_path gem, @security_policy
250
339
  extract_files
251
340
  end
252
341
 
342
+ ##
343
+ # The location of of the spec file that is installed.
344
+ #
345
+
346
+ def spec_file
347
+ File.join gem_home, "specifications", "#{spec.full_name}.gemspec"
348
+ end
349
+
253
350
  ##
254
351
  # Writes the .gemspec specification (in Ruby) to the gem home's
255
352
  # specifications directory.
256
353
 
257
354
  def write_spec
258
- file_name = spec.spec_file.untaint
259
-
260
- File.open(file_name, "w") do |file|
355
+ File.open(spec_file, "w") do |file|
261
356
  file.puts spec.to_ruby_for_cache
262
357
  end
263
358
  end
@@ -277,34 +372,34 @@ class Gem::Installer
277
372
  end
278
373
  end
279
374
 
375
+ # DOC: Missing docs or :nodoc:.
280
376
  def generate_bin
281
377
  return if spec.executables.nil? or spec.executables.empty?
282
378
 
283
- # If the user has asked for the gem to be installed in a directory that is
284
- # the system gem directory, then use the system bin directory, else create
285
- # (or use) a new bin dir under the gem_home.
286
- bindir = @bin_dir || Gem.bindir(gem_home)
287
-
288
- Dir.mkdir bindir unless File.exist? bindir
289
- raise Gem::FilePermissionError.new(bindir) unless File.writable? bindir
379
+ Dir.mkdir @bin_dir unless File.exist? @bin_dir
380
+ raise Gem::FilePermissionError.new(@bin_dir) unless File.writable? @bin_dir
290
381
 
291
382
  spec.executables.each do |filename|
292
383
  filename.untaint
293
- bin_path = File.expand_path File.join(gem_dir, spec.bindir, filename)
384
+ bin_path = File.join gem_dir, spec.bindir, filename
294
385
 
295
- unless File.exist? bin_path
296
- warn "Hey?!?! Where did #{bin_path} go??"
386
+ unless File.exist? bin_path then
387
+ # TODO change this to a more useful warning
388
+ warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
297
389
  next
298
390
  end
299
391
 
300
392
  mode = File.stat(bin_path).mode | 0111
301
393
  FileUtils.chmod mode, bin_path
302
394
 
395
+ check_executable_overwrite filename
396
+
303
397
  if @wrappers then
304
- generate_bin_script filename, bindir
398
+ generate_bin_script filename, @bin_dir
305
399
  else
306
- generate_bin_symlink filename, bindir
400
+ generate_bin_symlink filename, @bin_dir
307
401
  end
402
+
308
403
  end
309
404
  end
310
405
 
@@ -358,10 +453,21 @@ class Gem::Installer
358
453
  ##
359
454
  # Generates a #! line for +bin_file_name+'s wrapper copying arguments if
360
455
  # necessary.
456
+ #
457
+ # If the :custom_shebang config is set, then it is used as a template
458
+ # for how to create the shebang used for to run a gem's executables.
459
+ #
460
+ # The template supports 4 expansions:
461
+ #
462
+ # $env the path to the unix env utility
463
+ # $ruby the path to the currently running ruby interpreter
464
+ # $exec the path to the gem's executable
465
+ # $name the name of the gem the executable is for
466
+ #
361
467
 
362
468
  def shebang(bin_file_name)
363
469
  ruby_name = Gem::ConfigMap[:ruby_install_name] if @env_shebang
364
- path = spec.bin_file bin_file_name
470
+ path = File.join gem_dir, spec.bindir, bin_file_name
365
471
  first_line = File.open(path, "rb") {|file| file.gets}
366
472
 
367
473
  if /\A#!/ =~ first_line then
@@ -371,7 +477,25 @@ class Gem::Installer
371
477
  shebang.strip! # Avoid nasty ^M issues.
372
478
  end
373
479
 
374
- if not ruby_name then
480
+ if which = Gem.configuration[:custom_shebang]
481
+ # replace bin_file_name with "ruby" to avoid endless loops
482
+ which = which.gsub(/ #{bin_file_name}$/," #{Gem::ConfigMap[:ruby_install_name]}")
483
+
484
+ which = which.gsub(/\$(\w+)/) do
485
+ case $1
486
+ when "env"
487
+ @env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
488
+ when "ruby"
489
+ "#{Gem.ruby}#{opts}"
490
+ when "exec"
491
+ bin_file_name
492
+ when "name"
493
+ spec.name
494
+ end
495
+ end
496
+
497
+ "#!#{which}"
498
+ elsif not ruby_name then
375
499
  "#!#{Gem.ruby}#{opts}"
376
500
  elsif opts then
377
501
  "#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
@@ -382,6 +506,7 @@ class Gem::Installer
382
506
  end
383
507
  end
384
508
 
509
+ # DOC: Missing docs or :nodoc:.
385
510
  def ensure_required_ruby_version_met
386
511
  if rrv = spec.required_ruby_version then
387
512
  unless rrv.satisfied_by? Gem.ruby_version then
@@ -390,9 +515,10 @@ class Gem::Installer
390
515
  end
391
516
  end
392
517
 
518
+ # DOC: Missing docs or :nodoc:.
393
519
  def ensure_required_rubygems_version_met
394
520
  if rrgv = spec.required_rubygems_version then
395
- unless rrgv.satisfied_by? Gem::Version.new(Gem::VERSION) then
521
+ unless rrgv.satisfied_by? Gem.rubygems_version then
396
522
  raise Gem::InstallError,
397
523
  "#{spec.name} requires RubyGems version #{rrgv}. " +
398
524
  "Try 'gem update --system' to update RubyGems itself."
@@ -400,6 +526,7 @@ class Gem::Installer
400
526
  end
401
527
  end
402
528
 
529
+ # DOC: Missing docs or :nodoc:.
403
530
  def ensure_dependencies_met
404
531
  deps = spec.runtime_dependencies
405
532
  deps |= spec.development_dependencies if @development
@@ -409,13 +536,14 @@ class Gem::Installer
409
536
  end
410
537
  end
411
538
 
539
+ # DOC: Missing docs or :nodoc:.
412
540
  def process_options
413
541
  @options = {
414
542
  :bin_dir => nil,
415
543
  :env_shebang => false,
416
- :exec_format => false,
417
544
  :force => false,
418
545
  :install_dir => Gem.dir,
546
+ :only_install_dir => false
419
547
  }.merge options
420
548
 
421
549
  @env_shebang = options[:env_shebang]
@@ -425,13 +553,18 @@ class Gem::Installer
425
553
  @format_executable = options[:format_executable]
426
554
  @security_policy = options[:security_policy]
427
555
  @wrappers = options[:wrappers]
428
- @bin_dir = options[:bin_dir]
556
+ @only_install_dir = options[:only_install_dir]
557
+
558
+ # If the user has asked for the gem to be installed in a directory that is
559
+ # the system gem directory, then use the system bin directory, else create
560
+ # (or use) a new bin dir under the gem_home.
561
+ @bin_dir = options[:bin_dir] || Gem.bindir(gem_home)
429
562
  @development = options[:development]
430
563
 
431
- raise "NOTE: Installer option :source_index is dead" if
432
- options[:source_index]
564
+ @build_args = options[:build_args] || Gem::Command.build_args
433
565
  end
434
566
 
567
+ # DOC: Missing docs or :nodoc:.
435
568
  def check_that_user_bin_dir_is_in_path
436
569
  user_bin_dir = @bin_dir || Gem.bindir(gem_home)
437
570
  user_bin_dir.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
@@ -449,6 +582,7 @@ class Gem::Installer
449
582
  end
450
583
  end
451
584
 
585
+ # DOC: Missing docs or :nodoc:.
452
586
  def verify_gem_home(unpack = false)
453
587
  FileUtils.mkdir_p gem_home
454
588
  raise Gem::FilePermissionError, gem_home unless
@@ -499,7 +633,6 @@ GOTO :EOF
499
633
  :WinNT
500
634
  @"#{ruby}" "%~dpn0" %*
501
635
  TEXT
502
-
503
636
  end
504
637
 
505
638
  ##
@@ -508,7 +641,14 @@ TEXT
508
641
 
509
642
  def build_extensions
510
643
  return if spec.extensions.empty?
511
- say "Building native extensions. This could take a while..."
644
+
645
+ if @build_args.empty?
646
+ say "Building native extensions. This could take a while..."
647
+ else
648
+ say "Building native extensions with: '#{@build_args.join(' ')}'"
649
+ say "This could take a while..."
650
+ end
651
+
512
652
  dest_path = File.join gem_dir, spec.require_paths.first
513
653
  ran_rake = false # only run rake once
514
654
 
@@ -516,6 +656,9 @@ TEXT
516
656
  break if ran_rake
517
657
  results = []
518
658
 
659
+ extension ||= ""
660
+ extension_dir = File.join gem_dir, File.dirname(extension)
661
+
519
662
  builder = case extension
520
663
  when /extconf/ then
521
664
  Gem::Ext::ExtConfBuilder
@@ -525,45 +668,41 @@ TEXT
525
668
  ran_rake = true
526
669
  Gem::Ext::RakeBuilder
527
670
  else
528
- results = ["No builder for extension '#{extension}'"]
529
- nil
671
+ message = "No builder for extension '#{extension}'"
672
+ extension_build_error extension_dir, message
530
673
  end
531
674
 
532
-
533
- extension_dir = begin
534
- File.join gem_dir, File.dirname(extension)
535
- rescue TypeError # extension == nil
536
- gem_dir
537
- end
538
-
539
-
540
675
  begin
541
- Gem::Ext::Builder::CHDIR_MUTEX.synchronize do
542
- Dir.chdir extension_dir do
543
- results = builder.build(extension, gem_dir, dest_path, results)
676
+ Dir.chdir extension_dir do
677
+ results = builder.build(extension, gem_dir, dest_path,
678
+ results, @build_args)
544
679
 
545
- say results.join("\n") if Gem.configuration.really_verbose
546
- end
680
+ say results.join("\n") if Gem.configuration.really_verbose
547
681
  end
548
682
  rescue
549
- results = results.join "\n"
683
+ extension_build_error(extension_dir, results.join("\n"))
684
+ end
685
+ end
686
+ end
550
687
 
551
- gem_make_out = File.join extension_dir, 'gem_make.out'
688
+ ##
689
+ # Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
690
+
691
+ def extension_build_error(build_dir, output)
692
+ gem_make_out = File.join build_dir, 'gem_make.out'
552
693
 
553
- open gem_make_out, 'wb' do |io| io.puts results end
694
+ open gem_make_out, 'wb' do |io| io.puts output end
554
695
 
555
- message = <<-EOF
696
+ message = <<-EOF
556
697
  ERROR: Failed to build gem native extension.
557
698
 
558
- #{results}
699
+ #{output}
559
700
 
560
701
  Gem files will remain installed in #{gem_dir} for inspection.
561
702
  Results logged to #{gem_make_out}
562
703
  EOF
563
704
 
564
- raise ExtensionBuildError, message
565
- end
566
- end
705
+ raise ExtensionBuildError, message
567
706
  end
568
707
 
569
708
  ##
@@ -572,36 +711,7 @@ EOF
572
711
  # Ensures that files can't be installed outside the gem directory.
573
712
 
574
713
  def extract_files
575
- raise ArgumentError, "format required to extract from" if @format.nil?
576
-
577
- @format.file_entries.each do |entry, file_data|
578
- path = entry['path'].untaint
579
-
580
- if path.start_with? "/" then # for extra sanity
581
- raise Gem::InstallError, "attempt to install file into #{entry['path']}"
582
- end
583
-
584
- path = File.expand_path File.join(gem_dir, path)
585
-
586
- unless path.start_with? gem_dir then
587
- msg = "attempt to install file into %p under %s" %
588
- [entry['path'], gem_dir]
589
- raise Gem::InstallError, msg
590
- end
591
-
592
- FileUtils.rm_rf(path) if File.exist? path
593
-
594
- dir = File.dirname path
595
- FileUtils.mkdir_p dir unless File.exist? dir
596
-
597
- File.open(path, "wb") do |out|
598
- out.write file_data
599
- end
600
-
601
- FileUtils.chmod entry['mode'], path
602
-
603
- say path if Gem.configuration.really_verbose
604
- end
714
+ @package.extract_files gem_dir
605
715
  end
606
716
 
607
717
  ##