nanoc 3.3.6 → 3.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.md +6 -0
- data/lib/nanoc.rb +1 -1
- data/lib/nanoc/base/compilation/compiler.rb +1 -1
- data/lib/nanoc/base/compilation/dependency_tracker.rb +10 -2
- data/lib/nanoc/base/source_data/item.rb +10 -0
- data/lib/nanoc/cli/command_runner.rb +0 -1
- data/lib/nanoc/cli/commands/deploy.rb +1 -1
- data/lib/nanoc/cli/error_handler.rb +22 -1
- data/lib/nanoc/data_sources/filesystem.rb +11 -3
- data/lib/nanoc/filters/relativize_paths.rb +1 -1
- data/lib/nanoc/helpers/capturing.rb +27 -0
- data/lib/nanoc/helpers/filtering.rb +2 -0
- data/tasks/test.rake +2 -2
- data/test/cli/commands/test_deploy.rb +1 -1
- data/test/cli/test_cli.rb +5 -0
- data/test/data_sources/test_filesystem_verbose.rb +1 -1
- data/test/extra/validators/test_links.rb +3 -3
- data/test/filters/test_relativize_paths.rb +1 -1
- data/test/helper.rb +6 -0
- data/test/helpers/test_capturing.rb +134 -0
- data/test/helpers/test_filtering.rb +20 -0
- metadata +3 -3
data/NEWS.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# nanoc news
|
2
2
|
|
3
|
+
## 3.3.7 (2012-05-28)
|
4
|
+
|
5
|
+
* Added filename to YAML parser errors
|
6
|
+
* Fixed issue which caused extra dependencies to be generated
|
7
|
+
* Made timing information take filtering helper into account
|
8
|
+
|
3
9
|
## 3.3.6 (2012-04-27)
|
4
10
|
|
5
11
|
* Fixed issue with relative_link_to stripping HTML boilerplate
|
data/lib/nanoc.rb
CHANGED
@@ -370,7 +370,7 @@ module Nanoc
|
|
370
370
|
# Calculate rule memory if we haven’t yet done do
|
371
371
|
rules_collection.new_rule_memory_for_rep(rep)
|
372
372
|
|
373
|
-
if !outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
|
373
|
+
if !rep.item.forced_outdated? && !outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
|
374
374
|
# Reuse content
|
375
375
|
Nanoc::NotificationCenter.post(:cached_content_used, rep)
|
376
376
|
rep.content = compiled_content_cache[rep]
|
@@ -37,8 +37,8 @@ module Nanoc
|
|
37
37
|
super('tmp/dependencies', 4)
|
38
38
|
|
39
39
|
@objects = objects
|
40
|
-
|
41
|
-
@
|
40
|
+
@graph = Nanoc::DirectedGraph.new([ nil ] + @objects)
|
41
|
+
@stack = []
|
42
42
|
end
|
43
43
|
|
44
44
|
# Starts listening for dependency messages (`:visit_started` and
|
@@ -75,6 +75,14 @@ module Nanoc
|
|
75
75
|
Nanoc::NotificationCenter.remove(:visit_ended, self)
|
76
76
|
end
|
77
77
|
|
78
|
+
# @return The topmost item on the stack, i.e. the one currently being
|
79
|
+
# compiled
|
80
|
+
#
|
81
|
+
# @api private
|
82
|
+
def top
|
83
|
+
@stack.last
|
84
|
+
end
|
85
|
+
|
78
86
|
# Returns the direct dependencies for the given object.
|
79
87
|
#
|
80
88
|
# The direct dependencies of the given object include the items and
|
@@ -294,6 +294,16 @@ module Nanoc
|
|
294
294
|
@identifier = *source
|
295
295
|
end
|
296
296
|
|
297
|
+
# @api private
|
298
|
+
def forced_outdated=(bool)
|
299
|
+
@forced_outdated = bool
|
300
|
+
end
|
301
|
+
|
302
|
+
# @api private
|
303
|
+
def forced_outdated?
|
304
|
+
@forced_outdated || false
|
305
|
+
end
|
306
|
+
|
297
307
|
# @deprecated Access the modification time using `item[:mtime]` instead.
|
298
308
|
def mtime
|
299
309
|
self[:mtime]
|
@@ -16,7 +16,7 @@ Available deployers: #{deployer_names.join(', ')}
|
|
16
16
|
EOS
|
17
17
|
|
18
18
|
option :t, :target, 'specify the location to deploy to', :argument => :required
|
19
|
-
flag :
|
19
|
+
flag :L, :list, 'list available locations to deploy to'
|
20
20
|
option :n, :'dry-run', 'show what would be deployed'
|
21
21
|
|
22
22
|
module Nanoc::CLI::Commands
|
@@ -20,7 +20,28 @@ module Nanoc::CLI
|
|
20
20
|
#
|
21
21
|
# @return [void]
|
22
22
|
def self.handle_while(params={}, &block)
|
23
|
-
|
23
|
+
if @disabled
|
24
|
+
yield
|
25
|
+
else
|
26
|
+
self.new(params).handle_while(&block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Disables error handling. This is used by the test cases to prevent error
|
31
|
+
# from being handled by the CLI while tests are running.
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
def self.disable
|
35
|
+
@disabled = true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Re-enables error handling after it was disabled. This is used by the test
|
39
|
+
# cases to prevent error from being handled by the CLI while tests are
|
40
|
+
# running.
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
def self.enable
|
44
|
+
@disabled = false
|
24
45
|
end
|
25
46
|
|
26
47
|
# Enables error handling in the given block. This method should not be
|
@@ -229,8 +229,12 @@ module Nanoc::DataSources
|
|
229
229
|
# Read content and metadata from separate files
|
230
230
|
if meta_filename
|
231
231
|
content = content_filename ? read(content_filename) : ''
|
232
|
-
|
233
|
-
|
232
|
+
meta_raw = read(meta_filename)
|
233
|
+
begin
|
234
|
+
meta = YAML.load(meta_raw) || {}
|
235
|
+
rescue Exception => e
|
236
|
+
raise "Could not parse YAML for #{meta_filename}: #{e.message}"
|
237
|
+
end
|
234
238
|
return [ meta, content ]
|
235
239
|
end
|
236
240
|
|
@@ -251,7 +255,11 @@ module Nanoc::DataSources
|
|
251
255
|
end
|
252
256
|
|
253
257
|
# Parse
|
254
|
-
|
258
|
+
begin
|
259
|
+
meta = YAML.load(pieces[2]) || {}
|
260
|
+
rescue Exception => e
|
261
|
+
raise "Could not parse YAML for #{content_filename}: #{e.message}"
|
262
|
+
end
|
255
263
|
content = pieces[4..-1].join.strip
|
256
264
|
|
257
265
|
# Done
|
@@ -55,7 +55,7 @@ module Nanoc::Filters
|
|
55
55
|
# this cleans the XHTML namespace to process fragments and full
|
56
56
|
# documents in the same way. At least, Nokogiri adds this namespace
|
57
57
|
# if detects the `html` element.
|
58
|
-
content.sub
|
58
|
+
content = content.sub(%r{(<html[^>]+)xmlns="http://www.w3.org/1999/xhtml"}, '\1')
|
59
59
|
end
|
60
60
|
|
61
61
|
nokogiri_process(content, selectors, namespaces, klass, params[:type])
|
@@ -62,6 +62,12 @@ module Nanoc::Helpers
|
|
62
62
|
@captures_store ||= CapturesStore.new
|
63
63
|
end
|
64
64
|
|
65
|
+
# @api private
|
66
|
+
def captures_store_compiled_items
|
67
|
+
require 'set'
|
68
|
+
@captures_store_compiled_items ||= Set.new
|
69
|
+
end
|
70
|
+
|
65
71
|
end
|
66
72
|
|
67
73
|
# @overload content_for(name, &block)
|
@@ -112,6 +118,27 @@ module Nanoc::Helpers
|
|
112
118
|
item = args[0]
|
113
119
|
name = args[1]
|
114
120
|
|
121
|
+
# Create dependency
|
122
|
+
current_item = @site.compiler.dependency_tracker.top
|
123
|
+
if item != current_item
|
124
|
+
Nanoc::NotificationCenter.post(:visit_started, item)
|
125
|
+
Nanoc::NotificationCenter.post(:visit_ended, item)
|
126
|
+
|
127
|
+
# This is an extremely ugly hack to get the compiler to recompile the
|
128
|
+
# item from which we use content. For this, we need to manually edit
|
129
|
+
# the content attribute to reset it. :(
|
130
|
+
# FIXME clean this up
|
131
|
+
if !@site.captures_store_compiled_items.include? item
|
132
|
+
@site.captures_store_compiled_items << item
|
133
|
+
item.forced_outdated = true
|
134
|
+
item.reps.each do |r|
|
135
|
+
raw_content = item.raw_content
|
136
|
+
r.content = { :raw => raw_content, :last => raw_content }
|
137
|
+
@site.compiler.send(:compile_rep, r)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
115
142
|
# Get content
|
116
143
|
@site.captures_store[item, name.to_sym]
|
117
144
|
end
|
@@ -38,7 +38,9 @@ module Nanoc::Helpers
|
|
38
38
|
filter = klass.new(@item_rep.assigns)
|
39
39
|
|
40
40
|
# Filter captured data
|
41
|
+
Nanoc::NotificationCenter.post(:filtering_started, @item_rep, filter_name)
|
41
42
|
filtered_data = filter.run(data, arguments)
|
43
|
+
Nanoc::NotificationCenter.post(:filtering_ended, @item_rep, filter_name)
|
42
44
|
|
43
45
|
# Append filtered data to buffer
|
44
46
|
buffer = eval('_erbout', block.binding)
|
data/tasks/test.rake
CHANGED
@@ -18,7 +18,7 @@ test = namespace :test do
|
|
18
18
|
test_files = Dir['test/**/*_spec.rb'] + Dir['test/**/test_*.rb']
|
19
19
|
test_files.each { |f| require f }
|
20
20
|
|
21
|
-
MiniTest::Unit.new.run($VERBOSE ? %w( --verbose ) : %w())
|
21
|
+
exit MiniTest::Unit.new.run($VERBOSE ? %w( --verbose ) : %w())
|
22
22
|
end
|
23
23
|
|
24
24
|
# test:...
|
@@ -36,7 +36,7 @@ test = namespace :test do
|
|
36
36
|
test_files = Dir["test/#{dir}/**/*_spec.rb"] + Dir["test/#{dir}/**/test_*.rb"]
|
37
37
|
test_files.each { |f| require f }
|
38
38
|
|
39
|
-
MiniTest::Unit.new.run($VERBOSE ? %w( --verbose ) : %w())
|
39
|
+
exit MiniTest::Unit.new.run($VERBOSE ? %w( --verbose ) : %w())
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -60,7 +60,7 @@ class Nanoc::CLI::Commands::DeployTest < MiniTest::Unit::TestCase
|
|
60
60
|
File.open('output/blah.html', 'w') { |io| io.write 'moo' }
|
61
61
|
|
62
62
|
ios = capturing_stdio do
|
63
|
-
Nanoc::CLI.run %w( deploy -
|
63
|
+
Nanoc::CLI.run %w( deploy -L )
|
64
64
|
end
|
65
65
|
|
66
66
|
assert ios[:stdout].include?('Available deployment configurations:')
|
data/test/cli/test_cli.rb
CHANGED
@@ -87,6 +87,11 @@ EOS
|
|
87
87
|
|
88
88
|
# Run command
|
89
89
|
position_before = $stderr.tell
|
90
|
+
Nanoc::CLI::ErrorHandler.disable
|
91
|
+
assert_raises RuntimeError do
|
92
|
+
Nanoc::CLI.run %w( _test )
|
93
|
+
end
|
94
|
+
Nanoc::CLI::ErrorHandler.enable
|
90
95
|
assert_raises SystemExit do
|
91
96
|
Nanoc::CLI.run %w( _test )
|
92
97
|
end
|
@@ -53,9 +53,9 @@ class Nanoc::Extra::Validators::LinksTest < MiniTest::Unit::TestCase
|
|
53
53
|
validator = Nanoc::Extra::Validators::Links.new('output', [ 'index.html' ])
|
54
54
|
|
55
55
|
# Test
|
56
|
-
assert_equal 200, validator.send(:fetch_http_status_for, URI.parse('http://
|
57
|
-
assert_equal 200, validator.send(:fetch_http_status_for, URI.parse('https://
|
58
|
-
assert_equal 404, validator.send(:fetch_http_status_for, URI.parse('http://
|
56
|
+
assert_equal 200, validator.send(:fetch_http_status_for, URI.parse('http://httpstat.us/200'))
|
57
|
+
assert_equal 200, validator.send(:fetch_http_status_for, URI.parse('https://httpstat.us/200'))
|
58
|
+
assert_equal 404, validator.send(:fetch_http_status_for, URI.parse('http://httpstat.us/404'))
|
59
59
|
end
|
60
60
|
|
61
61
|
end
|
data/test/helper.rb
CHANGED
@@ -120,9 +120,15 @@ EOS
|
|
120
120
|
# Enter tmp
|
121
121
|
FileUtils.mkdir_p('tmp')
|
122
122
|
FileUtils.cd('tmp')
|
123
|
+
|
124
|
+
# Let us get to the raw errors
|
125
|
+
Nanoc::CLI::ErrorHandler.disable
|
123
126
|
end
|
124
127
|
|
125
128
|
def teardown
|
129
|
+
# Restore normal error handling
|
130
|
+
Nanoc::CLI::ErrorHandler.enable
|
131
|
+
|
126
132
|
# Exit tmp
|
127
133
|
FileUtils.cd('..')
|
128
134
|
FileUtils.rm_rf('tmp')
|
@@ -9,6 +9,11 @@ class Nanoc::Helpers::CapturingTest < MiniTest::Unit::TestCase
|
|
9
9
|
def test_content_for
|
10
10
|
require 'erb'
|
11
11
|
|
12
|
+
File.open('Rules', 'w') do |io|
|
13
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
14
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
15
|
+
end
|
16
|
+
|
12
17
|
# Build content to be evaluated
|
13
18
|
content = "head <% content_for :sidebar do %>\n" +
|
14
19
|
" <%= 1+2 %>\n" +
|
@@ -49,6 +54,11 @@ class Nanoc::Helpers::CapturingTest < MiniTest::Unit::TestCase
|
|
49
54
|
def test_content_for_recursively
|
50
55
|
require 'erb'
|
51
56
|
|
57
|
+
File.open('Rules', 'w') do |io|
|
58
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
59
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
60
|
+
end
|
61
|
+
|
52
62
|
content = <<EOS
|
53
63
|
head
|
54
64
|
<% content_for :box do %>
|
@@ -74,6 +84,11 @@ EOS
|
|
74
84
|
def test_different_sites
|
75
85
|
require 'erb'
|
76
86
|
|
87
|
+
File.open('Rules', 'w') do |io|
|
88
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
89
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
90
|
+
end
|
91
|
+
|
77
92
|
@site = Nanoc3::Site.new({})
|
78
93
|
@item = Nanoc::Item.new('content', {}, '/')
|
79
94
|
content = "<% content_for :a do %>Content One<% end %>"
|
@@ -91,4 +106,123 @@ EOS
|
|
91
106
|
assert_equal 'Content Two', content_for(@item, :b)
|
92
107
|
end
|
93
108
|
|
109
|
+
def test_dependencies
|
110
|
+
with_site do |site|
|
111
|
+
# Prepare
|
112
|
+
File.open('lib/helpers.rb', 'w') do |io|
|
113
|
+
io.write 'include Nanoc::Helpers::Capturing'
|
114
|
+
end
|
115
|
+
File.open('content/includer.erb', 'w') do |io|
|
116
|
+
io.write '[<%= content_for(@items.find { |i| i.identifier == \'/includee/\' }, :blah) %>]'
|
117
|
+
end
|
118
|
+
File.open('Rules', 'w') do |io|
|
119
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
120
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Compile once
|
124
|
+
File.open('content/includee.erb', 'w') do |io|
|
125
|
+
io.write '{<% content_for :blah do %>Old content<% end %>}'
|
126
|
+
end
|
127
|
+
Nanoc::CLI.run(%w(compile))
|
128
|
+
assert_equal '[Old content]', File.read('output/includer/index.html')
|
129
|
+
|
130
|
+
# Compile again
|
131
|
+
File.open('content/includee.erb', 'w') do |io|
|
132
|
+
io.write '{<% content_for :blah do %>New content<% end %>}'
|
133
|
+
end
|
134
|
+
Nanoc::CLI.run(%w(compile))
|
135
|
+
assert_equal '[New content]', File.read('output/includer/index.html')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_dependency_without_item_variable
|
140
|
+
with_site do |site|
|
141
|
+
# Prepare
|
142
|
+
File.open('lib/helpers.rb', 'w') do |io|
|
143
|
+
io.write "include Nanoc::Helpers::Capturing\n"
|
144
|
+
io.write "include Nanoc::Helpers::Rendering\n"
|
145
|
+
end
|
146
|
+
File.open('content/includer.erb', 'w') do |io|
|
147
|
+
io.write '{<%= render \'partial\', :item => nil %>}'
|
148
|
+
end
|
149
|
+
File.open('layouts/partial.erb', 'w') do |io|
|
150
|
+
io.write '[<%= @item.inspect %>-<%= content_for(@items.find { |i| i.identifier == \'/includee/\' }, :blah) %>]'
|
151
|
+
end
|
152
|
+
File.open('Rules', 'w') do |io|
|
153
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
154
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
155
|
+
io.write "layout '*', :erb\n"
|
156
|
+
end
|
157
|
+
|
158
|
+
# Compile once
|
159
|
+
File.open('content/includee.erb', 'w') do |io|
|
160
|
+
io.write '{<% content_for :blah do %>Old content<% end %>}'
|
161
|
+
end
|
162
|
+
Nanoc::CLI.run(%w(compile))
|
163
|
+
assert_equal '{[nil-Old content]}', File.read('output/includer/index.html')
|
164
|
+
|
165
|
+
# Compile again
|
166
|
+
File.open('content/includee.erb', 'w') do |io|
|
167
|
+
io.write '{<% content_for :blah do %>New content<% end %>}'
|
168
|
+
end
|
169
|
+
Nanoc::CLI.run(%w(compile))
|
170
|
+
assert_equal '{[nil-New content]}', File.read('output/includer/index.html')
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_self
|
175
|
+
with_site do |site|
|
176
|
+
File.open('lib/helpers.rb', 'w') do |io|
|
177
|
+
io.write 'include Nanoc::Helpers::Capturing'
|
178
|
+
end
|
179
|
+
|
180
|
+
File.open('content/self.erb', 'w') do |io|
|
181
|
+
io.write "<% content_for :foo do %>Foo!<% end %>"
|
182
|
+
io.write "<%= content_for(@item, :foo) %>"
|
183
|
+
end
|
184
|
+
|
185
|
+
File.open('Rules', 'w') do |io|
|
186
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
187
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
188
|
+
end
|
189
|
+
|
190
|
+
Nanoc::CLI.run(%w(compile))
|
191
|
+
assert_equal 'Foo!', File.read('output/self/index.html')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_recompile_dependency
|
196
|
+
with_site do |site|
|
197
|
+
# Prepare
|
198
|
+
File.open('lib/helpers.rb', 'w') do |io|
|
199
|
+
io.write 'include Nanoc::Helpers::Capturing'
|
200
|
+
end
|
201
|
+
File.open('content/includee.erb', 'w') do |io|
|
202
|
+
io.write '{<% content_for :blah do %>Content<% end %>}'
|
203
|
+
end
|
204
|
+
File.open('Rules', 'w') do |io|
|
205
|
+
io.write "compile '*' do ; filter :erb ; end\n"
|
206
|
+
io.write "route '*' do ; item.identifier + 'index.html' ; end\n"
|
207
|
+
end
|
208
|
+
|
209
|
+
# Compile once
|
210
|
+
File.open('content/includer.erb', 'w') do |io|
|
211
|
+
io.write 'Old-<%= content_for(@items.find { |i| i.identifier == \'/includee/\' }, :blah) %>'
|
212
|
+
end
|
213
|
+
Nanoc::CLI.run(%w(compile))
|
214
|
+
assert_equal 'Old-Content', File.read('output/includer/index.html')
|
215
|
+
|
216
|
+
# Compile again
|
217
|
+
$LOUD = true
|
218
|
+
File.open('content/includer.erb', 'w') do |io|
|
219
|
+
io.write 'New-<%= content_for(@items.find { |i| i.identifier == \'/includee/\' }, :blah) %>'
|
220
|
+
end
|
221
|
+
Nanoc::CLI.run(%w(compile))
|
222
|
+
assert_equal 'New-Content', File.read('output/includer/index.html')
|
223
|
+
end
|
224
|
+
ensure
|
225
|
+
$LOUD = false
|
226
|
+
end
|
227
|
+
|
94
228
|
end
|
@@ -103,4 +103,24 @@ class Nanoc::Helpers::FilteringTest < MiniTest::Unit::TestCase
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
def test_notifications
|
107
|
+
notifications = Set.new
|
108
|
+
Nanoc::NotificationCenter.on(:filtering_started) { notifications << :filtering_started }
|
109
|
+
Nanoc::NotificationCenter.on(:filtering_ended) { notifications << :filtering_ended }
|
110
|
+
|
111
|
+
# Build content to be evaluated
|
112
|
+
content = "<% filter :erb do %>\n" +
|
113
|
+
" ... stuff ...\n" +
|
114
|
+
"<% end %>\n"
|
115
|
+
|
116
|
+
# Mock item and rep
|
117
|
+
@item_rep = mock
|
118
|
+
@item_rep.expects(:assigns).returns({})
|
119
|
+
|
120
|
+
::ERB.new(content).result(binding)
|
121
|
+
|
122
|
+
assert notifications.include?(:filtering_started)
|
123
|
+
assert notifications.include?(:filtering_ended)
|
124
|
+
end
|
125
|
+
|
106
126
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: cri
|
@@ -399,7 +399,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
399
399
|
version: '0'
|
400
400
|
requirements: []
|
401
401
|
rubyforge_project:
|
402
|
-
rubygems_version: 1.8.
|
402
|
+
rubygems_version: 1.8.24
|
403
403
|
signing_key:
|
404
404
|
specification_version: 3
|
405
405
|
summary: a web publishing system written in Ruby for building small to medium-sized
|