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,36 +1,59 @@
1
- # -*- coding: utf-8 -*-
2
1
  #--
3
2
  # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4
3
  # All rights reserved.
5
4
  # See LICENSE.txt for permissions.
6
5
  #++
7
6
 
7
+ ##
8
+ # The Specification class contains the information for a Gem. Typically
9
+ # defined in a .gemspec file or a Rakefile, and looks like this:
10
+ #
11
+ # Gem::Specification.new do |s|
12
+ # s.name = 'example'
13
+ # s.version = '0.1.0'
14
+ # s.summary = "This is an example!"
15
+ # s.description = "Much longer explanation of the example!"
16
+ # s.authors = ["Ruby Coder"]
17
+ # s.email = 'rubycoder@example.com'
18
+ # s.files = ["lib/example.rb"]
19
+ # s.homepage = 'http://rubygems.org/gems/example'
20
+ # end
21
+ #
22
+ # Starting in RubyGems 1.9.0, a Specification can hold arbitrary
23
+ # metadata. This metadata is accessed via Specification#metadata
24
+ # and has the following restrictions:
25
+ #
26
+ # * Must be a Hash object
27
+ # * All keys and values must be Strings
28
+ # * Keys can be a maximum of 128 bytes and values can be a
29
+ # maximum of 1024 bytes
30
+ # * All strings must be UTF8, no binary data is allowed
31
+ #
32
+ # For example, to add metadata for the location of a bugtracker:
33
+ #
34
+ # s.metadata = { "bugtracker" => "http://somewhere.com/blah" }
35
+ #
36
+
37
+
8
38
  require 'rubygems/version'
9
39
  require 'rubygems/requirement'
10
40
  require 'rubygems/platform'
11
- require "rubygems/deprecate"
41
+ require 'rubygems/deprecate'
12
42
 
13
43
  # :stopdoc:
14
- class Date; end # for ruby_code if date.rb wasn't required
44
+ # date.rb can't be loaded for `make install` due to miniruby
45
+ # Date is needed for old gems that stored #date as Date instead of Time.
46
+ class Date; end
15
47
  # :startdoc:
16
48
 
17
- ##
18
- # The Specification class contains the metadata for a Gem. Typically
19
- # defined in a .gemspec file or a Rakefile, and looks like this:
20
- #
21
- # spec = Gem::Specification.new do |s|
22
- # s.name = 'example'
23
- # s.version = '1.0'
24
- # s.summary = 'Example gem specification'
25
- # ...
26
- # end
27
- #
28
- # For a great way to package gems, use Hoe.
29
-
30
49
  class Gem::Specification
31
50
 
51
+ # REFACTOR: Consider breaking out this version stuff into a separate
52
+ # module. There's enough special stuff around it that it may justify
53
+ # a separate class.
54
+
32
55
  ##
33
- # The the version number of a specification that does not specify one
56
+ # The version number of a specification that does not specify one
34
57
  # (i.e. RubyGems 0.7 or earlier).
35
58
 
36
59
  NONEXISTENT_SPECIFICATION_VERSION = -1
@@ -50,17 +73,37 @@ class Gem::Specification
50
73
  # 2 0.9.5 2007-10-01 Added "required_rubygems_version"
51
74
  # Now forward-compatible with future versions
52
75
  # 3 1.3.2 2009-01-03 Added Fixnum validation to specification_version
76
+ # 4 1.9.0 2011-06-07 Added metadata
53
77
  #--
54
78
  # When updating this number, be sure to also update #to_ruby.
55
79
  #
56
80
  # NOTE RubyGems < 1.2 cannot load specification versions > 2.
57
81
 
58
- CURRENT_SPECIFICATION_VERSION = 3
59
-
60
- # :stopdoc:
82
+ CURRENT_SPECIFICATION_VERSION = 4
83
+
84
+ ##
85
+ # An informal list of changes to the specification. The highest-valued
86
+ # key should be equal to the CURRENT_SPECIFICATION_VERSION.
87
+
88
+ SPECIFICATION_VERSION_HISTORY = {
89
+ -1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
90
+ 1 => [
91
+ 'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
92
+ '"test_file=x" is a shortcut for "test_files=[x]"'
93
+ ],
94
+ 2 => [
95
+ 'Added "required_rubygems_version"',
96
+ 'Now forward-compatible with future versions',
97
+ ],
98
+ 3 => [
99
+ 'Added Fixnum validation to the specification_version'
100
+ ],
101
+ 4 => [
102
+ 'Added sandboxed freeform metadata to the specification version.'
103
+ ]
104
+ }
61
105
 
62
- # version => # of fields
63
- MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16, 3 => 17 }
106
+ MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16, 3 => 17, 4 => 18 }
64
107
 
65
108
  today = Time.now.utc
66
109
  TODAY = Time.utc(today.year, today.month, today.day)
@@ -96,6 +139,7 @@ class Gem::Specification
96
139
  :files => [],
97
140
  :homepage => nil,
98
141
  :licenses => [],
142
+ :metadata => {},
99
143
  :name => nil,
100
144
  :platform => Gem::Platform::RUBY,
101
145
  :post_install_message => nil,
@@ -123,19 +167,37 @@ class Gem::Specification
123
167
  # :section: Required gemspec attributes
124
168
 
125
169
  ##
126
- # This gem's name
170
+ # This gem's name.
171
+ #
172
+ # Usage:
173
+ #
174
+ # spec.name = 'rake'
127
175
 
128
176
  attr_accessor :name
129
177
 
130
178
  ##
131
- # This gem's version
179
+ # This gem's version.
180
+ #
181
+ # The version string can contain numbers and periods, such as +1.0.0+.
182
+ # A gem is a 'prerelease' gem if the version has a letter in it, such as
183
+ # +1.0.0.pre+.
184
+ #
185
+ # Usage:
186
+ #
187
+ # spec.version = '0.4.1'
132
188
 
133
189
  attr_reader :version
134
190
 
135
191
  ##
136
- # Paths in the gem to add to $LOAD_PATH when this gem is activated.
192
+ # Paths in the gem to add to <tt>$LOAD_PATH</tt> when this gem is activated.
137
193
  #
138
- # The default ['lib'] is typically sufficient.
194
+ # Usage:
195
+ #
196
+ # # If all library files are in the root directory...
197
+ # spec.require_path = '.'
198
+ #
199
+ # # If you have 'lib' and 'ext' directories...
200
+ # spec.require_paths << 'ext'
139
201
 
140
202
  attr_accessor :require_paths
141
203
 
@@ -147,32 +209,113 @@ class Gem::Specification
147
209
  attr_accessor :rubygems_version
148
210
 
149
211
  ##
150
- # The Gem::Specification version of this gemspec.
212
+ # A short summary of this gem's description. Displayed in `gem list -d`.
151
213
  #
152
- # Do not set this, it is set automatically when the gem is packaged.
214
+ # The description should be more detailed than the summary.
215
+ #
216
+ # Usage:
217
+ #
218
+ # spec.summary = "This is a small summary of my gem"
153
219
 
154
- attr_accessor :specification_version
220
+ attr_reader :summary
155
221
 
156
222
  ##
157
- # A short summary of this gem's description. Displayed in `gem list -d`.
223
+ # The platform this gem runs on.
158
224
  #
