rubygems-update 0.9.4 → 0.9.5

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 (225) hide show
  1. data/ChangeLog +587 -0
  2. data/README +0 -1
  3. data/Rakefile +39 -12
  4. data/TODO +0 -5
  5. data/bin/gem +7 -7
  6. data/bin/update_rubygems +1 -1
  7. data/examples/application/an-app.gemspec +1 -1
  8. data/gemspecs/cgikit-1.1.0.gemspec +1 -2
  9. data/gemspecs/jabber4r.gemspec +1 -1
  10. data/gemspecs/linguistics.gemspec +1 -1
  11. data/gemspecs/ook.gemspec +1 -1
  12. data/gemspecs/progressbar.gemspec +1 -1
  13. data/gemspecs/redcloth.gemspec +1 -1
  14. data/gemspecs/rublog.gemspec +1 -1
  15. data/gemspecs/ruby-doom.gemspec +1 -1
  16. data/gemspecs/rubyjdwp.gemspec +1 -1
  17. data/gemspecs/statistics.gemspec +1 -1
  18. data/lib/rubygems.rb +167 -105
  19. data/lib/rubygems/builder.rb +12 -10
  20. data/lib/rubygems/command.rb +177 -60
  21. data/lib/rubygems/command_manager.rb +30 -38
  22. data/lib/rubygems/commands/build_command.rb +42 -46
  23. data/lib/rubygems/commands/cert_command.rb +72 -69
  24. data/lib/rubygems/commands/check_command.rb +63 -63
  25. data/lib/rubygems/commands/cleanup_command.rb +25 -7
  26. data/lib/rubygems/commands/contents_command.rb +70 -62
  27. data/lib/rubygems/commands/dependency_command.rb +131 -86
  28. data/lib/rubygems/commands/environment_command.rb +67 -46
  29. data/lib/rubygems/commands/fetch_command.rb +62 -0
  30. data/lib/rubygems/commands/generate_index_command.rb +57 -0
  31. data/lib/rubygems/commands/help_command.rb +163 -73
  32. data/lib/rubygems/commands/install_command.rb +114 -128
  33. data/lib/rubygems/commands/list_command.rb +10 -8
  34. data/lib/rubygems/commands/lock_command.rb +101 -0
  35. data/lib/rubygems/commands/mirror_command.rb +105 -0
  36. data/lib/rubygems/commands/outdated_command.rb +24 -15
  37. data/lib/rubygems/commands/pristine_command.rb +118 -88
  38. data/lib/rubygems/commands/query_command.rb +109 -77
  39. data/lib/rubygems/commands/rdoc_command.rb +13 -10
  40. data/lib/rubygems/commands/search_command.rb +10 -8
  41. data/lib/rubygems/commands/server_command.rb +48 -0
  42. data/lib/rubygems/commands/sources_command.rb +104 -83
  43. data/lib/rubygems/commands/specification_command.rb +65 -51
  44. data/lib/rubygems/commands/uninstall_command.rb +17 -12
  45. data/lib/rubygems/commands/unpack_command.rb +68 -68
  46. data/lib/rubygems/commands/update_command.rb +72 -25
  47. data/lib/rubygems/commands/which_command.rb +86 -0
  48. data/lib/rubygems/config_file.rb +202 -78
  49. data/lib/rubygems/custom_require.rb +7 -88
  50. data/lib/rubygems/dependency.rb +65 -0
  51. data/lib/rubygems/dependency_installer.rb +232 -0
  52. data/lib/rubygems/dependency_list.rb +133 -105
  53. data/lib/rubygems/digest/md5.rb +4 -1
  54. data/lib/rubygems/digest/sha2.rb +1 -1
  55. data/lib/rubygems/doc_manager.rb +41 -19
  56. data/lib/rubygems/exceptions.rb +63 -0
  57. data/lib/rubygems/ext.rb +18 -0
  58. data/lib/rubygems/ext/builder.rb +56 -0
  59. data/lib/rubygems/ext/configure_builder.rb +24 -0
  60. data/lib/rubygems/ext/ext_conf_builder.rb +23 -0
  61. data/lib/rubygems/ext/rake_builder.rb +27 -0
  62. data/lib/rubygems/format.rb +16 -6
  63. data/lib/rubygems/gem_openssl.rb +43 -6
  64. data/lib/rubygems/gem_path_searcher.rb +84 -0
  65. data/lib/rubygems/gem_runner.rb +20 -5
  66. data/lib/rubygems/indexer.rb +163 -0
  67. data/lib/rubygems/indexer/abstract_index_builder.rb +80 -0
  68. data/lib/rubygems/indexer/marshal_index_builder.rb +17 -0
  69. data/lib/rubygems/indexer/master_index_builder.rb +53 -0
  70. data/lib/rubygems/indexer/quick_index_builder.rb +48 -0
  71. data/lib/rubygems/install_update_options.rb +87 -0
  72. data/lib/rubygems/installer.rb +316 -562
  73. data/lib/rubygems/local_remote_options.rb +106 -0
  74. data/lib/rubygems/old_format.rb +5 -13
  75. data/lib/rubygems/open-uri.rb +2 -0
  76. data/lib/rubygems/package.rb +28 -32
  77. data/lib/rubygems/platform.rb +187 -0
  78. data/lib/rubygems/remote_fetcher.rb +46 -29
  79. data/lib/rubygems/remote_installer.rb +11 -18
  80. data/lib/rubygems/requirement.rb +157 -0
  81. data/lib/rubygems/rubygems_version.rb +1 -1
  82. data/lib/rubygems/security.rb +715 -457
  83. data/lib/rubygems/server.rb +77 -59
  84. data/lib/rubygems/source_index.rb +154 -83
  85. data/lib/rubygems/source_info_cache.rb +73 -30
  86. data/lib/rubygems/source_info_cache_entry.rb +12 -3
  87. data/lib/rubygems/specification.rb +378 -145
  88. data/lib/rubygems/uninstaller.rb +183 -0
  89. data/lib/rubygems/user_interaction.rb +38 -9
  90. data/lib/rubygems/validator.rb +53 -24
  91. data/lib/rubygems/version.rb +126 -289
  92. data/lib/rubygems/version_option.rb +49 -0
  93. data/pkgs/sources/lib/sources.rb +1 -4
  94. data/pkgs/sources/sources.gemspec +3 -3
  95. data/scripts/gemdoc.rb +0 -1
  96. data/setup.rb +166 -1505
  97. data/test/bogussources.rb +0 -1
  98. data/test/data/gem-private_key.pem +27 -0
  99. data/test/data/gem-public_cert.pem +20 -0
  100. data/test/functional.rb +3 -105
  101. data/test/gemutilities.rb +145 -24
  102. data/test/insure_session.rb +0 -1
  103. data/test/{test_datadir.rb → test_config.rb} +7 -13
  104. data/test/test_gem.rb +360 -9
  105. data/test/test_gem_builder.rb +34 -0
  106. data/test/{test_command.rb → test_gem_command.rb} +119 -62
  107. data/test/{test_parse_commands.rb → test_gem_command_manager.rb} +64 -40
  108. data/test/test_gem_commands_build_command.rb +75 -0
  109. data/test/test_gem_commands_cert_command.rb +122 -0
  110. data/test/test_gem_commands_check_command.rb +25 -0
  111. data/test/test_gem_commands_contents_command.rb +92 -0
  112. data/test/test_gem_commands_dependency_command.rb +108 -0
  113. data/test/test_gem_commands_environment_command.rb +117 -0
  114. data/test/test_gem_commands_fetch_command.rb +34 -0
  115. data/test/test_gem_commands_generate_index_command.rb +32 -0
  116. data/test/test_gem_commands_install_command.rb +160 -0
  117. data/test/test_gem_commands_mirror_command.rb +56 -0
  118. data/test/test_gem_commands_pristine_command.rb +100 -0
  119. data/test/test_gem_commands_query_command.rb +82 -0
  120. data/test/test_gem_commands_sources_command.rb +147 -0
  121. data/test/test_gem_commands_specification_command.rb +93 -0
  122. data/test/test_gem_commands_unpack_command.rb +55 -0
  123. data/test/test_gem_config_file.rb +210 -0
  124. data/test/test_gem_dependency.rb +89 -0
  125. data/test/test_gem_dependency_installer.rb +542 -0
  126. data/test/test_gem_dependency_list.rb +212 -0
  127. data/test/test_gem_doc_manager.rb +32 -0
  128. data/test/test_gem_ext_configure_builder.rb +13 -17
  129. data/test/test_gem_ext_ext_conf_builder.rb +9 -9
  130. data/test/test_gem_ext_rake_builder.rb +23 -11
  131. data/test/test_gem_format.rb +69 -0
  132. data/test/test_gem_gem_path_searcher.rb +57 -0
  133. data/test/test_gem_gem_runner.rb +35 -0
  134. data/test/test_gem_indexer.rb +119 -0
  135. data/test/test_gem_install_update_options.rb +40 -0
  136. data/test/test_gem_installer.rb +796 -0
  137. data/test/test_gem_local_remote_options.rb +84 -0
  138. data/test/test_gem_outdated_command.rb +11 -9
  139. data/test/test_gem_platform.rb +240 -0
  140. data/test/{test_remote_fetcher.rb → test_gem_remote_fetcher.rb} +124 -55
  141. data/test/{test_remote_installer.rb → test_gem_remote_installer.rb} +3 -4
  142. data/test/test_gem_requirement.rb +223 -0
  143. data/test/test_gem_server.rb +71 -0
  144. data/test/test_gem_source_index.rb +429 -0
  145. data/test/test_gem_source_info_cache.rb +79 -17
  146. data/test/test_gem_source_info_cache_entry.rb +11 -9
  147. data/test/test_gem_specification.rb +738 -0
  148. data/test/test_gem_stream_ui.rb +117 -0
  149. data/test/test_gem_validator.rb +70 -0
  150. data/test/test_gem_version.rb +191 -0
  151. data/test/test_gem_version_option.rb +77 -0
  152. data/test/{test_require_gem.rb → test_kernel.rb} +19 -12
  153. data/test/test_open_uri.rb +1 -2
  154. data/test/test_package.rb +45 -34
  155. metadata +116 -141
  156. data/Releases +0 -127
  157. data/bin/gem_mirror +0 -73
  158. data/bin/gem_server +0 -6
  159. data/bin/gemlock +0 -127
  160. data/bin/gemri +0 -24
  161. data/bin/gemwhich +0 -89
  162. data/bin/index_gem_repository.rb +0 -302
  163. data/lib/gemconfigure.rb +0 -24
  164. data/lib/rubygems/gem_commands.rb +0 -273
  165. data/pkgs/sources/sources-0.0.1.gem +0 -0
  166. data/post-install.rb +0 -121
  167. data/test/brokenbuildgem.rb +0 -35
  168. data/test/data/PostMessage-0.0.1.gem +0 -0
  169. data/test/data/a-0.0.1.gem +0 -0
  170. data/test/data/a-0.0.2.gem +0 -0
  171. data/test/data/b-0.0.2.gem +0 -0
  172. data/test/data/broken-1.0.0.gem +0 -0
  173. data/test/data/broken_build/broken-build.gemspec +0 -20
  174. data/test/data/broken_build/ext/extconf.rb +0 -3
  175. data/test/data/broken_build/ext/foo.c +0 -1
  176. data/test/data/c-1.2.gem +0 -0
  177. data/test/data/gemhome/cache/a-0.0.1.gem +0 -0
  178. data/test/data/gemhome/cache/a-0.0.2.gem +0 -0
  179. data/test/data/gemhome/cache/b-0.0.2.gem +0 -0
  180. data/test/data/gemhome/cache/c-1.2.gem +0 -0
  181. data/test/data/gemhome/gems/a-0.0.1/lib/code.rb +0 -1
  182. data/test/data/gemhome/gems/a-0.0.2/lib/code.rb +0 -1
  183. data/test/data/gemhome/gems/b-0.0.2/lib/code.rb +0 -1
  184. data/test/data/gemhome/gems/c-1.2/lib/code.rb +0 -1
  185. data/test/data/gemhome/specifications/a-0.0.1.gemspec +0 -8
  186. data/test/data/gemhome/specifications/a-0.0.2.gemspec +0 -8
  187. data/test/data/gemhome/specifications/b-0.0.2.gemspec +0 -8
  188. data/test/data/gemhome/specifications/c-1.2.gemspec +0 -8
  189. data/test/data/legacy/keyedlist-0.4.0.ruby +0 -11
  190. data/test/data/legacy/keyedlist-0.4.0.yaml +0 -16
  191. data/test/data/lib/code.rb +0 -1
  192. data/test/data/one/README.one +0 -1
  193. data/test/data/one/lib/one.rb +0 -9
  194. data/test/data/one/one-0.0.1.gem +0 -0
  195. data/test/data/one/one.gemspec +0 -17
  196. data/test/data/one/one.yaml +0 -40
  197. data/test/data/post_install.gemspec +0 -19
  198. data/test/functional_extension_gems.rb +0 -48
  199. data/test/functional_generate_yaml_index.rb +0 -104
  200. data/test/gemenvironment.rb +0 -59
  201. data/test/io_capture.rb +0 -33
  202. data/test/mock/gems/gems/sources-0.0.1/lib/sources.rb +0 -11
  203. data/test/mock/gems/specifications/sources-0.0.1.gemspec +0 -8
  204. data/test/onegem.rb +0 -35
  205. data/test/test_builder.rb +0 -34
  206. data/test/test_check_command.rb +0 -34
  207. data/test/test_configfile.rb +0 -42
  208. data/test/test_dependency_list.rb +0 -169
  209. data/test/test_file_list.rb +0 -101
  210. data/test/test_format.rb +0 -49
  211. data/test/test_gem_sources_command.rb +0 -135
  212. data/test/test_gemloadpaths.rb +0 -51
  213. data/test/test_gempaths.rb +0 -170
  214. data/test/test_installer.rb +0 -369
  215. data/test/test_loadmanager.rb +0 -48
  216. data/test/test_process_commands.rb +0 -52
  217. data/test/test_source_index.rb +0 -231
  218. data/test/test_specific_extras.rb +0 -46
  219. data/test/test_specification.rb +0 -565
  220. data/test/test_user_interaction.rb +0 -48
  221. data/test/test_validator.rb +0 -59
  222. data/test/test_version_comparison.rb +0 -321
  223. data/test/testgem.rc +0 -7
  224. data/test/user_capture.rb +0 -7
  225. data/test/yaml_data.rb +0 -63
