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 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
@@ -3,7 +3,7 @@
3
3
  module Nanoc
4
4
 
5
5
  # The current nanoc version.
6
- VERSION = '3.3.6'
6
+ VERSION = '3.3.7'
7
7
 
8
8
  # @return [String] A string containing information about this nanoc version
9
9
  # and its environment (Ruby engine and version, Rubygems version if any).
@@ -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
- @graph = Nanoc::DirectedGraph.new([ nil ] + @objects)
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]
@@ -56,7 +56,6 @@ module Nanoc::CLI
56
56
  #
57
57
  # @return [void]
58
58
  def require_site
59
- @site = nil
60
59
  if site.nil?
61
60
  $stderr.puts 'The current working directory does not seem to be a ' +
62
61
  'valid/complete nanoc site directory; aborting.'
@@ -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 :l, :list, 'list available locations to deploy to'
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
- self.new(params).handle_while(&block)
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
- meta = YAML.load(read(meta_filename)) || {}
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
- meta = YAML.load(pieces[2]) || {}
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!(%r{(<html[^>]+)xmlns="http://www.w3.org/1999/xhtml"}, '\1')
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)
@@ -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 -l )
63
+ Nanoc::CLI.run %w( deploy -L )
64
64
  end
65
65
 
66
66
  assert ios[:stdout].include?('Available deployment configurations:')
@@ -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
@@ -80,7 +80,7 @@ class Nanoc::DataSources::FilesystemVerboseTest < MiniTest::Unit::TestCase
80
80
  end
81
81
 
82
82
  # Load
83
- items = data_source.items
83
+ items = data_source.items.sort_by { |i| i[:title] }
84
84
 
85
85
  # Check
86
86
  assert_equal 2, items.size
@@ -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://www.apple.com/'))
57
- assert_equal 200, validator.send(:fetch_http_status_for, URI.parse('https://www.apple.com/'))
58
- assert_equal 404, validator.send(:fetch_http_status_for, URI.parse('http://www.apple.com/sdfghgfdsdfgh'))
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
@@ -654,7 +654,7 @@ XML
654
654
  XML
655
655
 
656
656
  # Test
657
- actual_content = filter.run(raw_content, :type => :xhtml)
657
+ actual_content = filter.run(raw_content.freeze, :type => :xhtml)
658
658
  assert_equal(expected_content, actual_content)
659
659
  end
660
660
  end
@@ -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.6
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-04-27 00:00:00.000000000 Z
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.22
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