159
- # The description should be more detailed than the summary. For example,
160
- # you might wish to copy the entire README into the description.
225
+ # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT.
226
+ #
227
+ # Most gems contain pure Ruby code; they should simply leave the default value
228
+ # in place. Some gems contain C (or other) code to be compiled into a Ruby
229
+ # “extension”. The should leave the default value in place unless their code
230
+ # will only compile on a certain type of system. Some gems consist of
231
+ # pre-compiled code (“binary gems”). It’s especially important that they set
232
+ # the platform attribute appropriately. A shortcut is to set the platform to
233
+ # Gem::Platform::CURRENT, which will cause the gem builder to set the platform
234
+ # to the appropriate value for the system on which the build is being performed.
235
+ #
236
+ # If this attribute is set to a non-default value, it will be included in the
237
+ # filename of the gem when it is built, e.g. fxruby-1.2.0-win32.gem.
238
+ #
239
+ # Usage:
240
+ #
241
+ # spec.platform = Gem::Platform::Win32
161
242
 
162
- attr_reader :summary
243
+ def platform= platform
244
+ if @original_platform.nil? or
245
+ @original_platform == Gem::Platform::RUBY then
246
+ @original_platform = platform
247
+ end
163
248
 
164
- ######################################################################
165
- # :section: Optional gemspec attributes
249
+ case platform
250
+ when Gem::Platform::CURRENT then
251
+ @new_platform = Gem::Platform.local
252
+ @original_platform = @new_platform.to_s
253
+
254
+ when Gem::Platform then
255
+ @new_platform = platform
256
+
257
+ # legacy constants
258
+ when nil, Gem::Platform::RUBY then
259
+ @new_platform = Gem::Platform::RUBY
260
+ when 'mswin32' then # was Gem::Platform::WIN32
261
+ @new_platform = Gem::Platform.new 'x86-mswin32'
262
+ when 'i586-linux' then # was Gem::Platform::LINUX_586
263
+ @new_platform = Gem::Platform.new 'x86-linux'
264
+ when 'powerpc-darwin' then # was Gem::Platform::DARWIN
265
+ @new_platform = Gem::Platform.new 'ppc-darwin'
266
+ else
267
+ @new_platform = Gem::Platform.new platform
268
+ end
269
+
270
+ @platform = @new_platform.to_s
271
+
272
+ invalidate_memoized_attributes
273
+
274
+ @new_platform
275
+ end
166
276
 
167
277
  ##
168
- # Autorequire was used by old RubyGems to automatically require a file.
278
+ # Files included in this gem. You cannot append to this accessor, you must
279
+ # assign to it.
169
280
  #
170
- # Deprecated: It is neither supported nor functional.
281
+ # Only add files you can require to this list, not directories, etc.
282
+ #
283
+ # Directories are automatically stripped from this list when building a gem,
284
+ # other non-files cause an error.
285
+ #
286
+ # Usage:
287
+ #
288
+ # require 'rake'
289
+ # spec.files = FileList['lib/**/*.rb',
290
+ # 'bin/*',
291
+ # '[A-Z]*',
292
+ # 'test/**/*'].to_a
293
+ #
294
+ # # or without Rake...
295
+ # spec.files = Dir['lib/**/*.rb'] + Dir['bin/*']
296
+ # spec.files += Dir['[A-Z]*'] + Dir['test/**/*']
297
+ # spec.files.reject! { |fn| fn.include? "CVS" }
171
298
 
172
- attr_accessor :autorequire
299
+ def files
300
+ # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
301
+ # DOC: Why isn't it normal? Why does it suck? How can we fix this?
302
+ @files = [@files,
303
+ @test_files,
304
+ add_bindir(@executables),
305
+ @extra_rdoc_files,
306
+ @extensions,
307
+ ].flatten.uniq.compact
308
+ end
309
+
310
+ ######################################################################
311
+ # :section: Optional gemspec attributes
173
312
 
174
313
  ##
175
314
  # The path in the gem for executable scripts. Usually 'bin'
315
+ #
316
+ # Usage:
317
+ #
318
+ # spec.bindir = 'bin'
176
319
 
177
320
  attr_accessor :bindir
178
321
 
@@ -184,39 +327,241 @@ class Gem::Specification
184
327
 
185
328
  ##
186
329
  # A long description of this gem
330
+ #
331
+ # The description should be more detailed than the summary.
332
+ #
333
+ # Usage:
334
+ #
335
+ # spec.description = <<-EOF
336
+ # Rake is a Make-like program implemented in Ruby. Tasks and
337
+ # dependencies are specified in standard Ruby syntax.
338
+ # EOF
187
339
 
188
340
  attr_reader :description
189
341
 
190
342
  ##
191
- # Sets the default executable for this gem.
343
+ # A contact email for this gem
192
344
  #
193
- # Deprecated: You must now specify the executable name to Gem.bin_path.
345
+ # Usage:
346
+ #
347
+ # spec.email = 'john.jones@example.com'
348
+ # spec.email = ['jack@example.com', 'jill@example.com']
194
349
 
195
- attr_writer :default_executable
350
+ attr_accessor :email
196
351
 
197
352
  ##
198
- # A contact email for this gem
353
+ # The URL of this gem's home page
199
354
  #
200
- # If you are providing multiple authors and multiple emails they should be
201
- # in the same order such that:
355
+ # Usage:
356
+ #
357
+ # spec.homepage = 'http://rake.rubyforge.org'
358
+
359
+ attr_accessor :homepage
360
+
361
+ ##
362
+ # A message that gets displayed after the gem is installed.
202
363
  #
203
- # Hash[*spec.authors.zip(spec.emails).flatten]
364
+ # Usage:
204
365
  #
205
- # Gives a hash of author name to email address.
366
+ # spec.post_install_message = "Thanks for installing!"
206
367
 
207
- attr_accessor :email
368
+ attr_accessor :post_install_message
208
369
 
209
370
  ##
210
- # The URL of this gem's home page
371
+ # The key used to sign this gem. See Gem::Security for details.
211
372
 
212
- attr_accessor :homepage
373
+ attr_accessor :signing_key
213
374
 
214
375
  ##
215
- # True when this gemspec has been activated. This attribute is not persisted.
376
+ # :attr_accessor: metadata
377
+ #
378
+ # Arbitrary metadata for this gem. An instance of Hash.
379
+ #
380
+ # metadata is simply a Symbol => String association that contains arbitary
381
+ # data that could be useful to other consumers.
382
+
383
+ attr_accessor :metadata
384
+
385
+ ##
386
+ # Adds a development dependency named +gem+ with +requirements+ to this
387
+ # gem.
388
+ #
389
+ # Usage:
390
+ #
391
+ # spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'
392
+ #
393
+ # Development dependencies aren't installed by default and aren't
394
+ # activated when a gem is required.
395
+
396
+ def add_development_dependency(gem, *requirements)
397
+ add_dependency_with_type(gem, :development, *requirements)
398
+ end
399
+
400
+ ##
401
+ # Adds a runtime dependency named +gem+ with +requirements+ to this gem.
402
+ #
403
+ # Usage:
404
+ #
405
+ # spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
406
+
407
+ def add_runtime_dependency(gem, *requirements)
408
+ add_dependency_with_type(gem, :runtime, *requirements)
409
+ end
410
+
411
+ ##
412
+ # Singular writer for #authors
413
+ #
414
+ # Usage:
415
+ #
416
+ # spec.author = 'John Jones'
417
+
418
+ def author= o
419
+ self.authors = [o]
420
+ end
421
+
422
+ ##
423
+ # Sets the list of authors, ensuring it is an array.
424
+ #
425
+ # Usage:
426
+ #
427
+ # spec.authors = ['John Jones', 'Mary Smith']
428
+
429
+ def authors= value
430
+ @authors = Array(value).flatten.grep(String)
431
+ end
432
+
433
+ ##
434
+ # Executables included in the gem.
435
+ #
436
+ # For example, the rake gem has rake as an executable. You don’t specify the
437
+ # full path (as in bin/rake); all application-style files are expected to be
438
+ # found in bindir. These files must be executable ruby files. Files that
439
+ # use bash or other interpreters will not work.
440
+ #
441
+ # Usage:
442
+ #
443
+ # spec.executables << 'rake'
444
+
445
+ def executables
446
+ @executables ||= []
447
+ end
448
+
449
+ ##
450
+ # Extensions to build when installing the gem, specifically the paths to
451
+ # extconf.rb-style files used to compile extensions.
452
+ #
453
+ # These files will be run when the gem is installed, causing the C (or
454
+ # whatever) code to be compiled on the user’s machine.
455
+ #
456
+ # Usage:
457
+ #
458
+ # spec.extensions << 'ext/rmagic/extconf.rb'
459
+
460
+ def extensions
461
+ @extensions ||= []
462
+ end
216
463
 