@@ -1,9 +1,8 @@
1
1
  require 'fileutils'
2
+
2
3
  require 'rubygems'
3
- require 'rubygems/remote_fetcher'
4
4
  require 'rubygems/source_info_cache_entry'
5
-
6
- require 'sources'
5
+ require 'rubygems/user_interaction'
7
6
 
8
7
  # SourceInfoCache stores a copy of the gem index for each gem source.
9
8
  #
@@ -38,7 +37,7 @@ class Gem::SourceInfoCache
38
37
  def self.cache
39
38
  return @cache if @cache
40
39
  @cache = new
41
- @cache.refresh
40
+ @cache.refresh if Gem.configuration.update_sources
42
41
  @cache
43
42
  end
44
43
 
@@ -47,8 +46,14 @@ class Gem::SourceInfoCache
47
46
  end
48
47
 
49
48
  # Search all source indexes for +pattern+.
50
- def self.search(pattern)
51
- cache.search(pattern)
49
+ def self.search(pattern, platform_only = false)
50
+ cache.search pattern, platform_only
51
+ end
52
+
53
+ # Search all source indexes for +pattern+. Only returns gems matching
54
+ # Gem.platforms when +only_platform+ is true. See #search_with_source.
55
+ def self.search_with_source(pattern, only_platform = false)
56
+ cache.search_with_source(pattern, only_platform)
52
57
  end
