mime-types 1.16 → 1.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gemtest +0 -0
  2. data/.hoerc +12 -0
  3. data/{History.txt → History.rdoc} +17 -0
  4. data/Licence.rdoc +10 -0
  5. data/Manifest.txt +36 -6
  6. data/README.rdoc +19 -0
  7. data/Rakefile +138 -255
  8. data/lib/mime/types.rb +117 -25
  9. data/lib/mime/{types.rb.data → types/application} +306 -690
  10. data/lib/mime/types/application.mac +2 -0
  11. data/lib/mime/types/application.nonstandard +114 -0
  12. data/lib/mime/types/application.obsolete +40 -0
  13. data/lib/mime/types/audio +131 -0
  14. data/lib/mime/types/audio.nonstandard +10 -0
  15. data/lib/mime/types/audio.obsolete +1 -0
  16. data/lib/mime/types/image +43 -0
  17. data/lib/mime/types/image.nonstandard +17 -0
  18. data/lib/mime/types/image.obsolete +5 -0
  19. data/lib/mime/types/message +19 -0
  20. data/lib/mime/types/message.obsolete +1 -0
  21. data/lib/mime/types/model +15 -0
  22. data/lib/mime/types/multipart +14 -0
  23. data/lib/mime/types/multipart.nonstandard +1 -0
  24. data/lib/mime/types/multipart.obsolete +7 -0
  25. data/lib/mime/types/other.nonstandard +8 -0
  26. data/lib/mime/types/text +54 -0
  27. data/lib/mime/types/text.nonstandard +5 -0
  28. data/lib/mime/types/text.obsolete +7 -0
  29. data/lib/mime/types/text.vms +1 -0
  30. data/lib/mime/types/video +68 -0
  31. data/lib/mime/types/video.nonstandard +11 -0
  32. data/lib/mime/types/video.obsolete +3 -0
  33. data/mime-types.gemspec +40 -26
  34. data/test/test_mime_type.rb +262 -300
  35. data/test/test_mime_types.rb +74 -97
  36. data/type-lists/application.txt +951 -0
  37. data/type-lists/audio.txt +132 -0
  38. data/type-lists/image.txt +43 -0
  39. data/type-lists/message.txt +20 -0
  40. data/type-lists/model.txt +15 -0
  41. data/type-lists/multipart.txt +14 -0
  42. data/type-lists/text.txt +57 -0
  43. data/type-lists/video.txt +67 -0
  44. metadata +205 -64
  45. data.tar.gz.sig +0 -2
  46. data/Install.txt +0 -17
  47. data/Licence.txt +0 -15
  48. data/README.txt +0 -28
  49. data/setup.rb +0 -1585
  50. metadata.gz.sig +0 -0