217
- attr_accessor :loaded # :nodoc:
464
+ ##
465
+ # Extra files to add to RDoc such as README or doc/examples.txt
466
+ #
467
+ # When the user elects to generate the RDoc documentation for a gem (typically
468
+ # at install time), all the library files are sent to RDoc for processing.
469
+ # This option allows you to have some non-code files included for a more
470
+ # complete set of documentation.
471
+ #
472
+ # Usage:
473
+ #
474
+ # spec.extra_rdoc_files = ['README', 'doc/user-guide.txt']
218
475
 
219
- alias :loaded? :loaded # :nodoc:
476
+ def extra_rdoc_files
477
+ @extra_rdoc_files ||= []
478
+ end
479
+
480
+ ##
481
+ # The license for this gem.
482
+ #
483
+ # The license must be a short name, no more than 64 characters.
484
+ #
485
+ # This should just be the name of your license. The full
486
+ # text of the license should be inside of the gem when you build it.
487
+ #
488
+ # Usage:
489
+ # spec.license = 'MIT'
490
+
491
+ def license=o
492
+ self.licenses = [o]
493
+ end
494
+
495
+ ##
496
+ # The license(s) for the library.
497
+ #
498
+ # Each license must be a short name, no more than 64 characters.
499
+ #
500
+ # This should just be the name of your license. The full
501
+ # text of the license should be inside of the gem when you build it.
502
+ #
503
+ # Usage:
504
+ # spec.licenses = ['MIT', 'GPL-2']
505
+
506
+ def licenses= licenses
507
+ @licenses = Array licenses
508
+ end
509
+
510
+ ##
511
+ # Specifies the rdoc options to be used when generating API documentation.
512
+ #
513
+ # Usage:
514
+ #
515
+ # spec.rdoc_options << '--title' << 'Rake -- Ruby Make' <<
516
+ # '--main' << 'README' <<
517
+ # '--line-numbers'
518
+
519
+ def rdoc_options
520
+ @rdoc_options ||= []
521
+ end
522
+
523
+ ##
524
+ # The version of ruby required by this gem
525
+ #
526
+ # Usage:
527
+ #
528
+ # # If it will work with 1.8.6 or greater...
529
+ # spec.required_ruby_version = '>= 1.8.6'
530
+ #
531
+ # # Hopefully by now:
532
+ # spec.required_ruby_version = '>= 1.9.2'
533
+
534
+ def required_ruby_version= req
535
+ @required_ruby_version = Gem::Requirement.create req
536
+ end
537
+
538
+ ##
539
+ # Lists the external (to RubyGems) requirements that must be met for this gem
540
+ # to work. It’s simply information for the user.
541
+ #
542
+ # Usage:
543
+ #
544
+ # spec.requirements << 'libmagick, v6.0'
545
+ # spec.requirements << 'A good graphics card'
546
+
547
+ def requirements
548
+ @requirements ||= []
549
+ end
550
+
551
+ ##
552
+ # A collection of unit test files. They will be loaded as unit tests when
553
+ # the user requests a gem to be unit tested.
554
+ #
555
+ # Usage:
556
+ # spec.test_files = Dir.glob('test/tc_*.rb')
557
+ # spec.test_files = ['tests/test-suite.rb']
558
+
559
+ def test_files= files
560
+ @test_files = Array files
561
+ end
562
+
563
+ ######################################################################
564
+ # :section: Specification internals
220
565
 
221
566
  ##
222
567
  # True when this gemspec has been activated. This attribute is not persisted.
@@ -225,6 +570,20 @@ class Gem::Specification
225
570
 
226
571
  alias :activated? :activated
227
572
 
573
+ ##
574
+ # Autorequire was used by old RubyGems to automatically require a file.
575
+ #
576
+ # Deprecated: It is neither supported nor functional.
577
+
578
+ attr_accessor :autorequire
579
+
580
+ ##
581
+ # Sets the default executable for this gem.
582
+ #
583
+ # Deprecated: You must now specify the executable name to Gem.bin_path.
584
+
585
+ attr_writer :default_executable
586
+
228
587
  ##
229
588
  # Path this gemspec was loaded from. This attribute is not persisted.
230
589
 
@@ -235,11 +594,6 @@ class Gem::Specification
235
594
 
236
595
  attr_writer :original_platform # :nodoc:
237
596
 
238
- ##
239
- # A message that gets displayed after the gem is installed
240
-
241
- attr_accessor :post_install_message
242
-
243
597
  ##
244
598
  # The version of ruby required by this gem
245
599
 
@@ -249,7 +603,6 @@ class Gem::Specification
249
603
  # The RubyGems version required by this gem
250
604
 
251
605
  attr_reader :required_rubygems_version
252
-
253
606
  ##
254
607
  # The rubyforge project this gem lives under. i.e. RubyGems'
255
608
  # rubyforge_project is "rubygems".
@@ -257,22 +610,49 @@ class Gem::Specification
257
610
  attr_accessor :rubyforge_project
258
611
 
259
612
  ##
260
- # The key used to sign this gem. See Gem::Security for details.
613
+ # The Gem::Specification version of this gemspec.
614
+ #
615
+ # Do not set this, it is set automatically when the gem is packaged.
261
616
 
262
- attr_accessor :signing_key
617
+ attr_accessor :specification_version
263
618
 
264
- def self._all # :nodoc:
265
- unless defined?(@@all) && @@all then
266
- specs = {}
619
+ class << self
620
+ def default_specifications_dir
621
+ File.join(Gem.default_dir, "specifications", "default")
622
+ end
267
623
 
268
- self.dirs.each { |dir|
624
+ private
625
+ def each_spec(search_dirs) # :nodoc:
626
+ search_dirs.each { |dir|
269
627
  Dir[File.join(dir, "*.gemspec")].each { |path|
270
628
  spec = Gem::Specification.load path.untaint
271
629
  # #load returns nil if the spec is bad, so we just ignore
272
630
  # it at this stage
273
- specs[spec.full_name] ||= spec if spec
631
+ yield(spec) if spec
274
632
  }
275
633
  }
634
+ end
635
+
636
+ def each_default(&block) # :nodoc:
637
+ each_spec([default_specifications_dir],
638
+ &block)
639
+ end
640
+
641
+ def each_normal(&block) # :nodoc:
642
+ each_spec(dirs, &block)
643
+ end
644
+ end
645
+
646
+ def self._all # :nodoc:
647
+ unless defined?(@@all) && @@all then
648
+
649
+ specs = {}
650
+ each_default do |spec|
651
+ specs[spec.full_name] ||= spec
652
+ end
653
+ each_normal do |spec|
654
+ specs[spec.full_name] ||= spec
655
+ end
276
656
 
277
657
  @@all = specs.values
278
658
 
@@ -289,6 +669,15 @@ class Gem::Specification
289
669
  }