53
58
 
54
59
  def initialize # :nodoc:
@@ -60,31 +65,50 @@ class Gem::SourceInfoCache
60
65
  # The most recent cache data.
61
66
  def cache_data
62
67
  return @cache_data if @cache_data
63
- @dirty = false
64
68
  cache_file # HACK writable check
65
- # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
69
+
66
70
  begin
71
+ # Marshal loads 30-40% faster from a String, and 2MB on 20061116 is small
67
72
  data = File.open cache_file, 'rb' do |fp| fp.read end
68
73
  @cache_data = Marshal.load data
74
+
69
75
  @cache_data.each do |url, sice|
70
- next unless Hash === sice
71
- @dirty = true
72
- if sice.key? 'cache' and sice.key? 'size' and
73
- Gem::SourceIndex === sice['cache'] and Numeric === sice['size'] then
74
- new_sice = Gem::SourceInfoCacheEntry.new sice['cache'], sice['size']
76
+ next unless sice.is_a?(Hash)
77
+ update
78
+ cache = sice['cache']
79
+ size = sice['size']
80
+ if cache.is_a?(Gem::SourceIndex) and size.is_a?(Numeric) then
81
+ new_sice = Gem::SourceInfoCacheEntry.new cache, size
75
82
  @cache_data[url] = new_sice
76
83
  else # irreperable, force refetch.
77
- sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
78
- sice.refresh url # HACK may be unnecessary, see ::cache and #refresh
79
- @cache_data[url] = sice
84
+ reset_cache_for(url)
80
85
  end
81
86
  end
82
87
  @cache_data
83
- rescue
84
- {}
88
+ rescue => e
89
+ if Gem.configuration.really_verbose then
90
+ say "Exception during cache_data handling: #{ex.class} - #{ex}"
91
+ say "Cache file was: #{cache_file}"
92
+ say "\t#{e.backtrace.join "\n\t"}"
93
+ end
94
+ reset_cache_data
85
95
  end
86
96
  end
87
97
 
98
+ def reset_cache_for(url)
99
+ say "Reseting cache for #{url}" if Gem.configuration.really_verbose
100
+
101
+ sice = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0
102
+ sice.refresh url # HACK may be unnecessary, see ::cache and #refresh
103
+
104
+ @cache_data[url] = sice
105
+ @cache_data
106
+ end
107
+
108
+ def reset_cache_data
109
+ @cache_data = {}
110
+ end
111
+
88
112
  # The name of the cache file to be read
89
113
  def cache_file
90
114
  return @cache_file if @cache_file
@@ -108,17 +132,36 @@ class Gem::SourceInfoCache
108
132
  cache_data[source_uri] = cache_entry
109
133
  end
110
134
 
111
- cache_entry.refresh source_uri
135
+ update if cache_entry.refresh source_uri
112
136
  end
113
- update
137
+
114
138
  flush
115
139
  end
116
140
 
117
141
  # Searches all source indexes for +pattern+.
118
- def search(pattern)
119
- cache_data.map do |source, sic_entry|
120
- sic_entry.source_index.search pattern
121
- end.flatten
142
+ def search(pattern, platform_only = false)
143
+ cache_data.map do |source_uri, sic_entry|
144
+ next unless Gem.sources.include? source_uri
145
+ sic_entry.source_index.search pattern, platform_only
146
+ end.flatten.compact
147
+ end
148
+
149
+ # Searches all source indexes for +pattern+. If +only_platform+ is true,
150
+ # only gems matching Gem.platforms will be selected. Returns an Array of
151
+ # pairs containing the Gem::Specification found and the source_uri it was
152
+ # found at.
153
+ def search_with_source(pattern, only_platform = false)
154
+ results = []
155
+
156
+ cache_data.map do |source_uri, sic_entry|
157
+ next unless Gem.sources.include? source_uri
158
+
159
+ sic_entry.source_index.search(pattern, only_platform).each do |spec|
160
+ results << [spec, source_uri]
161
+ end
162
+ end
163
+
164
+ results
122
165
  end