File without changes
data/.hoerc ADDED
@@ -0,0 +1,12 @@
1
+ ---
2
+ publish_on_announce: false
3
+ exclude: !ruby/regexp /\.(?:svn|git)|(?:\.(?:swp|hoerc|DS_Store)|~|email.txt)$|(?:coverage|type-lists)\//
4
+ signing_key_file: ~/.gem/gem-private_key.pem
5
+ signing_cert_file: ~/.gem/gem-public_cert.pem
6
+ blogs:
7
+ - user: user
8
+ url: url
9
+ extra_headers:
10
+ mt_convert_breaks: markdown
11
+ blog_id: blog_id
12
+ password: password
@@ -1,3 +1,20 @@
1
+ == MIME::Types 1.17 / 2011-MM-DD
2
+ * Minor Enhancements:
3
+ * Implemented modern 'hoe' semantics.
4
+ * Switched to minitest instead of test/unit.
5
+ * Converted documentation from .txt to .rdoc.
6
+ * Removed setup.rb. (Issue #3:
7
+ https://github.com/halostatue/mime-types/issues/3).
8
+ * Should no longer complain about missing RubyGems keys (Issue #2:
9
+ https://github.com/halostatue/mime-types/issues/2).
10
+ * Added .mp4 and .mpg4 as recognized extensions for
11
+ {application,audio,video}/mp4 per RFC4337. (Issue #1:
12
+ https://github.com/halostatue/mime-types/issues/1).
13
+ * Added audio/x-aac and .aac per RubyForge issue #28054
14
+ (http://rubyforge.org/tracker/index.php?func=detail&aid=28054&group_id=293&atid=1194).
15
+ * Made it much easier to update MIME types from this point forward.
16
+ * Updated MIME types from IANA.
17
+
1
18
  == MIME::Types 1.16
2
19
  * Made compatible with Ruby 1.8.6, 1.8.7, and 1.9.1.
3
20
  * Switched to the 'hoe' gem system and added a lot of build-time tools.
@@ -0,0 +1,10 @@
1
+ == License
2
+
3
+ This software is available under a triple disjunctive license:
4
+ {Ruby's license}[http://www.ruby-lang.org/en/LICENSE.txt],
5
+ the
6
+ {Perl Artistic license}[http://www.perl.com/pub/a/language/misc/Artistic.html],
7
+ or the {GNU GPL version 2}[http://www.gnu.org/licenses/old-licenses/gpl-2.0.html]
8
+ (or at your option, any later verison).
9
+
10
+ If you do not accept one of these licences, you may not use this software.
@@ -1,12 +1,42 @@
1
- History.txt
2
- Install.txt
3
- Licence.txt
1
+ .hoerc
2
+ History.rdoc
3
+ Licence.rdoc
4
4
  Manifest.txt
5
- README.txt
5
+ README.rdoc
6
6
  Rakefile
7
7
  lib/mime/types.rb
8
- lib/mime/types.rb.data
8
+ lib/mime/types/application
9
+ lib/mime/types/application.mac
10
+ lib/mime/types/application.nonstandard
11
+ lib/mime/types/application.obsolete
12
+ lib/mime/types/audio
13
+ lib/mime/types/audio.nonstandard
14
+ lib/mime/types/audio.obsolete
15
+ lib/mime/types/image
16
+ lib/mime/types/image.nonstandard
17
+ lib/mime/types/image.obsolete
18
+ lib/mime/types/message
19
+ lib/mime/types/message.obsolete
20
+ lib/mime/types/model
21
+ lib/mime/types/multipart
22
+ lib/mime/types/multipart.nonstandard
23
+ lib/mime/types/multipart.obsolete
24
+ lib/mime/types/other.nonstandard
25
+ lib/mime/types/text
26
+ lib/mime/types/text.nonstandard
27
+ lib/mime/types/text.obsolete
28
+ lib/mime/types/text.vms
29
+ lib/mime/types/video
30
+ lib/mime/types/video.nonstandard
31
+ lib/mime/types/video.obsolete
9
32
  mime-types.gemspec
10
- setup.rb
11
33
  test/test_mime_type.rb
12
34
  test/test_mime_types.rb
35
+ type-lists/application.txt
36
+ type-lists/audio.txt
37
+ type-lists/image.txt
38
+ type-lists/message.txt
39
+ type-lists/model.txt
40
+ type-lists/multipart.txt
41
+ type-lists/text.txt
42
+ type-lists/video.txt
@@ -0,0 +1,19 @@
1
+ = MIME::Types for Ruby
2
+
3
+ == Description
4
+
5
+ This library allows for the identification of a file's likely MIME content
6
+ type. This is release 1.17. The identification of MIME content type is based
7
+ on a file's filename extensions.
8
+
9
+ MIME::Types for Ruby originally based on and synchronized with MIME::Types for
10
+ Perl by Mark Overmeer, copyright 2001 - 2009. As of version 1.15, the data
11
+ format for the MIME::Type list has changed and the synchronization will no
12
+ longer happen.
13
+
14
+ Homepage:: http://mime-types.rubyforge.org/
15
+ GitHub:: http://github.com/halostatue/mime-types/
16
+ Copyright:: 2002 - 2011, Austin Ziegler
17
+ Based in part on prior work copyright Mark Overmeer
18
+
19
+ :include: License.rdoc
data/Rakefile CHANGED
@@ -1,289 +1,191 @@
1
- #! /usr/bin/env rake
2
- #--
3
- # MIME::Types
4
- # A Ruby implementation of a MIME Types information library. Based in spirit
5
- # on the Perl MIME::Types information library by Mark Overmeer.
6
- # http://rubyforge.org/projects/mime-types/
7
- #
8
- # Licensed under the Ruby disjunctive licence with the GNU GPL or the Perl
9
- # Artistic licence. See Licence.txt for more information.
10
- #
11
- # Copyright 2003 - 2009 Austin Ziegler
12
- #++
1
+ # -*- ruby encoding: utf-8 -*-
13
2
 
14
3
  require 'rubygems'
15
4
  require 'hoe'
16
5
 
17
- $LOAD_PATH.unshift('lib')
6
+ Hoe.plugin :doofus
7
+ Hoe.plugin :gemspec
8
+ Hoe.plugin :rubyforge
9
+ Hoe.plugin :git
10
+ Hoe.plugin :minitest
18
11
 
19
- require 'mime/types'
12
+ spec = Hoe.spec 'mime-types' do
13
+ self.rubyforge_name = self.name
20
14
 
21
- PKG_NAME = 'mime-types'
22
- PKG_VERSION = MIME::Types::VERSION
23
- PKG_DIST = "#{PKG_NAME}-#{PKG_VERSION}"
24
- PKG_TAR = "pkg/#{PKG_DIST}.tar.gz"
25
- MANIFEST = File.read("Manifest.txt").split
15
+ developer('Austin Ziegler', 'austin@rubyforge.org')
26
16
 
27
- hoe = Hoe.new PKG_NAME, PKG_VERSION do |p|
28
- p.rubyforge_name = PKG_NAME
29
- # This is a lie because I will continue to use Archive::Tar::Minitar.
30
- p.need_tar = false
31
- # need_zip - Should package create a zipfile? [default: false]
17
+ self.url = "http://mime-types.rubyforge.org/"
18
+ self.remote_rdoc_dir = 'rdoc'
19
+ self.rsync_args << ' --exclude=statsvn/'
32
20
 
33
- p.author = [ "Austin Ziegler" ]
34
- p.email = %W(austin@rubyforge.org)
35
- p.url = "http://mime-types.rubyforge.org/"
36
- p.summary = %q{Manages a MIME Content-Type database that will return the Content-Type for a given filename.}
37
- p.changes = p.paragraphs_of("History.txt", 0..0).join("\n\n")
38
- p.description = p.paragraphs_of("README.txt", 1..1).join("\n\n")
21
+ self.history_file = 'History.rdoc'
22
+ self.readme_file = 'README.rdoc'
23
+ self.extra_rdoc_files = FileList["*.rdoc"].to_a
39
24
 
40
- p.extra_dev_deps << %w(archive-tar-minitar ~>0.5)
41
- p.extra_dev_deps << %w(nokogiri ~>1.2)
42
- p.extra_dev_deps << %w(rcov ~>0.8)
43
-
44
- p.clean_globs << "coverage"
45
-
46
- p.spec_extras[:extra_rdoc_files] = MANIFEST.grep(/txt$/) - ["Manifest.txt"]
25
+ self.extra_dev_deps << ['nokogiri', '~> 1.5']
26
+ self.extra_dev_deps << ['minitest', '~> 2.0']
27
+ self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
28
+ self.extra_dev_deps << ['hoe-gemspec', '~> 1.0']
29
+ self.extra_dev_deps << ['hoe-git', '~> 1.0']
30
+ self.extra_dev_deps << ['hoe-seattlerb', '~> 1.0']
47
31
  end
48
32
 
49
- begin
50
- require 'rcov/rcovtask'
51
- Rcov::RcovTask.new do |t|
52
- t.libs << 'test'
53
- t.test_files = hoe.test_files
54
- t.verbose = true
55
- end
56
- rescue LoadError
57
- puts "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
58
- end
33
+ namespace :mime do
34
+ desc "Download the current MIME type registrations from IANA."
35
+ task :iana, :save, :destination do |t, args|
36
+ save_type = (args.save || :text).to_sym
59
37
 
60
- =begin
61
- require 'cucumber/rake/task'
62
- Cucumber::Rake::Task.new(:features)
63
- rescue LoadError
64
- puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
65
- =end
66
-
67
- desc "Build a MIME::Types .tar.gz distribution."
68
- task :tar => [ PKG_TAR ]
69
- file PKG_TAR => [ :test ] do |t|
70
- require 'archive/tar/minitar'
71
- require 'zlib'
72
- files = MANIFEST.map { |f|
73
- fn = File.join(PKG_DIST, f)
74
- tm = File.stat(f).mtime
75
-
76
- if File.directory?(f)
77
- { :name => fn, :mode => 0755, :dir => true, :mtime => tm }
38
+ case save_type
39
+ when :text, :both, :html
40
+ nil
78
41
  else
79
- mode = if f =~ %r{^bin}
80
- 0755
81
- else
82
- 0644
83
- end
84
- data = File.read(f)
85
- { :name => fn, :mode => mode, :data => data, :size => data.size,
86
- :mtime => tm }
87
- end
88
- }
89
-
90
- begin
91
- unless File.directory?(File.dirname(t.name))
92
- require 'fileutils'
93
- FileUtils.mkdir_p File.dirname(t.name)
94
- end
95
- tf = File.open(t.name, 'wb')
96
- gz = Zlib::GzipWriter.new(tf)
97
- tw = Archive::Tar::Minitar::Writer.new(gz)
98
-
99
- files.each do |entry|
100
- if entry[:dir]
101
- tw.mkdir(entry[:name], entry)
102
- else
103
- tw.add_file_simple(entry[:name], entry) { |os|
104
- os.write(entry[:data])
105
- }
106
- end
42
+ raise "Unknown save type provided. Must be one of text, both, or html."
107
43
  end
108
- ensure
109
- tw.close if tw
110
- gz.close if gz
111
- end
112
- end
113
- task :package => [ PKG_TAR ]
114
44
 
115
- desc "Build the manifest file from the current set of files."
116
- task :build_manifest do |t|
117
- require 'find'
45
+ destination = args.destination || "type-lists"
118
46
 
119
- hoerc = File.join(File.dirname(__FILE__), ".hoerc")
120
- hoerc = File.open(hoerc, "rb") { |f| f.read }
121
- hoerc = YAML::load(hoerc)
47
+ require 'open-uri'
48
+ require 'nokogiri'
49
+ require 'cgi'
122
50
 
123
- paths = []
124
- Find.find(".") do |path|
125
- next if File.directory?(path) || path =~ hoerc["exclude"]
126
- paths << path.sub(%r{^\./}, '')
127
- end
51
+ class IANAParser
52
+ include Comparable
128
53
 
129
- paths = paths.sort.join("\n")
54
+ INDEX = %q(http://www.iana.org/assignments/media-types/)
55
+ CONTACT_PEOPLE = %r{http://www.iana.org/assignments/contact-people.html?#(.*)}
56
+ RFC_EDITOR = %r{http://www.rfc-editor.org/rfc/rfc(\d+).txt}
57
+ IETF_RFC = %r{http://www.ietf.org/rfc/rfc(\d+).txt}
58
+ IETF_RFC_TOOLS = %r{http://tools.ietf.org/html/rfc(\d+)}
130
59
 
131
- File.open("Manifest.txt", "w") do |f|
132
- f.puts paths
133
- end
134
-
135
- puts paths
136
- end
60
+ class << self
61
+ def load_index
62
+ @types ||= {}
137
63
 
138
- desc "Download the current MIME type registrations from IANA."
139
- task :iana, :save, :destination do |t, args|
140
- save_type = args.save || :text
141
- save_type = save_type.to_sym
142
-
143
- case save_type
144
- when :text, :both, :html
145
- nil
146
- else
147
- raise "Unknown save type provided. Must be one of text, both, or html."
148
- end
149
-
150
- destination = args.destination || "type-lists"
64
+ Nokogiri::HTML(open(INDEX) { |f| f.read }).xpath('//p/a').each do |tag|
65
+ href_match = %r{^/assignments/media-types/(.+)/$}.match(tag['href'])
66
+ next if href_match.nil?
67
+ type = href_match.captures[0]
68
+ @types[tag.content] = IANAParser.new(tag.content, type)
69
+ end
70
+ end
151
71
 
152
- require 'open-uri'
153
- require 'nokogiri'
154
- require 'cgi'
72
+ attr_reader :types
73
+ end
155
74
 
156
- class IANAParser
157
- include Comparable
75
+ def initialize(name, type)
76
+ @name = name
77
+ @type = type
78
+ @url = File.join(INDEX, @type)
79
+ end
158
80
 
159
- INDEX = %q(http://www.iana.org/assignments/media-types/)
160
- CONTACT_PEOPLE = %r{http://www.iana.org/assignments/contact-people.html?#(.*)}
161
- RFC_EDITOR = %r{http://www.rfc-editor.org/rfc/rfc(\d+).txt}
162
- IETF_RFC = %r{http://www.ietf.org/rfc/rfc(\d+).txt}
163
- IETF_RFC_TOOLS = %r{http://tools.ietf.org/html/rfc(\d+)}
81
+ attr_reader :name
82
+ attr_reader :type
83
+ attr_reader :url
84
+ attr_reader :html
164
85
 
165
- class << self
166
- def load_index
167
- @types ||= {}
86
+ def download(name = nil)
87
+ @html = Nokogiri::HTML(open(name || @url) { |f| f.read })
88
+ end
168
89
 
169
- Nokogiri::HTML(open(INDEX) { |f| f.read }).xpath('//p/a').each do |tag|
170
- href_match = %r{^/assignments/media-types/(.+)/$}.match(tag['href'])
171
- next if href_match.nil?
172
- type = href_match.captures[0]
173
- @types[tag.content] = IANAParser.new(tag.content, type)
174
- end
90
+ def save_html
91
+ File.open("#@name.html", "wb") { |w| w.write @html }
175
92
  end
176
93
 
177
- attr_reader :types
178
- end
94
+ def <=>(o)
95
+ self.name <=> o.name
96
+ end
179
97
 
180
- def initialize(name, type)
181
- @name = name
182
- @type = type
183
- @url = File.join(INDEX, @type)
184
- end
98
+ def parse
99
+ nodes = html.xpath("//table//table//tr")
185
100
 
186
- attr_reader :name
187
- attr_reader :type
188
- attr_reader :url
189
- attr_reader :html
101
+ # How many <td> children does the first node have?
102
+ node_count = nodes.first.children.select { |n| n.elem? }.size
190
103
 
191
- def download(name = nil)
192
- @html = Nokogiri::HTML(open(name || @url) { |f| f.read })
193
- end
104
+ if node_count == 1
105
+ # The title node doesn't have what we expect. Let's try it based
106
+ # on the first real node.
107
+ node_count = nodes.first.next.children.select { |n| n.elem? }.size
108
+ end
194
109
 
195
- def save_html
196
- File.open("#@name.html", "wb") { |w| w.write @html }
197
- end
110
+ @mime_types = nodes.map do |node|
111
+ next if node == nodes.first
112
+ elems = node.children.select { |n| n.elem? }
113
+ next if elems.size.zero?
198
114
 
199
- def <=>(o)
200
- self.name <=> o.name
201
- end
115
+ raise "size mismatch #{elems.size} != #{node_count}" if node_count != elems.size
202
116
 
203
- def parse
204
- nodes = html.xpath("//table//table//tr")
205
-
206
- # How many <td> children does the first node have?
207
- node_count = nodes.first.children.select { |node| node.elem? }.size
208
-
209
- @mime_types = nodes.map do |node|
210
- next if node == nodes.first
211
- elems = node.children.select { |n| n.elem? }
212
- next if elems.size.zero?
213
- raise "size mismatch #{elems.size} != #{node_count}" if node_count != elems.size
214
-
215
- case elems.size
216
- when 3
217
- subtype_index = 1
218
- refnode_index = 2
219
- when 4
220
- subtype_index = 1
221
- refnode_index = 3
222
- else
223
- raise "Unknown element size."
224
- end
117
+ case elems.size
118
+ when 3
119
+ subtype_index = 1
120
+ refnode_index = 2
121
+ when 4
122
+ subtype_index = 1
123
+ refnode_index = 3
124
+ else
125
+ raise "Unknown element size."
126
+ end
225
127
 
226
- subtype = elems[subtype_index].content.chomp.strip
227
- refnodes = elems[refnode_index].children.select { |n| n.elem? }.map { |ref|
228
- case ref['href']
229
- when CONTACT_PEOPLE
230
- tag = CGI::unescape($1).chomp.strip
231
- if tag == ref.content
128
+ subtype = elems[subtype_index].content.chomp.strip
129
+ refnodes = elems[refnode_index].children.select { |n| n.elem? }.map { |ref|
130
+ case ref['href']
131
+ when CONTACT_PEOPLE
132
+ tag = CGI::unescape($1).chomp.strip
133
+ if tag == ref.content
232
134
  "[#{ref.content}]"
233
- else
135
+ else
234
136
  "[#{ref.content}=#{tag}]"
235
- end
236
- when RFC_EDITOR, IETF_RFC, IETF_RFC_TOOLS
137
+ end
138
+ when RFC_EDITOR, IETF_RFC, IETF_RFC_TOOLS
237
139
  "RFC#$1"
238
- when %r{(https?://.*)}
140
+ when %r{(https?://.*)}
239
141
  "{#{ref.content}=#$1}"
240
- else
241
- ref
242
- end
243
- }
244
- refs = refnodes.join(',')
142
+ else
143
+ ref
144
+ end
145
+ }
146
+ refs = refnodes.join(',')
245
147
 
246
148
  "#@type/#{subtype} 'IANA,#{refs}"
247
- end.compact
149
+ end.compact
248
150
 
249
- @mime_types
250
- end
151
+ @mime_types
152
+ end
251
153
 
252
- def save_text
253
- File.open("#@name.txt", "wb") { |w| w.write @mime_types.join("\n") }
154
+ def save_text
155
+ File.open("#@name.txt", "wb") { |w| w.write @mime_types.join("\n") }
156
+ end
254
157
  end
255
- end
256
158
 
257
- puts "Downloading index of MIME types from #{IANAParser::INDEX}."
258
- IANAParser.load_index
159
+ puts "Downloading index of MIME types from #{IANAParser::INDEX}."
160
+ IANAParser.load_index
259
161
 
260
- require 'fileutils'
261
- FileUtils.mkdir_p destination
262
- Dir.chdir destination do
263
- IANAParser.types.values.sort.each do |parser|
264
- next if parser.name == "example" or parser.name == "mime"
265
- puts "Downloading #{parser.name} from #{parser.url}"
266
- parser.download
162
+ require 'fileutils'
163
+ FileUtils.mkdir_p destination
164
+ Dir.chdir destination do
165
+ IANAParser.types.values.sort.each do |parser|
166
+ next if parser.name == "example" or parser.name == "mime"
167
+ puts "Downloading #{parser.name} from #{parser.url}"
168
+ parser.download
267
169
 
268
- if :html == save_type || :both == save_type
269
- puts "Saving #{parser.name}.html"
270
- parser.save_html
271
- end
170
+ if :html == save_type || :both == save_type
171
+ puts "Saving #{parser.name}.html"
172
+ parser.save_html
173
+ end
272
174
 
273
- puts "Parsing #{parser.name} HTML"
274
- parser.parse
175
+ puts "Parsing #{parser.name} HTML"
176
+ parser.parse
275
177
 
276
- if :text == save_type || :both == save_type
277
- puts "Saving #{parser.name}.txt"
278
- parser.save_text
178
+ if :text == save_type || :both == save_type
179
+ puts "Saving #{parser.name}.txt"
180
+ parser.save_text
181
+ end
279
182
  end
280
183
  end
281
184
  end
282
- end
283
185
 
284
- desc "Shows known MIME type sources."
285
- task :mime_type_sources do
286
- puts <<-EOS
186
+ desc "Shows known MIME type sources."
187
+ task :mime_type_sources do
188
+ puts <<-EOS
287
189
  http://www.ltsw.se/knbase/internet/mime.htp
288
190
  http://www.webmaster-toolkit.com/mime-types.shtml
289
191
  http://plugindoc.mozdev.org/winmime.php
@@ -291,26 +193,7 @@ http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-lat
291
193
  http://www.feedforall.com/mime-types.htm
292
194
  http://www.iana.org/assignments/media-types/
293
195
  EOS
294
- end
295
-
296
- desc "Validate the RubyGem spec for GitHub."
297
- task :github_validate_spec do |t|
298
- require 'yaml'
299
-
300
- require 'rubygems/specification'
301
- data = File.read("#{PKG_NAME}.gemspec")
302
- spec = nil
303
-
304
- if data !~ %r{!ruby/object:Gem::Specification}
305
- code = "$SAFE = 3\n#{data}"
306
- p code.split($/)[44]
307
- Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
308
- else
309
- spec = YAML.load(data)
310
196
  end
311
-
312
- spec.validate
313
-
314
- puts spec
315
- puts "OK"
316
197
  end
198
+
199
+ # vim: syntax=ruby