290
670
  end
291
671
 
672
+ ##
673
+ # Loads the default specifications. It should be called only once.
674
+
675
+ def self.load_defaults
676
+ each_default do |spec|
677
+ Gem.register_default_spec(spec)
678
+ end
679
+ end
680
+
292
681
  ##
293
682
  # Adds +spec+ to the known specifications, keeping the collection
294
683
  # properly sorted.
@@ -381,7 +770,7 @@ class Gem::Specification
381
770
 
382
771
  def self.dirs
383
772
  @@dirs ||= Gem.path.collect { |dir|
384
- File.join dir, "specifications"
773
+ File.join dir.dup.untaint, "specifications"
385
774
  }
386
775
  end
387
776
 
@@ -445,12 +834,22 @@ class Gem::Specification
445
834
  }
446
835
  end
447
836
 
837
+ ##
838
+ # Return the best specification that contains the file matching +path+
839
+ # amongst the specs that are not activated.
840
+
841
+ def self.find_inactive_by_path path
842
+ self.find { |spec|
843
+ spec.contains_requirable_file? path unless spec.activated?
844
+ }
845
+ end
846
+
448
847
  ##
449
848
  # Return currently unresolved specs that contain the file matching +path+.
450
849
 
451
850
  def self.find_in_unresolved path
452
851
  # TODO: do we need these?? Kill it
453
- specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten
852
+ specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten
454
853
 
455
854
  specs.find_all { |spec| spec.contains_requirable_file? path }
456
855
  end
@@ -460,7 +859,7 @@ class Gem::Specification
460
859
  # specs that contain the file matching +path+.
461
860
 
462
861
  def self.find_in_unresolved_tree path
463
- specs = Gem.unresolved_deps.values.map { |dep| dep.to_specs }.flatten
862
+ specs = unresolved_deps.values.map { |dep| dep.to_specs }.flatten
464
863
 
465
864
  specs.reverse_each do |spec|
466
865
  trails = []
@@ -499,12 +898,8 @@ class Gem::Specification
499
898
  raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
500
899
  end
501
900
 
502
- unless (spec.instance_variables.include? '@specification_version' or
503
- spec.instance_variables.include? :@specification_version) and
504
- spec.instance_variable_get :@specification_version
505
- spec.instance_variable_set :@specification_version,
506
- NONEXISTENT_SPECIFICATION_VERSION
507
- end
901
+ spec.instance_eval { @specification_version ||= NONEXISTENT_SPECIFICATION_VERSION }
902
+ spec.reset_nil_attributes_to_default
508
903
 
509
904
  spec
510
905
  end
@@ -534,9 +929,9 @@ class Gem::Specification
534
929
  # Loads Ruby format gemspec from +file+.
535
930
 
536
931
  def self.load file
537
- return unless file && File.file?(file)
538
-
932
+ return unless file
539
933
  file = file.dup.untaint
934
+ return unless File.file?(file)
540
935
 
541
936
  code = if defined? Encoding
542
937
  File.read file, :mode => 'r:UTF-8:-'
@@ -596,9 +991,9 @@ class Gem::Specification
596
991
 
597
992
  latest_specs.each do |local|
598
993
  dependency = Gem::Dependency.new local.name, ">= #{local.version}"
599
- remotes = fetcher.find_matching dependency
600
- remotes = remotes.map { |(_, version, _), _| version }
601
- latest = remotes.sort.last
994
+ remotes, _ = fetcher.search_for_dependency dependency
995
+ remotes = remotes.map { |n, _| n.version }
996
+ latest = remotes.sort.last
602
997
 
603
998
  outdateds << local.name if latest and local.version < latest
604
999
  end
@@ -636,14 +1031,27 @@ class Gem::Specification
636
1031
 
637
1032
  def self.reset
638
1033
  @@dirs = nil
639
- # from = caller.first(10).reject { |s| s =~ /minitest/ }
640
- # warn ""
641
- # warn "NOTE: Specification.reset from #{from.inspect}"
642
- Gem.pre_reset_hooks.each { |hook| hook.call }
1034
+ Gem.pre_reset_hooks.each { |hook| hook.call }
643
1035
  @@all = nil
1036
+ unresolved = unresolved_deps
1037
+ unless unresolved.empty? then
1038
+ w = "W" + "ARN"
1039
+ warn "#{w}: Unresolved specs during Gem::Specification.reset:"
1040
+ unresolved.values.each do |dep|
1041
+ warn " #{dep}"
1042
+ end
1043
+ warn "#{w}: Clearing out unresolved specs."
1044
+ warn "Please report a bug if this causes problems."
1045
+ unresolved.clear
1046
+ end
644
1047
  Gem.post_reset_hooks.each { |hook| hook.call }
645
1048
  end
646
1049
 
1050
+ # DOC: This method needs documented or nodoc'd
1051
+ def self.unresolved_deps
1052
+ @unresolved_deps ||= Hash.new { |h, n| h[n] = Gem::Dependency.new n }
1053
+ end
1054
+
647
1055
  ##
648
1056
  # Load custom marshal format, re-initializing defaults as needed
649
1057
 
@@ -691,6 +1099,7 @@ class Gem::Specification
691
1099
  spec.instance_variable_set :@new_platform, array[16]
692
1100
  spec.instance_variable_set :@platform, array[16].to_s
693
1101
  spec.instance_variable_set :@license, array[17]
1102
+ spec.instance_variable_set :@metadata, array[18]
694
1103
  spec.instance_variable_set :@loaded, false
695
1104
  spec.instance_variable_set :@activated, false
696
1105
 
@@ -733,7 +1142,8 @@ class Gem::Specification
733
1142
  @homepage,
734
1143
  true, # has_rdoc
735
1144
  @new_platform,
736
- @licenses
1145
+ @licenses,
1146
+ @metadata
737
1147
  ]
738
1148
  end
739
1149
 
@@ -764,6 +1174,8 @@ class Gem::Specification
764
1174
  # resolved later, as needed.
765
1175
 
766
1176
  def activate_dependencies
1177
+ unresolved = Gem::Specification.unresolved_deps
1178
+
767
1179
  self.runtime_dependencies.each do |spec_dep|
768
1180
  if loaded = Gem.loaded_specs[spec_dep.name]
769
1181
  next if spec_dep.matches_spec? loaded
@@ -781,11 +1193,11 @@ class Gem::Specification
781
1193
  specs.first.activate
782
1194
  else
783
1195
  name = spec_dep.name
784
- Gem.unresolved_deps[name] = Gem.unresolved_deps[name].merge spec_dep
1196
+ unresolved[name] = unresolved[name].merge spec_dep
785
1197
  end
786
1198
  end
787
1199
 
788
- Gem.unresolved_deps.delete self.name
1200
+ unresolved.delete self.name
789
1201
  end
790
1202
 
791
1203
  ##
@@ -814,48 +1226,26 @@ class Gem::Specification
814
1226
  Gem::Requirement.default