123
166
 
124
167
  # Mark the cache as updated (i.e. dirty).
@@ -155,12 +198,12 @@ class Gem::SourceInfoCache
155
198
  end
156
199
 
157
200
  # Set the source info cache data directly. This is mainly used for unit
158
- # testing when we don't want to read a file system for to grab the cached
159
- # source index information. The +hash+ should map a source URL into a
160
- # SourceIndexCacheEntry.
201
+ # testing when we don't want to read a file system to grab the cached source
202
+ # index information. The +hash+ should map a source URL into a
203
+ # SourceInfoCacheEntry.
161
204
  def set_cache_data(hash)
162
205
  @cache_data = hash
163
- @dirty = false
206
+ update
164
207
  end
165
208
 
166
209
  private
@@ -171,7 +214,7 @@ class Gem::SourceInfoCache
171
214
  return fn if File.writable?(fn)
172
215
  return nil if File.exist?(fn)
173
216
  dir = File.dirname(fn)
174
- if ! File.exist? dir
217
+ unless File.exist? dir then
175
218
  begin
176
219
  FileUtils.mkdir_p(dir)
177
220
  rescue RuntimeError
@@ -179,7 +222,7 @@ class Gem::SourceInfoCache
179
222
  end
180
223
  end
181
224
  if File.writable?(dir)
182
- FileUtils.touch fn
225
+ File.open(fn, "wb") { |f| f << Marshal.dump({}) }
183
226
  return fn
184
227
  end
185
228
  nil
@@ -21,10 +21,19 @@ class Gem::SourceInfoCacheEntry
21
21
  end
22
22
 
23
23
  def refresh(source_uri)
24
- remote_size = Gem::RemoteFetcher.fetcher.fetch_size source_uri + '/yaml'
25
- return if @size == remote_size # HACK bad check, local cache not YAML
26
- @source_index.update source_uri
24
+ begin
25
+ marshal_uri = URI.join source_uri.to_s, "Marshal.#{Gem.marshal_version}"
26
+ remote_size = Gem::RemoteFetcher.fetcher.fetch_size marshal_uri
27
+ rescue Gem::RemoteSourceException
28
+ yaml_uri = URI.join source_uri.to_s, 'yaml'
29
+ remote_size = Gem::RemoteFetcher.fetcher.fetch_size yaml_uri
30
+ end
31
+
32
+ return false if @size == remote_size # TODO Use index_signature instead of size?
33
+ updated = @source_index.update source_uri
27
34
  @size = remote_size
35
+
36
+ updated
28
37
  end
29
38
 
30
39
  def ==(other) # :nodoc:
@@ -7,36 +7,22 @@
7
7
  require 'time'
8
8
  require 'rubygems'
9
9
  require 'rubygems/version'
10
+ require 'rubygems/platform'
10
11
 
11
- class Time # :nodoc:
12
- def self.today
13
- Time.parse Time.now.strftime("%Y-%m-%d")
14
- end
15
- end
12
+ # :stopdoc:
13
+ # Time::today has been deprecated in 0.9.5 and will be removed.
14
+ def Time.today
15
+ t = Time.now
16
+ t - ((t.to_i + t.gmt_offset) % 86400)
17
+ end unless defined? Time.today
18
+ # :startdoc:
16
19
 
17
20
  module Gem
18
-
19
- # == Gem::Platform
20
- #
21
- # Available list of platforms for targeting Gem installations.
22
- # Platform::RUBY is the default platform (pure Ruby Gem).
23
- #
24
- module Platform
25
- RUBY = 'ruby'
26
- WIN32 = 'mswin32'
27
- LINUX_586 = 'i586-linux'
28
- DARWIN = 'powerpc-darwin'
29
- CURRENT = 'current'
30
- end
31
-
32
- # Potentially raised when a specification is validated.
33
- class InvalidSpecificationException < Gem::Exception; end
34
- class EndOfYAMLException < Gem::Exception; end
35
21
 
36
22
  # == Gem::Specification
37
23
  #
38
- # The Specification class contains the metadata for a Gem. Typically defined in a
39
- # .gemspec file or a Rakefile, and looks like this:
24
+ # The Specification class contains the metadata for a Gem. Typically
25
+ # defined in a .gemspec file or a Rakefile, and looks like this:
40
26
  #
41
27
  # spec = Gem::Specification.new do |s|
42
28
  # s.name = 'rfoo'
@@ -45,31 +31,46 @@ module Gem
45
31
  # ...
46
32
  # end
47
33
  #
48
- # There are many <em>gemspec attributes</em>, and the best place to learn about them in
49
- # the "Gemspec Reference" linked from the RubyGems wiki.
34
+ # There are many <em>gemspec attributes</em>, and the best place to learn
35
+ # about them in the "Gemspec Reference" linked from the RubyGems wiki.
50
36
  #
51
37
  class Specification
52
38
 
39
+ # Allows deinstallation of gems with legacy platforms.
40
+ attr_accessor :original_platform # :nodoc:
41
+
53
42
  # ------------------------- Specification version contstants.
54
43
 
55
- # The the version number of a specification that does not specify one (i.e. RubyGems 0.7
56
- # or earlier).
44
+ # The the version number of a specification that does not specify one
45
+ # (i.e. RubyGems 0.7 or earlier).
57
46
  NONEXISTENT_SPECIFICATION_VERSION = -1
58
47
 
59
- # The specification version applied to any new Specification instances created. This
60
- # should be bumped whenever something in the spec format changes.
61
- CURRENT_SPECIFICATION_VERSION = 1
48
+ # The specification version applied to any new Specification instances
49
+ # created. This should be bumped whenever something in the spec format
50
+ # changes.
51
+ CURRENT_SPECIFICATION_VERSION = 2
62
52
 
63
- # An informal list of changes to the specification. The highest-valued key should be
64
- # equal to the CURRENT_SPECIFICATION_VERSION.
53
+ # An informal list of changes to the specification. The highest-valued
54
+ # key should be equal to the CURRENT_SPECIFICATION_VERSION.
65
55
  SPECIFICATION_VERSION_HISTORY = {
66
56
  -1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
67
57
  1 => [
68
58
  'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
69
59
  '"test_file=x" is a shortcut for "test_files=[x]"'
70
- ]
60
+ ],
61
+ 2 => [
62
+ 'Added "required_rubygems_version"',
63
+ 'Now forward-compatible with future versions',
64
+ ],
71
65
  }
72
66
 
