rubygems-update 1.8.30 → 2.0.0.preview2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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
  ##