815
1227
  else
816
1228
  requirements.flatten
817
- end
818
-
819
- unless dependency.respond_to?(:name) &&
820
- dependency.respond_to?(:version_requirements)
821
-
822
- dependency = Gem::Dependency.new(dependency, requirements, type)
823
- end
824
-
825
- dependencies << dependency
826
- end
827
-
828
- private :add_dependency_with_type
829
-
830
- ##
831
- # Adds a development dependency named +gem+ with +requirements+ to this
832
- # Gem. For example:
833
- #
834
- # spec.add_development_dependency 'example', '~> 1.1', '>= 1.1.4'
835
- #
836
- # Development dependencies aren't installed by default and aren't
837
- # activated when a gem is required.
838
-
839
- def add_development_dependency(gem, *requirements)
840
- add_dependency_with_type(gem, :development, *requirements)
841
- end
1229
+ end
842
1230
 
843
- ##
844
- # Adds a runtime dependency named +gem+ with +requirements+ to this Gem.
845
- # For example:
846
- #
847
- # spec.add_runtime_dependency 'example', '~> 1.1', '>= 1.1.4'
1231
+ unless dependency.respond_to?(:name) &&
1232
+ dependency.respond_to?(:version_requirements)
1233
+ dependency = Gem::Dependency.new(dependency, requirements, type)
1234
+ end
848
1235
 
849
- def add_runtime_dependency(gem, *requirements)
850
- add_dependency_with_type(gem, :runtime, *requirements)
1236
+ dependencies << dependency
851
1237
  end
852
1238
 
1239
+ private :add_dependency_with_type
1240
+
853
1241
  alias add_dependency add_runtime_dependency
854
1242
 
855
1243
  ##
856
1244
  # Adds this spec's require paths to LOAD_PATH, in the proper location.
857
1245
 
858
1246
  def add_self_to_load_path
1247
+ return if default_gem?
1248
+
859
1249
  paths = require_paths.map do |path|
860
1250
  File.join full_gem_path, path
861
1251
  end
@@ -879,34 +1269,13 @@ class Gem::Specification
879
1269
  val = authors and val.first
880
1270
  end
881
1271
 
882
- ##
883
- # Singular writer for #authors
884
-
885
- def author= o
886
- self.authors = [o]
887
- end
888
-
889
1272
  ##
890
1273
  # The list of author names who wrote this gem.
891
- #
892
- # If you are providing multiple authors and multiple emails they should be
893
- # in the same order such that:
894
- #
895
- # Hash[*spec.authors.zip(spec.emails).flatten]
896
- #
897
- # Gives a hash of author name to email address.
898
1274
 
899
1275
  def authors
900
1276
  @authors ||= []
901
1277
  end
902
1278
 
903
- ##
904
- # Sets the list of authors, ensuring it is an array.
905
-
906
- def authors= value
907
- @authors = Array(value).flatten.grep(String)
908
- end
909
-
910
1279
  ##
911
1280
  # Returns the full path to the base gem directory.
912
1281
  #
@@ -934,6 +1303,32 @@ class Gem::Specification
934
1303
  File.join bin_dir, name
935
1304
  end
936
1305
 
1306
+ ##
1307
+ # Returns the build_args used to install the gem
1308
+
1309
+ def build_args
1310
+ if File.exists? build_info_file
1311
+ File.readlines(build_info_file).map { |x| x.strip }
1312
+ else
1313
+ []
1314
+ end
1315
+ end
1316
+
1317
+ ##
1318
+ # Returns the full path to the build info directory
1319
+
1320
+ def build_info_dir
1321
+ File.join base_dir, "build_info"
1322
+ end
1323
+
1324
+ ##
1325
+ # Returns the full path to the file containing the build
1326
+ # information generated when the gem was installed
1327
+
1328
+ def build_info_file
1329
+ File.join build_info_dir, "#{full_name}.info"
1330
+ end
1331
+
937
1332
  ##
938
1333
  # Returns the full path to the cache directory containing this
939
1334
  # spec's cached gem.
@@ -949,8 +1344,6 @@ class Gem::Specification
949
1344
  @cache_file ||= File.join cache_dir, "#{full_name}.gem"
950
1345
  end
951
1346
 
952
- alias :cache_gem :cache_file
953
-
954
1347
  ##
955
1348
  # Return any possible conflicts against the currently loaded specs.
956
1349
 
@@ -970,17 +1363,13 @@ class Gem::Specification
970
1363
  # Return true if this spec can require +file+.
971
1364
 
972
1365
  def contains_requirable_file? file
973
- root = full_gem_path
1366
+ root = full_gem_path
1367
+ suffixes = Gem.suffixes
974
1368
 
975
- require_paths.each do |lib|
1369
+ require_paths.any? do |lib|
976
1370
  base = "#{root}/#{lib}/#{file}"
977
- Gem.suffixes.each do |suf|
978
- path = "#{base}#{suf}"
979
- return true if File.file? path
980
- end
1371
+ suffixes.any? { |suf| File.file? "#{base}#{suf}" }
981
1372
  end
982
-
983
- return false
984
1373
  end
985
1374
 
986
1375
  ##
@@ -990,10 +1379,15 @@ class Gem::Specification
990
1379
  @date ||= TODAY
991
1380
  end
992
1381
 
1382
+ DateTimeFormat = /\A
1383
+ (\d{4})-(\d{2})-(\d{2})
1384
+ (\s+ \d{2}:\d{2}:\d{2}\.\d+ \s* (Z | [-+]\d\d:\d\d) )?
1385
+ \Z/x
1386
+
993
1387
  ##
994
1388
  # The date this gem was created
995
1389
  #
996
- # Do not set this, it is set automatically when the gem is packaged.
1390
+ # DO NOT set this, it is set automatically when the gem is packaged.
997
1391
 
998
1392
  def date= date
999
1393
  # We want to end up with a Time object with one-day resolution.
@@ -1001,7 +1395,7 @@ class Gem::Specification
1001
1395
  # way to do it.
1002
1396
  @date = case date
1003
1397
  when String then
1004
- if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
1398
+ if DateTimeFormat =~ date then
1005
1399
  Time.utc($1.to_i, $2.to_i, $3.to_i)
1006
1400
 
1007
1401
  # Workaround for where the date format output from psych isn't
@@ -1061,6 +1455,7 @@ class Gem::Specification
1061
1455
  # [depending_gem, dependency, [list_of_gems_that_satisfy_dependency]]
1062
1456
 
1063
1457
  def dependent_gems
1458
+ # REFACTOR: out = []; each; out; ? Really? No #collect love?
1064
1459
  out = []
1065
1460
  Gem::Specification.each do |spec|
1066
1461
  spec.dependencies.each do |dep|
@@ -1098,10 +1493,21 @@ class Gem::Specification
1098
1493
  end
1099
1494
 
1100
1495
  ##
1101
- # Returns the full path to this spec's documentation directory.
1496
+ # Returns the full path to this spec's documentation directory. If +type+
1497
+ # is given it will be appended to the end. For examlpe:
1498
+ #
1499
+ # spec.doc_dir # => "/path/to/gem_repo/doc/a-1"
1500
+ #
1501
+ # spec.doc_dir 'ri' # => "/path/to/gem_repo/doc/a-1/ri"
1102
1502
 
1103
- def doc_dir
1503
+ def doc_dir type = nil
1104
1504
  @doc_dir ||= File.join base_dir, 'doc', full_name