67
+ # :stopdoc:
68
+ MARSHAL_FIELDS = { -1 => 16, 1 => 16, 2 => 16 }
69
+
70
+ now = Time.at(Time.now.to_i)
71
+ TODAY = now - ((now.to_i + now.gmt_offset) % 86400)
72
+ # :startdoc:
73
+
73
74
  # ------------------------- Class variables.
74
75
 
75
76
  # List of Specification instances.
@@ -84,6 +85,9 @@ module Gem
84
85
  # List of _all_ attributes and default values: [[:name, nil], [:bindir, 'bin'], ...]
85
86
  @@attributes = []
86
87
 
88
+ @@nil_attributes = []
89
+ @@non_nil_attributes = [:@original_platform]
90
+
87
91
  # List of array attributes
88
92
  @@array_attributes = []
89
93
 
@@ -139,6 +143,13 @@ module Gem
139
143
  # values.
140
144
  #
141
145
  def self.attribute(name, default=nil)
146
+ ivar_name = "@#{name}".intern
147
+ if default.nil? then
148
+ @@nil_attributes << ivar_name
149
+ else
150
+ @@non_nil_attributes << [ivar_name, default]
151
+ end
152
+
142
153
  @@attributes << [name, default]
143
154
  @@default_value[name] = default
144
155
  attr_accessor(name)
@@ -147,17 +158,21 @@ module Gem
147
158
  # Same as :attribute, but ensures that values assigned to the
148
159
  # attribute are array values by applying :to_a to the value.
149
160
  def self.array_attribute(name)
161
+ @@non_nil_attributes << ["@#{name}".intern, []]
162
+
150
163
  @@array_attributes << name
151
164
  @@attributes << [name, []]
152
165
  @@default_value[name] = []
153
- module_eval %{
166
+ code = %{
154
167
  def #{name}
155
168
  @#{name} ||= []
156
169
  end
157
170
  def #{name}=(value)
158
- @#{name} = value.to_a
171
+ @#{name} = Array(value)
159
172
  end
160
173
  }
174
+
175
+ module_eval code, __FILE__, __LINE__ - 9
161
176
  end
162
177
 
163
178
  # Same as attribute above, but also records this attribute as mandatory.
@@ -215,6 +230,69 @@ module Gem
215
230
  }
216
231
  end
217
232
 
233
+ # Dump only crucial instance variables.
234
+ #
235
+ # MAINTAIN ORDER!
236
+ def _dump(limit) # :nodoc:
237
+ Marshal.dump [
238
+ @rubygems_version,
239
+ @specification_version,
240
+ @name,
241
+ @version,
242
+ (Time === @date ? @date : Time.parse(@date.to_s)),
243
+ @summary,
244
+ @required_ruby_version,
245
+ @required_rubygems_version,
246
+ @original_platform,
247
+ @dependencies,
248
+ @rubyforge_project,
249
+ @email,
250
+ @authors,
251
+ @description,
252
+ @homepage,
253
+ @has_rdoc,
254
+ @new_platform,
255
+ ]
256
+ end
257
+
258
+ # Load custom marshal format, re-initializing defaults as needed
259
+ def self._load(str)
260
+ array = Marshal.load str
261
+
262
+ spec = Gem::Specification.new
263
+ spec.instance_variable_set :@specification_version, array[1]
264
+
265
+ current_version = CURRENT_SPECIFICATION_VERSION
266
+
267
+ field_count = MARSHAL_FIELDS[spec.specification_version]
268
+
269
+ if field_count.nil? or array.size < field_count then
270
+ raise TypeError, "invalid Gem::Specification format #{array.inspect}"
271
+ end
272
+
273
+ spec.instance_variable_set :@rubygems_version, array[0]
274
+ # spec version
275
+ spec.instance_variable_set :@name, array[2]
276
+ spec.instance_variable_set :@version, array[3]
277
+ spec.instance_variable_set :@date, array[4]
278
+ spec.instance_variable_set :@summary, array[5]
279
+ spec.instance_variable_set :@required_ruby_version, array[6]
280
+ spec.instance_variable_set :@required_rubygems_version, array[7]
281
+ spec.instance_variable_set :@original_platform, array[8]
282
+ spec.instance_variable_set :@dependencies, array[9]
283
+ spec.instance_variable_set :@rubyforge_project, array[10]
284
+ spec.instance_variable_set :@email, array[11]
285
+ spec.instance_variable_set :@authors, array[12]
286
+ spec.instance_variable_set :@description, array[13]
287
+ spec.instance_variable_set :@homepage, array[14]
288
+ spec.instance_variable_set :@has_rdoc, array[15]
289
+ spec.instance_variable_set :@new_platform, array[16]
290
+ spec.instance_variable_set :@platform, array[16].to_s
291
+ spec.instance_variable_set :@loaded, false
292
+
293
+ spec
294
+ end
295
+
218
296
  def warn_deprecated(old, new)
219
297
  # How (if at all) to implement this? We only want to warn when
220
298
  # a gem is being built, I should think.
@@ -226,23 +304,23 @@ module Gem
226
304
  required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
227
305
  required_attribute :name
228
306
  required_attribute :version
229
- required_attribute :date
307
+ required_attribute :date, TODAY
230
308
  required_attribute :summary
231
309
  required_attribute :require_paths, ['lib']
232
-
233
- read_only :specification_version
234
310
 
235
311
  # OPTIONAL gemspec attributes ------------------------------------
236
312
 
237
313
  attributes :email, :homepage, :rubyforge_project, :description
238
314
  attributes :autorequire, :default_executable
239
- attribute :bindir, 'bin'
240
- attribute :has_rdoc, false
241
- attribute :required_ruby_version, Gem::Version::Requirement.default
242
- attribute :platform, Gem::Platform::RUBY
315
+
316
+ attribute :bindir, 'bin'
317
+ attribute :has_rdoc, false
318
+ attribute :required_ruby_version, Gem::Requirement.default
319
+ attribute :required_rubygems_version, Gem::Requirement.default
320
+ attribute :platform, Gem::Platform::RUBY
243
321
 
244
322
  attribute :signing_key, nil
245
- attribute :cert_chain, nil
323
+ attribute :cert_chain, []
246
324
  attribute :post_install_message, nil
247
325
 
248
326
  array_attribute :authors
@@ -251,6 +329,10 @@ module Gem
251
329
  array_attribute :rdoc_options
252
330
  array_attribute :extra_rdoc_files
253
331
  array_attribute :executables
332
+
333
+ # Array of extensions to build. See Gem::Installer#build_extensions for
334
+ # valid values.
335
+
254
336
  array_attribute :extensions
255
337
  array_attribute :requirements
256
338
  array_attribute :dependencies
@@ -276,10 +358,13 @@ module Gem
276
358
  @test_files = [] unless defined? @test_files
277
359
  @test_files << val
