nanoc 3.3.6 → 3.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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