1505
+
1506
+ if type then
1507
+ File.join @doc_dir, type
1508
+ else
1509
+ @doc_dir
1510
+ end
1105
1511
  end
1106
1512
 
1107
1513
  def encode_with coder # :nodoc:
@@ -1143,13 +1549,6 @@ class Gem::Specification
1143
1549
  self.executables = [o]
1144
1550
  end
1145
1551
 
1146
- ##
1147
- # Executables included in the gem.
1148
-
1149
- def executables
1150
- @executables ||= []
1151
- end
1152
-
1153
1552
  ##
1154
1553
  # Sets executables to +value+, ensuring it is an array. Don't
1155
1554
  # use this, push onto the array instead.
@@ -1159,14 +1558,6 @@ class Gem::Specification
1159
1558
  @executables = Array(value)
1160
1559
  end
1161
1560
 
1162
- ##
1163
- # Extensions to build when installing the gem. See
1164
- # Gem::Installer#build_extensions for valid values.
1165
-
1166
- def extensions
1167
- @extensions ||= []
1168
- end
1169
-
1170
1561
  ##
1171
1562
  # Sets extensions to +extensions+, ensuring it is an array. Don't
1172
1563
  # use this, push onto the array instead.
@@ -1176,13 +1567,6 @@ class Gem::Specification
1176
1567
  @extensions = Array extensions
1177
1568
  end
1178
1569
 
1179
- ##
1180
- # Extra files to add to RDoc such as README or doc/examples.txt
1181
-
1182
- def extra_rdoc_files
1183
- @extra_rdoc_files ||= []
1184
- end
1185
-
1186
1570
  ##
1187
1571
  # Sets extra_rdoc_files to +files+, ensuring it is an array. Don't
1188
1572
  # use this, push onto the array instead.
@@ -1201,25 +1585,6 @@ class Gem::Specification
1201
1585
  "#{full_name}.gem"
1202
1586
  end
1203
1587
 
1204
- ##
1205
- # Files included in this gem. You cannot append to this accessor, you must
1206
- # assign to it.
1207
- #
1208
- # Only add files you can require to this list, not directories, etc.
1209
- #
1210
- # Directories are automatically stripped from this list when building a gem,
1211
- # other non-files cause an error.
1212
-
1213
- def files
1214
- # DO NOT CHANGE TO ||= ! This is not a normal accessor. (yes, it sucks)
1215
- @files = [@files,
1216
- @test_files,
1217
- add_bindir(@executables),
1218
- @extra_rdoc_files,
1219
- @extensions,
1220
- ].flatten.uniq.compact
1221
- end
1222
-
1223
1588
  ##
1224
1589
  # Sets files to +files+, ensuring it is an array.
1225
1590
 
@@ -1254,11 +1619,14 @@ class Gem::Specification
1254
1619
  # The full path to the gem (install path + full name).
1255
1620
 
1256
1621
  def full_gem_path
1257
- # TODO: try to get rid of this... or the awkward
1622
+ # TODO: This is a heavily used method by gems, so we'll need
1623
+ # to aleast just alias it to #gem_dir rather than remove it.
1624
+
1258
1625
  # TODO: also, shouldn't it default to full_name if it hasn't been written?
1259
1626
  return @full_gem_path if defined?(@full_gem_path) && @full_gem_path
1260
1627
 
1261
1628
  @full_gem_path = File.expand_path File.join(gems_dir, full_name)
1629
+ @full_gem_path.untaint
1262
1630
 
1263
1631
  return @full_gem_path if File.directory? @full_gem_path
1264
1632
 
@@ -1271,11 +1639,11 @@ class Gem::Specification
1271
1639
  # default Ruby platform.
1272
1640
 
1273
1641
  def full_name
1274
- if platform == Gem::Platform::RUBY or platform.nil? then
1275
- "#{@name}-#{@version}"
1276
- else
1277
- "#{@name}-#{@version}-#{platform}"
1278
- end
1642
+ @full_name ||= if platform == Gem::Platform::RUBY or platform.nil? then
1643
+ "#{@name}-#{@version}".untaint
1644
+ else
1645
+ "#{@name}-#{@version}-#{platform}".untaint
1646
+ end
1279
1647
  end
1280
1648
 
1281
1649
  ##
@@ -1373,13 +1741,9 @@ class Gem::Specification
1373
1741
  # Duplicates array_attributes from +other_spec+ so state isn't shared.
1374
1742
 
1375
1743
  def initialize_copy other_spec
1376
- other_ivars = other_spec.instance_variables
1377
- other_ivars = other_ivars.map { |ivar| ivar.intern } if # for 1.9
1378
- String === other_ivars.first
1379
-
1380
1744
  self.class.array_attributes.each do |name|
1381
1745
  name = :"@#{name}"
1382
- next unless other_ivars.include? name
1746
+ next unless other_spec.instance_variable_defined? name
1383
1747
 
1384
1748
  begin
1385
1749
  val = other_spec.instance_variable_get(name)
@@ -1399,11 +1763,22 @@ class Gem::Specification
1399
1763
  end
1400
1764
 
1401
1765
  ##
1402
- # The directory that this gem was installed into.
1403
- # TODO: rename - horrible. this is the base_dir for a gem path
1766
+ # Expire memoized instance variables that can incorrectly generate, replace
1767
+ # or miss files due changes in certain attributes used to compute them.
1768
+
1769
+ def invalidate_memoized_attributes
1770
+ @full_name = nil
1771
+ @cache_file = nil
1772
+ end
1773
+
1774
+ private :invalidate_memoized_attributes
1404
1775
 
1405
- def installation_path
1406
- loaded_from && base_dir
1776
+ def inspect
1777
+ if $DEBUG
1778
+ super
1779
+ else
1780
+ "#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>"
1781
+ end
1407
1782
  end
1408
1783
 
1409
1784
  ##
@@ -1426,7 +1801,7 @@ class Gem::Specification
1426
1801
  def lib_files
1427
1802
  @files.select do |file|
1428
1803
  require_paths.any? do |path|
1429
- file.index(path) == 0
1804
+ file.start_with? path
1430
1805
  end
1431
1806
  end
1432
1807
  end
@@ -1439,33 +1814,31 @@ class Gem::Specification
1439
1814
  end
1440
1815
 
1441
1816
  ##
1442
- # Singular accessor for #licenses
1443
-
1444
- def license=o
1445
- self.licenses = [o]
1446
- end
1447
-
1448
- ##
1449
- # The license(s) for the library. Each license must be a short name, no
1450
- # more than 64 characters.
1817
+ # Plural accessor for setting licenses
1451
1818
 
1452
1819
  def licenses
1453
1820
  @licenses ||= []
1454
1821
  end
1455
1822
 
1456
- ##
1457
- # Set licenses to +licenses+, ensuring it is an array.
1458
-
1459
- def licenses= licenses
1460
- @licenses = Array licenses
1461
- end
1462
-
1463
1823
  ##
1464
1824
  # Set the location a Specification was loaded from. +obj+ is converted
1465
1825
  # to a String.
1466
1826
 
1467
1827
  def loaded_from= path
1468
- @loaded_from = path.to_s
1828
+ @loaded_from = path.to_s
1829
+
1830
+ # reset everything @loaded_from depends upon
1831
+ @base_dir = nil
1832
+ @bin_dir = nil
1833
+ @cache_dir = nil
1834
+ @cache_file = nil
1835
+ @doc_dir = nil
1836
+ @full_gem_path = nil
1837
+ @gem_dir = nil
1838
+ @gems_dir = nil
1839
+ @ri_dir = nil
1840
+ @spec_dir = nil
1841
+ @spec_file = nil
1469
1842
  end