278
360
  end
279
-
280
- # RUNTIME attributes (not persisted) -----------------------------
281
-
361
+
362
+ # true when this gemspec has been loaded from a specifications directory.
363
+ # This attribute is not persisted.
364
+
282
365
  attr_writer :loaded
366
+
367
+ # Path this gemspec was loaded from. This attribute is not persisted.
283
368
  attr_accessor :loaded_from
284
369
 
285
370
  # Special accessor behaviours (overwriting default) --------------
@@ -288,21 +373,53 @@ module Gem
288
373
  @version = Version.create(version)
289
374
  end
290
375
 
376
+ overwrite_accessor :platform do
377
+ @new_platform
378
+ end
379
+
291
380
  overwrite_accessor :platform= do |platform|
292
- # Checks the provided platform for the special value
293
- # Platform::CURRENT and changes it to be binary specific to the
294
- # current platform (i386-mswin32, etc).
295
- @platform = (platform == Platform::CURRENT ? RUBY_PLATFORM : platform)
381
+ if @original_platform.nil? or
382
+ @original_platform == Gem::Platform::RUBY then
383
+ @original_platform = platform
384
+ end
385
+
386
+ case platform
387
+ when Gem::Platform::CURRENT then
388
+ @new_platform = Gem::Platform.local
389
+
390
+ when Gem::Platform then
391
+ @new_platform = platform
392
+
393
+ # legacy constants
394
+ when nil, Gem::Platform::RUBY then
395
+ @new_platform = Gem::Platform::RUBY
396
+ when Gem::Platform::WIN32 then
397
+ @new_platform = Gem::Platform::MSWIN32
398
+ when Gem::Platform::LINUX_586 then
399
+ @new_platform = Gem::Platform::X86_LINUX
400
+ when Gem::Platform::DARWIN then
401
+ @new_platform = Gem::Platform::PPC_DARWIN
402
+ else
403
+ @new_platform = platform
404
+ end
405
+
406
+ @platform = @new_platform.to_s
407
+
408
+ @new_platform
296
409
  end
297
410
 
298
411
  overwrite_accessor :required_ruby_version= do |value|
299
- @required_ruby_version = Version::Requirement.create(value)
412
+ @required_ruby_version = Gem::Requirement.create(value)
413
+ end
414
+
415
+ overwrite_accessor :required_rubygems_version= do |value|
416
+ @required_rubygems_version = Gem::Requirement.create(value)
300
417
  end
301
418
 
302
419
  overwrite_accessor :date= do |date|
303
420
  # We want to end up with a Time object with one-day resolution.
304
421
  # This is the cleanest, most-readable, faster-than-using-Date
305
- # way to do it.
422
+ # way to do it.
306
423
  case date
307
424
  when String then
308
425
  @date = Time.parse date
@@ -311,7 +428,7 @@ module Gem
311
428
  when Date then
312
429
  @date = Time.parse date.to_s
313
430
  else
314
- @date = Time.today
431
+ @date = TODAY
315
432
  end
316
433
  end
317
434
 
@@ -339,9 +456,9 @@ module Gem
339
456
  overwrite_accessor :default_executable do
340
457
  begin
341
458
  if defined? @default_executable and @default_executable
342
- result = @default_executable
459
+ result = @default_executable
343
460
  elsif @executables and @executables.size == 1
344
- result = @executables.first
461
+ result = Array(@executables).first
345
462
  else
346
463
  result = nil
347
464
  end
@@ -357,7 +474,7 @@ module Gem
357
474
  end
358
475
 
359
476
  if defined? @bindir and @bindir then
360
- @executables.map {|e| File.join(@bindir, e) }
477
+ Array(@executables).map {|e| File.join(@bindir, e) }
361
478
  else
362
479
  @executables
363
480
  end
@@ -367,12 +484,21 @@ module Gem
367
484
 
368
485
  overwrite_accessor :files do
369
486
  result = []
370
- result |= as_array(@files) if defined?(@files)
371
- result |= as_array(@test_files) if defined?(@test_files)
372
- result |= as_array(add_bindir(@executables) || [])
373
- result |= as_array(@extra_rdoc_files) if defined?(@extra_rdoc_files)
374
- result |= as_array(@extensions) if defined?(@extensions)
375
- result
487
+ result.push(*@files) if defined?(@files)
488
+ result.push(*@test_files) if defined?(@test_files)
489
+ result.push(*(add_bindir(@executables)))
490
+ result.push(*@extra_rdoc_files) if defined?(@extra_rdoc_files)
491
+ result.push(*@extensions) if defined?(@extensions)
492
+ result.uniq.compact
493
+ end
494
+
495
+ # Files in the Gem under one of the require_paths
496
+ def lib_files
497
+ @files.select do |file|
498
+ require_paths.any? do |path|
499
+ file.index(path) == 0
500
+ end
501
+ end
376
502
  end
377
503
 
378
504
  overwrite_accessor :test_files do
@@ -404,24 +530,39 @@ module Gem
404
530
  # Specification.list), and yields itself for further initialization.
405
531
  #
406
532
  def initialize
407
- # Each attribute has a default value (possibly nil). Here, we
408
- # initialize all attributes to their default value. This is
409
- # done through the accessor methods, so special behaviours will
410
- # be honored. Furthermore, we take a _copy_ of the default so
411
- # each specification instance has its own empty arrays, etc.
412
- @@attributes.each do |name, default|
413
- if RUBY_VERSION >= "1.9" then
414
- self.funcall "#{name}=", copy_of(default)
415
- else
416
- self.send "#{name}=", copy_of(default)
417
- end
418
- end
533
+ @new_platform = nil
534
+ assign_defaults
419
535
  @loaded = false
420
536
  @@list << self
537
+
421
538
  yield self if block_given?
539
+
422
540
  @@gather.call(self) if @@gather
423
541
  end
424
542
 
543
+ # Each attribute has a default value (possibly nil). Here, we
544
+ # initialize all attributes to their default value. This is
545
+ # done through the accessor methods, so special behaviours will
546
+ # be honored. Furthermore, we take a _copy_ of the default so
547
+ # each specification instance has its own empty arrays, etc.
548
+ def assign_defaults
549
+ @@nil_attributes.each do |name|
550
+ instance_variable_set name, nil
551
+ end
552
+
553
+ @@non_nil_attributes.each do |name, default|
554
+ value = case default
555
+ when Time, Numeric, Symbol, true, false, nil then default
556
+ else default.dup
557
+ end
558
+
559
+ instance_variable_set name, value
560
+ end
561
+
562
+ # HACK
563
+ instance_variable_set :@new_platform, Gem::Platform::RUBY
564
+ end
565
+
425
566
  # Special loader for YAML files. When a Specification object is