1470
1843
 
1471
1844
  ##
@@ -1517,6 +1890,13 @@ class Gem::Specification
1517
1890
  @extra_rdoc_files = @extra_rdoc_files.uniq if @extra_rdoc_files
1518
1891
  end
1519
1892
 
1893
+ ##
1894
+ # Return a NameTuple that represents this Specification
1895
+
1896
+ def name_tuple
1897
+ Gem::NameTuple.new name, version, original_platform
1898
+ end
1899
+
1520
1900
  ##
1521
1901
  # Returns the full name (name-version) of this gemspec using the original
1522
1902
  # platform. For use with legacy gems.
@@ -1543,44 +1923,6 @@ class Gem::Specification
1543
1923
  @new_platform ||= Gem::Platform::RUBY
1544
1924
  end
1545
1925
 
1546
- ##
1547
- # The platform this gem runs on. See Gem::Platform for details.
1548
- #
1549
- # Setting this to any value other than Gem::Platform::RUBY or
1550
- # Gem::Platform::CURRENT is probably wrong.
1551
-
1552
- def platform= platform
1553
- if @original_platform.nil? or
1554
- @original_platform == Gem::Platform::RUBY then
1555
- @original_platform = platform
1556
- end
1557
-
1558
- case platform
1559
- when Gem::Platform::CURRENT then
1560
- @new_platform = Gem::Platform.local
1561
- @original_platform = @new_platform.to_s
1562
-
1563
- when Gem::Platform then
1564
- @new_platform = platform
1565
-
1566
- # legacy constants
1567
- when nil, Gem::Platform::RUBY then
1568
- @new_platform = Gem::Platform::RUBY
1569
- when 'mswin32' then # was Gem::Platform::WIN32
1570
- @new_platform = Gem::Platform.new 'x86-mswin32'
1571
- when 'i586-linux' then # was Gem::Platform::LINUX_586
1572
- @new_platform = Gem::Platform.new 'x86-linux'
1573
- when 'powerpc-darwin' then # was Gem::Platform::DARWIN
1574
- @new_platform = Gem::Platform.new 'ppc-darwin'
1575
- else
1576
- @new_platform = Gem::Platform.new platform
1577
- end
1578
-
1579
- @platform = @new_platform.to_s
1580
-
1581
- @new_platform
1582
- end
1583
-
1584
1926
  def pretty_print(q) # :nodoc:
1585
1927
  q.group 2, 'Gem::Specification.new do |s|', 'end' do
1586
1928
  q.breakable
@@ -1639,13 +1981,6 @@ class Gem::Specification
1639
1981
  end
1640
1982
  end
1641
1983
 
1642
- ##
1643
- # An ARGV style array of options to RDoc
1644
-
1645
- def rdoc_options
1646
- @rdoc_options ||= []
1647
- end
1648
-
1649
1984
  ##
1650
1985
  # Sets rdoc_options to +value+, ensuring it is an array. Don't
1651
1986
  # use this, push onto the array instead.
@@ -1669,13 +2004,6 @@ class Gem::Specification
1669
2004
  self.require_paths = [path]
1670
2005
  end
1671
2006
 
1672
- ##
1673
- # The version of ruby required by this gem
1674
-
1675
- def required_ruby_version= req
1676
- @required_ruby_version = Gem::Requirement.create req
1677
- end
1678
-
1679
2007
  ##
1680
2008
  # The RubyGems version required by this gem
1681
2009
 
@@ -1683,14 +2011,6 @@ class Gem::Specification
1683
2011
  @required_rubygems_version = Gem::Requirement.create req
1684
2012
  end
1685
2013
 
1686
- ##
1687
- # An array or things required by this gem. Not used by anything
1688
- # presently.
1689
-
1690
- def requirements
1691
- @requirements ||= []
1692
- end
1693
-
1694
2014
  ##
1695
2015
  # Set requirements to +req+, ensuring it is an array. Don't
1696
2016
  # use this, push onto the array instead.
@@ -1715,15 +2035,16 @@ class Gem::Specification
1715
2035
  case obj
1716
2036
  when String then obj.dump
1717
2037
  when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']'
2038
+ when Hash then
2039
+ seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
2040
+ "{ #{seg.join(', ')} }"
1718
2041
  when Gem::Version then obj.to_s.dump
1719
2042
  when Date then obj.strftime('%Y-%m-%d').dump
1720
2043
  when Time then obj.strftime('%Y-%m-%d').dump
1721
2044
  when Numeric then obj.inspect
1722
2045
  when true, false, nil then obj.inspect
1723
2046
  when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
1724
- when Gem::Requirement then
1725
- list = obj.as_list
1726
- "Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})"
2047
+ when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
1727
2048
  else raise Gem::Exception, "ruby_code case not handled: #{obj.class}"
1728
2049
  end
1729
2050
  end
@@ -1803,7 +2124,7 @@ class Gem::Specification
1803
2124
  end
1804
2125
 
1805
2126
  ##
1806
- # Singular accessor for #test_files
2127
+ # Singular mutator for #test_files
1807
2128
 
1808
2129
  def test_file= file
1809
2130
  self.test_files = [file]
@@ -1828,28 +2149,14 @@ class Gem::Specification
1828
2149
  end
1829
2150
  end
1830
2151
 
1831
- ##
1832
- # Set test_files to +files+, ensuring it is an array.
1833
-
1834
- def test_files= files
1835
- @test_files = Array files
1836
- end
1837
-
1838
- def test_suite_file # :nodoc:
1839
- # TODO: deprecate
1840
- test_files.first
1841
- end
1842
-
1843
- def test_suite_file= file # :nodoc:
1844
- # TODO: deprecate
1845
- @test_files = [] unless defined? @test_files
1846
- @test_files << file
1847
- end
1848
-
1849
2152
  ##
1850
2153
  # Returns a Ruby code representation of this specification, such that it can
1851
2154
  # be eval'ed and reconstruct the same specification later. Attributes that
1852
2155
  # still have their default values are omitted.
2156
+ #
2157
+ # REFACTOR: This, plus stuff like #ruby_code and #pretty_print, should
2158
+ # probably be extracted out into some sort of separate class. SRP, do you
2159
+ # speak it!??!
1853
2160
 
1854
2161
  def to_ruby
1855
2162
  mark_version
@@ -1866,6 +2173,10 @@ class Gem::Specification
1866
2173
  result << ""
1867
2174
  result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version="
1868
2175
 
2176
+ if metadata and !metadata.empty?
2177
+ result << " s.metadata = #{ruby_code metadata} if s.respond_to? :metadata="
2178
+ end
2179
+
1869
2180
  handled = [
1870
2181
  :dependencies,
1871
2182
  :name,
@@ -1875,6 +2186,7 @@ class Gem::Specification
1875
2186
  :version,
1876
2187
  :has_rdoc,
1877
2188
  :default_executable,
2189
+ :metadata
1878
2190
  ]
1879
2191
 
1880
2192
  @@attributes.each do |attr_name|
@@ -1886,34 +2198,36 @@ class Gem::Specification
1886
2198
  end
1887
2199
  end
1888
2200
 