426
567
  # loaded from a YAML file, it bypasses the normal Ruby object
427
568
  # initialization routine (#initialize). This method makes up for
@@ -429,24 +570,29 @@ module Gem
429
570
  #
430
571
  # 'input' can be anything that YAML.load() accepts: String or IO.
431
572
  #
432
- def Specification.from_yaml(input)
433
- input = normalize_yaml_input(input)
434
- spec = YAML.load(input)
435
- if(spec && spec.class == FalseClass) then
573
+ def self.from_yaml(input)
574
+ input = normalize_yaml_input input
575
+ spec = YAML.load input
576
+
577
+ if spec && spec.class == FalseClass then
436
578
  raise Gem::EndOfYAMLException
437
579
  end
438
- unless Specification === spec
580
+
581
+ unless Gem::Specification === spec then
439
582
  raise Gem::Exception, "YAML data doesn't evaluate to gem specification"
440
583
  end
441
- unless spec.instance_variables.include? '@specification_version' and
584
+
585
+ unless (spec.instance_variables.include? '@specification_version' or
586
+ spec.instance_variables.include? :@specification_version) and
442
587
  spec.instance_variable_get :@specification_version
443
588
  spec.instance_variable_set :@specification_version,
444
- NONEXISTENT_SPECIFICATION_VERSION
589
+ NONEXISTENT_SPECIFICATION_VERSION
445
590
  end
591
+
446
592
  spec
447
593
  end
448
594
 
449
- def Specification.load(filename)
595
+ def self.load(filename)
450
596
  gemspec = nil
451
597
  fail "NESTED Specification.load calls not allowed!" if @@gather
452
598
  @@gather = proc { |gs| gemspec = gs }
@@ -458,7 +604,7 @@ module Gem
458
604
  end
459
605
 
460
606
  # Make sure the yaml specification is properly formatted with dashes.
461
- def Specification.normalize_yaml_input(input)
607
+ def self.normalize_yaml_input(input)
462
608
  result = input.respond_to?(:read) ? input.read : input
463
609
  result = "--- " + result unless result =~ /^--- /
464
610
  result
@@ -472,19 +618,34 @@ module Gem
472
618
  @rubygems_version = RubyGemsVersion
473
619
  end
474
620
 
621
+ # Ignore unknown attributes if the
622
+ def method_missing(sym, *a, &b) # :nodoc:
623
+ if @specification_version > CURRENT_SPECIFICATION_VERSION and
624
+ sym.to_s =~ /=$/ then
625
+ warn "ignoring #{sym} loading #{full_name}" if $DEBUG
626
+ else
627
+ super
628
+ end
629
+ end
630
+
475
631
  # Adds a dependency to this Gem. For example,
476
632
  #
477
633
  # spec.add_dependency('jabber4r', '> 0.1', '<= 0.5')
478
634
  #
479
635
  # gem:: [String or Gem::Dependency] The Gem name/dependency.
480
- # requirements:: [default="> 0.0.0"] The version requirements.
636
+ # requirements:: [default=">= 0"] The version requirements.
481
637
  #
482
638
  def add_dependency(gem, *requirements)
483
- requirements = ['> 0.0.0'] if requirements.empty?
484
- requirements.flatten!
639
+ requirements = if requirements.empty? then
640
+ Gem::Requirement.default
641
+ else
642
+ requirements.flatten
643
+ end
644
+
485
645
  unless gem.respond_to?(:name) && gem.respond_to?(:version_requirements)
486
646
  gem = Dependency.new(gem, requirements)
487
647
  end
648
+
488
649
  dependencies << gem
489
650
  end
490
651
 
@@ -493,19 +654,32 @@ module Gem
493
654
  # default Ruby platform).
494
655
  #
495
656
  def full_name
496
- if platform == Gem::Platform::RUBY || platform.nil?
657
+ if platform == Gem::Platform::RUBY or platform.nil? then
497
658
  "#{@name}-#{@version}"
498
659
  else
499
660
  "#{@name}-#{@version}-#{platform}"
500
- end
661
+ end
501
662
  end
502
-
663
+
664
+ # Returns the full name (name-version) of this gemspec using the original
665
+ # platform.
666
+ #
667
+ def original_name # :nodoc:
668
+ if platform == Gem::Platform::RUBY or platform.nil? then
669
+ "#{@name}-#{@version}"
670
+ else
671
+ "#{@name}-#{@version}-#{@original_platform}"
672
+ end
673
+ end
674
+
503
675
  # The full path to the gem (install path + full name).
504
676
  #
505
677
  # return:: [String] the full gem path
506
678
  #
507
679
  def full_gem_path
508
- File.join(installation_path, "gems", full_name)
680
+ path = File.join installation_path, 'gems', full_name
681
+ return path if File.directory? path
682
+ File.join installation_path, 'gems', original_name
509
683
  end
510
684
 
511
685
  # The default (generated) file name of the gem.
@@ -532,17 +706,20 @@ module Gem
532
706
  return @name == dependency.name &&
533
707
  dependency.version_requirements.satisfied_by?(@version)
534
708
  end
535
-
709
+
536
710
  # Comparison methods ---------------------------------------------
537
-
538
- # Compare specs (name then version).
539
- def <=>(other)
540
- [@name, @version] <=> [other.name, other.version]
711
+
712
+ def sort_obj
713
+ [@name, @version.to_ints, @new_platform == Gem::Platform::RUBY ? -1 : 1]
714
+ end
715
+
716
+ def <=>(other) # :nodoc:
717
+ sort_obj <=> other.sort_obj
541
718
  end
542
719
 
543
720
  # Tests specs for equality (across all attributes).
544
721
  def ==(other) # :nodoc:
545
- other.kind_of?(self.class) && same_attributes?(other)
722
+ self.class === other && same_attributes?(other)
546
723
  end
547
724
 
548
725
  alias eql? == # :nodoc:
@@ -561,39 +738,94 @@ module Gem
561
738
  hash_code + n
562
739
  }
563
740
  end
564
-
741
+
565
742
  # Export methods (YAML and Ruby code) ----------------------------
566
-
567
- # Returns an array of attribute names to be used when generating a
568
- # YAML representation of this object. If an attribute still has
569
- # its default value, it is omitted.
570
- def to_yaml_properties
743
+
744
+ def to_yaml(opts = {}) # :nodoc:
571
745
  mark_version
572
- @@attributes.map { |name, default| "@#{name}" }
746
+
747
+ attributes = @@attributes.map { |name,| name.to_s }.sort
748
+ attributes = attributes - %w[name version platform]
749
+
750
+ yaml = YAML.quick_emit object_id, opts do |out|
751
+ out.map taguri, to_yaml_style do |map|
752
+ map.add 'name', @name
753
+ map.add 'version', @version
754
+ platform = if String === @original_platform then
755
+ @original_platform
756
+ else
757
+ @original_platform.to_s
758
+ end
759
+ map.add 'platform', platform
760
+
761
+ attributes.each do |name|
762
+ map.add name, instance_variable_get("@#{name}")
763
+ end
764
+ end
765
+ end
766
+ end
767
+
768
+ def yaml_initialize(tag, vals) # :nodoc:
769
+ vals.each do |ivar, val|
770
+ instance_variable_set "@#{ivar}", val
771
+ end
772
+
773
+ @original_platform = @platform # for backwards compatibility
774
+ self.platform = Gem::Platform.new @platform
573
775
  end
574
776
 
575
- # Returns a Ruby code representation of this specification, such
576
- # that it can be eval'ed and reconstruct the same specification
577
- # later. Attributes that still have their default values are
578
- # omitted.
777
+ # Returns a Ruby code representation of this specification, such that it
778
+ # can be eval'ed and reconstruct the same specification later. Attributes
779
+ # that still have their default values are omitted.
579
780
  def to_ruby
580
781
  mark_version
581
- result = "Gem::Specification.new do |s|\n"
582
- @@attributes.each do |name, default|
583
- # TODO better implementation of next line (read_only_attribute? ... something like that)
584
- next if name == :dependencies or name == :specification_version
782
+ result = []
783
+ result << "Gem::Specification.new do |s|"
784
+
785
+ result << " s.name = #{ruby_code name}"
786
+ result << " s.version = #{ruby_code version}"
787
+ unless platform.nil? or platform == Gem::Platform::RUBY then
788
+ result << " s.platform = #{ruby_code original_platform}"
789
+ end
790
+ result << ""
791
+ result << " s.specification_version = #{specification_version} if s.respond_to? :specification_version="
792
+ result << ""
793
+ result << " s.required_rubygems_version = #{ruby_code required_rubygems_version} if s.respond_to? :required_rubygems_version="
794
+
795
+ handled = [
796
+ :dependencies,
797
+ :name,
798
+ :platform,
799
+ :required_rubygems_version,
800
+ :specification_version,
801
+ :version,
802
+ ]
803
+
804
+ attributes = @@attributes.sort_by { |name,| name.to_s }
805
+
806
+ attributes.each do |name, default|
807
+ next if handled.include? name
585
808
  current_value = self.send(name)
586
- result << " s.#{name} = #{ruby_code(current_value)}\n" unless current_value == default
809
+ if current_value != default or self.class.required_attribute? name then
810
+ result << " s.#{name} = #{ruby_code current_value}"
811
+ end
587
812
  end
813
+
814
+ result << "" unless dependencies.empty?
815
+
588
816
  dependencies.each do |dep|
589
817
  version_reqs_param = dep.requirements_list.inspect
590
- result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})\n"
818
+ result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
591
819
  end
592
- result << "end\n"
820
+
821
+ result << "end"
822
+ result << ""
823
+
824
+ result.join "\n"
593
825
  end
594
826
 
595
827
  # Validation and normalization methods ---------------------------
596
-
828
+
597
829
  # Checks that the specification contains all required fields, and
598
830
  # does a very basic sanity check.
599
831
  #
@@ -601,19 +833,32 @@ module Gem
601
833
  # the checks..
602
834
  def validate
603
835
  normalize
604
- if rubygems_version != RubyGemsVersion
605
- raise InvalidSpecificationException.new(%[
606
- Expected RubyGems Version #{RubyGemsVersion}, was #{rubygems_version}
607
- ].strip)
836
+
837
+ if rubygems_version != RubyGemsVersion then
838
+ raise Gem::InvalidSpecificationException,
839
+ "expected RubyGems version #{RubyGemsVersion}, was #{rubygems_version}"
608
840
  end
841
+
609
842
  @@required_attributes.each do |symbol|
610
- unless self.send(symbol)
611
- raise InvalidSpecificationException.new("Missing value for attribute #{symbol}")
843
+ unless self.send symbol then
844
+ raise Gem::InvalidSpecificationException,
845
+ "missing value for attribute #{symbol}"
612
846
  end
613
847
  end
614
- if require_paths.empty?
615
- raise InvalidSpecificationException.new("Gem spec needs to have at least one require_path")
848
+
849
+ if require_paths.empty? then
850
+ raise Gem::InvalidSpecificationException,
851
+ "specification must have at least one require_path"
852
+ end
853
+
854
+ case platform
855
+ when Gem::Platform, Platform::RUBY then # ok
856
+ else
857
+ raise Gem::InvalidSpecificationException,
858
+ "invalid platform #{platform.inspect}, see Gem::Platform"
616
859
  end
860
+
861
+ true
617
862
  end
618
863
 
619
864
  # Normalize the list of files so that:
@@ -671,31 +916,19 @@ module Gem
671
916
  end
672
917
  end
673
918
 
674
- # Duplicate an object unless it's an immediate value.
675
- def copy_of(obj)
676
- case obj
677
- when Numeric, Symbol, true, false, nil then obj
678
- else obj.dup
679
- end
680
- end
681
-
682
- def as_array(items)
683
- items.to_ary
684
- rescue NoMethodError => ex
685
- [items]
686
- end
687
-
688
919
  # Return a string containing a Ruby code representation of the
689
920
  # given object.
690
921
  def ruby_code(obj)
691
922
  case obj
692
- when String then '%q{' + obj + '}'
693
- when Array then obj.inspect
694
- when Gem::Version then obj.to_s.inspect
695
- when Date, Time then '%q{' + obj.strftime('%Y-%m-%d') + '}'
696
- when Numeric then obj.inspect
697
- when true, false, nil then obj.inspect
698
- when Gem::Version::Requirement then "Gem::Version::Requirement.new(#{obj.to_s.inspect})"
923
+ when String then '%q{' + obj + '}'
924
+ when Array then obj.inspect
925
+ when Gem::Version then obj.to_s.inspect
926
+ when Date then '%q{' + obj.strftime('%Y-%m-%d') + '}'
927
+ when Time then '%q{' + obj.strftime('%Y-%m-%d') + '}'
928
+ when Numeric then obj.inspect
929
+ when true, false, nil then obj.inspect
930
+ when Gem::Platform then "Gem::Platform.new(#{obj.to_a.inspect})"
931
+ when Gem::Requirement then "Gem::Requirement.new(#{obj.to_s.inspect})"
699
932
  else raise Exception, "ruby_code case not handled: #{obj.class}"
700
933
  end
701
934
  end