1889
- result << nil
1890
- result << " if s.respond_to? :specification_version then"
1891
- result << " s.specification_version = #{specification_version}"
1892
- result << nil
2201
+ unless dependencies.empty? then
2202
+ result << nil
2203
+ result << " if s.respond_to? :specification_version then"
2204
+ result << " s.specification_version = #{specification_version}"
2205
+ result << nil
1893
2206
 
1894
- result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
2207
+ result << " if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then"
1895
2208
 
1896
- dependencies.each do |dep|
1897
- req = dep.requirements_list.inspect
1898
- dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
1899
- result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
1900
- end
2209
+ dependencies.each do |dep|
2210
+ req = dep.requirements_list.inspect
2211
+ dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
2212
+ result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
2213
+ end
1901
2214
 
1902
- result << " else"
2215
+ result << " else"
1903
2216
 
1904
- dependencies.each do |dep|
1905
- version_reqs_param = dep.requirements_list.inspect
1906
- result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
1907
- end
2217
+ dependencies.each do |dep|
2218
+ version_reqs_param = dep.requirements_list.inspect
2219
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
2220
+ end
1908
2221
 
1909
- result << ' end'
2222
+ result << ' end'
1910
2223
 
1911
- result << " else"
2224
+ result << " else"
1912
2225
  dependencies.each do |dep|
1913
2226
  version_reqs_param = dep.requirements_list.inspect
1914
2227
  result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
1915
2228
  end
1916
- result << " end"
2229
+ result << " end"
2230
+ end
1917
2231
 
1918
2232
  result << "end"
1919
2233
  result << nil
@@ -2061,12 +2375,42 @@ class Gem::Specification
2061
2375
  end
2062
2376
  end
2063
2377
 
2378
+ # FIX: uhhhh single element array.each?
2064
2379
  [:authors].each do |field|
2065
2380
  val = self.send field
2066
2381
  raise Gem::InvalidSpecificationException, "#{field} may not be empty" if
2067
2382
  val.empty?
2068
2383
  end
2069
2384
 
2385
+ unless Hash === metadata
2386
+ raise Gem::InvalidSpecificationException,
2387
+ 'metadata must be a hash'
2388
+ end
2389
+
2390
+ metadata.keys.each do |k|
2391
+ if !k.kind_of?(String)
2392
+ raise Gem::InvalidSpecificationException,
2393
+ 'metadata keys must be a String'
2394
+ end
2395
+
2396
+ if k.size > 128
2397
+ raise Gem::InvalidSpecificationException,
2398
+ "metadata key too large (#{k.size} > 128)"
2399
+ end
2400
+ end
2401
+
2402
+ metadata.values.each do |k|
2403
+ if !k.kind_of?(String)
2404
+ raise Gem::InvalidSpecificationException,
2405
+ 'metadata values must be a String'
2406
+ end
2407
+
2408
+ if k.size > 1024
2409
+ raise Gem::InvalidSpecificationException,
2410
+ "metadata value too large (#{k.size} > 1024)"
2411
+ end
2412
+ end
2413
+
2070
2414
  licenses.each { |license|
2071
2415
  if license.length > 64
2072
2416
  raise Gem::InvalidSpecificationException,
@@ -2074,8 +2418,13 @@ class Gem::Specification
2074
2418
  end
2075
2419
  }
2076
2420
 
2421
+ alert_warning 'licenses is empty' if licenses.empty?
2422
+
2423
+ validate_permissions
2424
+
2077
2425
  # reject lazy developers:
2078
2426
 
2427
+ # FIX: Doesn't this just evaluate to "FIXME" or "TODO"?
2079
2428
  lazy = '"FIxxxXME" or "TOxxxDO"'.gsub(/xxx/, '')
2080
2429
 
2081
2430
  unless authors.grep(/FI XME|TO DO/x).empty? then
@@ -2121,9 +2470,36 @@ class Gem::Specification
2121
2470
  alert_warning "#{executable_path} is missing #! line" unless shebang
2122
2471
  end
2123
2472
 
2473
+ dependencies.each do |dep|
2474
+ prerelease_dep = dep.requirements_list.any? do |req|
2475
+ Gem::Requirement.new(req).prerelease?
2476
+ end
2477
+
2478
+ alert_warning "prerelease dependency on #{dep} is not recommended" if
2479
+ prerelease_dep
2480
+ end
2481
+
2124
2482
  true
2125
2483
  end
2126
2484
 
2485
+ ##
2486
+ # Checks to see if the files to be packaged are world-readable.
2487
+
2488
+ def validate_permissions
2489
+ return if Gem.win_platform?
2490
+
2491
+ files.each do |file|
2492
+ next if File.stat(file).mode & 0444 == 0444
2493
+ alert_warning "#{file} is not world-readable"
2494
+ end
2495
+
2496
+ executables.each do |name|
2497
+ exec = File.join @bindir, name
2498
+ next if File.stat(exec).executable?
2499
+ alert_warning "#{exec} is not executable"
2500
+ end
2501
+ end
2502
+
2127
2503
  ##
2128
2504
  # Set the version to +version+, potentially also setting
2129
2505
  # required_rubygems_version if +version+ indicates it is a
@@ -2132,6 +2508,8 @@ class Gem::Specification
2132
2508
  def version= version
2133
2509
  @version = Gem::Version.create(version)
2134
2510
  self.required_rubygems_version = '> 1.3.1' if @version.prerelease?
2511
+ invalidate_memoized_attributes
2512
+
2135
2513
  return @version
2136
2514
  end
2137
2515
 
@@ -2151,15 +2529,33 @@ class Gem::Specification
2151
2529
  self.platform = Gem::Platform.new @platform
2152
2530
  end
2153
2531
 
2532
+ ##
2533
+ # Reset nil attributes to their default values to make the spec valid
2534
+
2535
+ def reset_nil_attributes_to_default
2536
+ nil_attributes = self.class.non_nil_attributes.find_all do |name|
2537
+ !instance_variable_defined?("@#{name}") || instance_variable_get("@#{name}").nil?
2538
+ end
2539
+
2540
+ nil_attributes.each do |attribute|
2541
+ default = self.default_value attribute
2542
+
2543
+ value = case default
2544
+ when Time, Numeric, Symbol, true, false, nil then default
2545
+ else default.dup
2546
+ end
2547
+
2548
+ instance_variable_set "@#{attribute}", value
2549
+ end
2550
+ end
2551
+
2552
+ def default_gem?
2553
+ loaded_from &&
2554
+ File.dirname(loaded_from) == self.class.default_specifications_dir
2555
+ end
2556
+
2154
2557
  extend Gem::Deprecate
2155
2558
 
2156
- deprecate :test_suite_file, :test_file, 2011, 10
2157
- deprecate :test_suite_file=, :test_file=, 2011, 10
2158
- deprecate :loaded, :activated, 2011, 10
2159
- deprecate :loaded?, :activated?, 2011, 10
2160
- deprecate :loaded=, :activated=, 2011, 10
2161
- deprecate :installation_path, :base_dir, 2011, 10
2162
- deprecate :cache_gem, :cache_file, 2011, 10
2163
2559
  # TODO:
2164
2560
  # deprecate :has_rdoc, :none, 2011, 10
2165
2561
  # deprecate :has_rdoc?, :none, 2011, 10
@@ -2171,5 +2567,5 @@ class Gem::Specification
2171
2567
  # deprecate :full_gem_path, :cache_file, 2011, 10
2172
2568
  end
2173
2569
 
2570
+ # DOC: What is this and why is it here, randomly, at the end of this file?
2174
2571
  Gem.clear_paths
2175
-