nanoc 4.4.4 → 4.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +9 -8
  4. data/NEWS.md +10 -0
  5. data/lib/nanoc/base.rb +0 -3
  6. data/lib/nanoc/base/contracts_support.rb +55 -2
  7. data/lib/nanoc/base/core_ext/array.rb +0 -2
  8. data/lib/nanoc/base/core_ext/hash.rb +0 -2
  9. data/lib/nanoc/base/entities.rb +1 -0
  10. data/lib/nanoc/base/entities/context.rb +1 -4
  11. data/lib/nanoc/base/entities/directed_graph.rb +0 -10
  12. data/lib/nanoc/base/entities/identifiable_collection.rb +1 -2
  13. data/lib/nanoc/base/entities/identifier.rb +6 -8
  14. data/lib/nanoc/base/entities/item_rep.rb +12 -18
  15. data/lib/nanoc/base/{compilation → entities}/outdatedness_reasons.rb +0 -0
  16. data/lib/nanoc/base/entities/site.rb +3 -19
  17. data/lib/nanoc/base/errors.rb +9 -0
  18. data/lib/nanoc/base/memoization.rb +0 -2
  19. data/lib/nanoc/base/repos/checksum_store.rb +21 -14
  20. data/lib/nanoc/base/repos/compiled_content_cache.rb +11 -15
  21. data/lib/nanoc/base/repos/dependency_store.rb +8 -27
  22. data/lib/nanoc/base/services.rb +3 -0
  23. data/lib/nanoc/base/services/compiler.rb +379 -0
  24. data/lib/nanoc/base/services/compiler_loader.rb +3 -1
  25. data/lib/nanoc/base/services/executor.rb +27 -41
  26. data/lib/nanoc/base/services/item_rep_builder.rb +4 -0
  27. data/lib/nanoc/base/services/item_rep_writer.rb +5 -2
  28. data/lib/nanoc/base/{compilation → services}/outdatedness_checker.rb +1 -1
  29. data/lib/nanoc/base/views/post_compile_item_rep_view.rb +1 -1
  30. data/lib/nanoc/base/views/view_context.rb +3 -3
  31. data/lib/nanoc/checking/check.rb +1 -1
  32. data/lib/nanoc/checking/checks/external_links.rb +1 -1
  33. data/lib/nanoc/cli.rb +0 -4
  34. data/lib/nanoc/cli/commands/compile.rb +2 -2
  35. data/lib/nanoc/cli/commands/shell.rb +1 -1
  36. data/lib/nanoc/data_sources/filesystem.rb +10 -20
  37. data/lib/nanoc/data_sources/filesystem/errors.rb +55 -0
  38. data/lib/nanoc/filters/asciidoc.rb +0 -2
  39. data/lib/nanoc/filters/coffeescript.rb +0 -2
  40. data/lib/nanoc/filters/colorize_syntax.rb +0 -2
  41. data/lib/nanoc/filters/handlebars.rb +0 -2
  42. data/lib/nanoc/filters/mustache.rb +0 -2
  43. data/lib/nanoc/filters/redcarpet.rb +0 -4
  44. data/lib/nanoc/filters/slim.rb +0 -2
  45. data/lib/nanoc/filters/typogruby.rb +0 -2
  46. data/lib/nanoc/filters/xsl.rb +0 -2
  47. data/lib/nanoc/filters/yui_compressor.rb +0 -2
  48. data/lib/nanoc/helpers/capturing.rb +22 -19
  49. data/lib/nanoc/helpers/link_to.rb +3 -7
  50. data/lib/nanoc/helpers/rendering.rb +1 -1
  51. data/lib/nanoc/rule_dsl/action_provider.rb +2 -2
  52. data/lib/nanoc/rule_dsl/compiler_dsl.rb +0 -2
  53. data/lib/nanoc/rule_dsl/recording_executor.rb +6 -6
  54. data/lib/nanoc/rule_dsl/rule.rb +0 -2
  55. data/lib/nanoc/rule_dsl/rule_context.rb +3 -3
  56. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +5 -5
  57. data/lib/nanoc/spec.rb +1 -1
  58. data/lib/nanoc/version.rb +1 -1
  59. data/test/base/test_compiler.rb +3 -1
  60. data/test/base/test_dependency_tracker.rb +0 -19
  61. data/test/base/test_item_rep.rb +3 -0
  62. data/test/cli/commands/test_create_site.rb +1 -1
  63. data/test/data_sources/test_filesystem.rb +5 -5
  64. data/test/filters/test_coffeescript.rb +2 -0
  65. data/test/filters/test_handlebars.rb +4 -0
  66. data/test/filters/test_uglify_js.rb +4 -0
  67. data/test/filters/test_xsl.rb +1 -1
  68. data/test/helper.rb +6 -0
  69. data/test/helpers/test_capturing.rb +6 -1
  70. data/test/helpers/test_xml_sitemap.rb +1 -1
  71. metadata +6 -6
  72. data/lib/nanoc/base/compilation/compiler.rb +0 -295
  73. data/test/base/test_checksum_store.rb +0 -28
@@ -1,5 +1,7 @@
1
1
  class Nanoc::Filters::UglifyJSTest < Nanoc::TestCase
2
2
  def test_filter
3
+ skip_v8_on_ruby24
4
+
3
5
  if_have 'uglifier' do
4
6
  # Create filter
5
7
  filter = ::Nanoc::Filters::UglifyJS.new
@@ -12,6 +14,8 @@ class Nanoc::Filters::UglifyJSTest < Nanoc::TestCase
12
14
  end
13
15
 
14
16
  def test_filter_with_options
17
+ skip_v8_on_ruby24
18
+
15
19
  if_have 'uglifier' do
16
20
  filter = ::Nanoc::Filters::UglifyJS.new
17
21
  input = "if(donkey) alert('It is a donkey!');"
@@ -97,7 +97,7 @@ EOS
97
97
  reps: :__irrelevat_reps,
98
98
  items: :__irrelevat_items,
99
99
  dependency_tracker: @dependency_tracker,
100
- compiler: :__irrelevat_compiler,
100
+ compilation_context: :__irrelevat_compiler,
101
101
  )
102
102
  end
103
103
 
@@ -28,6 +28,12 @@ module Nanoc::TestHelpers
28
28
  ENV.key?('DISABLE_NOKOGIRI')
29
29
  end
30
30
 
31
+ def skip_v8_on_ruby24
32
+ if ENV.key?('DISABLE_V8')
33
+ skip 'V8 specs are disabled (broken on Ruby 2.4)'
34
+ end
35
+ end
36
+
31
37
  def if_have(*libs)
32
38
  libs.each do |lib|
33
39
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && lib == 'nokogiri' && disable_nokogiri?
@@ -12,10 +12,15 @@ class Nanoc::Helpers::CapturingTest < Nanoc::TestCase
12
12
  reps: item_rep_repo_for(item),
13
13
  items: :__irrelevant__,
14
14
  dependency_tracker: :__irrelevant__,
15
- compiler: :__irrelevant__,
15
+ compilation_context: :__irrelevant__,
16
16
  )
17
17
  end
18
18
 
19
+ def before
20
+ super
21
+ Nanoc::CLI::ErrorHandler.enable
22
+ end
23
+
19
24
  def test_dependencies
20
25
  with_site do |_site|
21
26
  # Prepare
@@ -6,7 +6,7 @@ class Nanoc::Helpers::XMLSitemapTest < Nanoc::TestCase
6
6
 
7
7
  @reps = Nanoc::Int::ItemRepRepo.new
8
8
  dependency_tracker = Nanoc::Int::DependencyTracker.new(nil)
9
- @view_context = Nanoc::ViewContext.new(reps: @reps, items: nil, dependency_tracker: dependency_tracker, compiler: :__irrelevant__)
9
+ @view_context = Nanoc::ViewContext.new(reps: @reps, items: nil, dependency_tracker: dependency_tracker, compilation_context: :__irrelevant__)
10
10
 
11
11
  @items = nil
12
12
  @item = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.4
4
+ version: 4.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-19 00:00:00.000000000 Z
11
+ date: 2016-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cri
@@ -124,9 +124,6 @@ files:
124
124
  - bin/nanoc
125
125
  - lib/nanoc.rb
126
126
  - lib/nanoc/base.rb
127
- - lib/nanoc/base/compilation/compiler.rb
128
- - lib/nanoc/base/compilation/outdatedness_checker.rb
129
- - lib/nanoc/base/compilation/outdatedness_reasons.rb
130
127
  - lib/nanoc/base/contracts_support.rb
131
128
  - lib/nanoc/base/core_ext.rb
132
129
  - lib/nanoc/base/core_ext/array.rb
@@ -147,6 +144,7 @@ files:
147
144
  - lib/nanoc/base/entities/item_rep.rb
148
145
  - lib/nanoc/base/entities/layout.rb
149
146
  - lib/nanoc/base/entities/lazy_value.rb
147
+ - lib/nanoc/base/entities/outdatedness_reasons.rb
150
148
  - lib/nanoc/base/entities/outdatedness_status.rb
151
149
  - lib/nanoc/base/entities/pattern.rb
152
150
  - lib/nanoc/base/entities/processing_action.rb
@@ -176,6 +174,7 @@ files:
176
174
  - lib/nanoc/base/services.rb
177
175
  - lib/nanoc/base/services/action_provider.rb
178
176
  - lib/nanoc/base/services/checksummer.rb
177
+ - lib/nanoc/base/services/compiler.rb
179
178
  - lib/nanoc/base/services/compiler_loader.rb
180
179
  - lib/nanoc/base/services/dependency_tracker.rb
181
180
  - lib/nanoc/base/services/executor.rb
@@ -185,6 +184,7 @@ files:
185
184
  - lib/nanoc/base/services/item_rep_selector.rb
186
185
  - lib/nanoc/base/services/item_rep_writer.rb
187
186
  - lib/nanoc/base/services/notification_center.rb
187
+ - lib/nanoc/base/services/outdatedness_checker.rb
188
188
  - lib/nanoc/base/services/outdatedness_rule.rb
189
189
  - lib/nanoc/base/services/outdatedness_rules.rb
190
190
  - lib/nanoc/base/services/pruner.rb
@@ -251,6 +251,7 @@ files:
251
251
  - lib/nanoc/cli/stream_cleaners/utf8.rb
252
252
  - lib/nanoc/data_sources.rb
253
253
  - lib/nanoc/data_sources/filesystem.rb
254
+ - lib/nanoc/data_sources/filesystem/errors.rb
254
255
  - lib/nanoc/data_sources/filesystem/tools.rb
255
256
  - lib/nanoc/deploying.rb
256
257
  - lib/nanoc/deploying/deployer.rb
@@ -321,7 +322,6 @@ files:
321
322
  - test/base/core_ext/hash_spec.rb
322
323
  - test/base/core_ext/pathname_spec.rb
323
324
  - test/base/core_ext/string_spec.rb
324
- - test/base/test_checksum_store.rb
325
325
  - test/base/test_code_snippet.rb
326
326
  - test/base/test_compiler.rb
327
327
  - test/base/test_context.rb
@@ -1,295 +0,0 @@
1
- module Nanoc::Int
2
- # Responsible for compiling a site’s item representations.
3
- #
4
- # The compilation process makes use of notifications (see
5
- # {Nanoc::Int::NotificationCenter}) to track dependencies between items,
6
- # layouts, etc. The following notifications are used:
7
- #
8
- # * `compilation_started` — indicates that the compiler has started
9
- # compiling this item representation. Has one argument: the item
10
- # representation itself. Only one item can be compiled at a given moment;
11
- # therefore, it is not possible to get two consecutive
12
- # `compilation_started` notifications without also getting a
13
- # `compilation_ended` notification in between them.
14
- #
15
- # * `compilation_ended` — indicates that the compiler has finished compiling
16
- # this item representation (either successfully or with failure). Has one
17
- # argument: the item representation itself.
18
- #
19
- # @api private
20
- class Compiler
21
- # @api private
22
- attr_reader :site
23
-
24
- # @api private
25
- attr_reader :compiled_content_cache
26
-
27
- # @api private
28
- attr_reader :checksum_store
29
-
30
- # @api private
31
- attr_reader :rule_memory_store
32
-
33
- # @api private
34
- attr_reader :action_provider
35
-
36
- # @api private
37
- attr_reader :dependency_store
38
-
39
- # @api private
40
- attr_reader :outdatedness_checker
41
-
42
- # @api private
43
- attr_reader :reps
44
-
45
- def initialize(site, compiled_content_cache:, checksum_store:, rule_memory_store:, action_provider:, dependency_store:, outdatedness_checker:, reps:)
46
- @site = site
47
-
48
- @compiled_content_cache = compiled_content_cache
49
- @checksum_store = checksum_store
50
- @rule_memory_store = rule_memory_store
51
- @dependency_store = dependency_store
52
- @outdatedness_checker = outdatedness_checker
53
- @reps = reps
54
- @action_provider = action_provider
55
- end
56
-
57
- def run_all
58
- @action_provider.preprocess(@site)
59
- build_reps
60
- prune
61
- run
62
- @action_provider.postprocess(@site, @reps)
63
- end
64
-
65
- def run
66
- load_stores
67
- @site.freeze
68
-
69
- # Determine which reps need to be recompiled
70
- forget_dependencies_if_outdated
71
-
72
- compile_reps
73
- store
74
- ensure
75
- Nanoc::Int::TempFilenameFactory.instance.cleanup(
76
- Nanoc::Filter::TMP_BINARY_ITEMS_DIR,
77
- )
78
- Nanoc::Int::TempFilenameFactory.instance.cleanup(
79
- Nanoc::Int::ItemRepWriter::TMP_TEXT_ITEMS_DIR,
80
- )
81
- end
82
-
83
- def load_stores
84
- # FIXME: icky hack to update the dependency store’s list of objects
85
- # (does not include preprocessed objects otherwise)
86
- dependency_store.objects = site.items.to_a + site.layouts.to_a
87
-
88
- stores.each(&:load)
89
- end
90
-
91
- # Store the modified helper data used for compiling the site.
92
- #
93
- # @return [void]
94
- def store
95
- # Calculate rule memory
96
- (@reps.to_a + @site.layouts.to_a).each do |obj|
97
- rule_memory_store[obj] = action_provider.memory_for(obj).serialize
98
- end
99
-
100
- # Calculate checksums
101
- objects_to_checksum =
102
- site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config]
103
- objects_to_checksum.each { |obj| checksum_store.add(obj) }
104
-
105
- # Store
106
- stores.each(&:store)
107
- end
108
-
109
- def build_reps
110
- builder = Nanoc::Int::ItemRepBuilder.new(
111
- site, action_provider, @reps
112
- )
113
- builder.run
114
- end
115
-
116
- # @param [Nanoc::Int::ItemRep] rep The item representation for which the
117
- # assigns should be fetched
118
- #
119
- # @return [Hash] The assigns that should be used in the next filter/layout
120
- # operation
121
- #
122
- # @api private
123
- def assigns_for(rep, dependency_tracker)
124
- content_or_filename_assigns =
125
- if rep.binary?
126
- { filename: rep.snapshot_contents[:last].filename }
127
- else
128
- { content: rep.snapshot_contents[:last].string }
129
- end
130
-
131
- view_context = create_view_context(dependency_tracker)
132
-
133
- content_or_filename_assigns.merge(
134
- item: Nanoc::ItemWithRepsView.new(rep.item, view_context),
135
- rep: Nanoc::ItemRepView.new(rep, view_context),
136
- item_rep: Nanoc::ItemRepView.new(rep, view_context),
137
- items: Nanoc::ItemCollectionWithRepsView.new(site.items, view_context),
138
- layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context),
139
- config: Nanoc::ConfigView.new(site.config, view_context),
140
- )
141
- end
142
-
143
- def create_view_context(dependency_tracker)
144
- Nanoc::ViewContext.new(
145
- reps: @reps,
146
- items: @site.items,
147
- dependency_tracker: dependency_tracker,
148
- compiler: self,
149
- )
150
- end
151
-
152
- # @api private
153
- def filter_name_and_args_for_layout(layout)
154
- mem = action_provider.memory_for(layout)
155
- if mem.nil? || mem.size != 1 || !mem[0].is_a?(Nanoc::Int::ProcessingActions::Filter)
156
- # FIXME: Provide a nicer error message
157
- raise Nanoc::Int::Errors::Generic, "No rule memory found for #{layout.identifier}"
158
- end
159
- [mem[0].filter_name, mem[0].params]
160
- end
161
-
162
- private
163
-
164
- def prune
165
- if site.config[:prune][:auto_prune]
166
- Nanoc::Pruner.new(site.config, reps, exclude: prune_config_exclude).run
167
- end
168
- end
169
-
170
- def prune_config
171
- site.config[:prune] || {}
172
- end
173
-
174
- def prune_config_exclude
175
- prune_config[:exclude] || {}
176
- end
177
-
178
- def compile_reps
179
- # Assign snapshots
180
- @reps.each do |rep|
181
- rep.snapshot_defs = action_provider.snapshots_defs_for(rep)
182
- end
183
-
184
- # Find item reps to compile and compile them
185
- outdated_reps = @reps.select { |r| outdatedness_checker.outdated?(r) }
186
- selector = Nanoc::Int::ItemRepSelector.new(outdated_reps)
187
- selector.each do |rep|
188
- handle_errors_while(rep) { compile_rep(rep) }
189
- end
190
- end
191
-
192
- def handle_errors_while(item_rep)
193
- yield
194
- rescue => e
195
- raise Nanoc::Int::Errors::CompilationError.new(e, item_rep)
196
- end
197
-
198
- # Compiles the given item representation.
199
- #
200
- # This method should not be called directly; please use
201
- # {Nanoc::Int::Compiler#run} instead, and pass this item representation's item
202
- # as its first argument.
203
- #
204
- # @param [Nanoc::Int::ItemRep] rep The rep that is to be compiled
205
- #
206
- # @return [void]
207
- def compile_rep(rep)
208
- @fibers ||= {}
209
- @fibers[rep] ||=
210
- Fiber.new do
211
- begin
212
- dependency_tracker = Nanoc::Int::DependencyTracker.new(@dependency_store)
213
- dependency_tracker.enter(rep.item)
214
-
215
- if can_reuse_content_for_rep?(rep)
216
- Nanoc::Int::NotificationCenter.post(:cached_content_used, rep)
217
- rep.snapshot_contents = compiled_content_cache[rep]
218
- else
219
- recalculate_content_for_rep(rep, dependency_tracker)
220
- end
221
-
222
- rep.compiled = true
223
- compiled_content_cache[rep] = rep.snapshot_contents
224
-
225
- @fibers.delete(rep)
226
- ensure
227
- dependency_tracker.exit
228
- end
229
- end
230
-
231
- fiber = @fibers[rep]
232
- while fiber.alive?
233
- Nanoc::Int::NotificationCenter.post(:compilation_started, rep)
234
- res = fiber.resume
235
-
236
- case res
237
- when Nanoc::Int::Errors::UnmetDependency
238
- Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, res)
239
- raise(res)
240
- when Proc
241
- fiber.resume(res.call)
242
- else
243
- # TODO: raise
244
- end
245
- end
246
-
247
- Nanoc::Int::NotificationCenter.post(:compilation_ended, rep)
248
- end
249
-
250
- # @return [Boolean]
251
- def can_reuse_content_for_rep?(rep)
252
- !outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
253
- end
254
-
255
- # @return [void]
256
- def recalculate_content_for_rep(rep, dependency_tracker)
257
- executor = Nanoc::Int::Executor.new(self, dependency_tracker)
258
-
259
- action_provider.memory_for(rep).each do |action|
260
- case action
261
- when Nanoc::Int::ProcessingActions::Filter
262
- executor.filter(rep, action.filter_name, action.params)
263
- when Nanoc::Int::ProcessingActions::Layout
264
- executor.layout(rep, action.layout_identifier, action.params)
265
- when Nanoc::Int::ProcessingActions::Snapshot
266
- executor.snapshot(rep, action.snapshot_name, final: action.final?, path: action.path)
267
- else
268
- raise "Internal inconsistency: unknown action #{action.inspect}"
269
- end
270
- end
271
- end
272
-
273
- # Clears the list of dependencies for items that will be recompiled.
274
- #
275
- # @return [void]
276
- def forget_dependencies_if_outdated
277
- @site.items.each do |i|
278
- if @reps[i].any? { |r| outdatedness_checker.outdated?(r) }
279
- @dependency_store.forget_dependencies_for(i)
280
- end
281
- end
282
- end
283
-
284
- # Returns all stores that can load/store data that can be used for
285
- # compilation.
286
- def stores
287
- [
288
- checksum_store,
289
- compiled_content_cache,
290
- @dependency_store,
291
- rule_memory_store,
292
- ]
293
- end
294
- end
295
- end
@@ -1,28 +0,0 @@
1
- class Nanoc::Int::ChecksumStoreTest < Nanoc::TestCase
2
- def test_get_with_existing_object
3
- require 'pstore'
4
-
5
- # Create store
6
- FileUtils.mkdir_p('tmp')
7
- pstore = PStore.new('tmp/checksums')
8
- pstore.transaction do
9
- pstore[:data] = { [:item, '/moo/'] => 'zomg' }
10
- pstore[:version] = 1
11
- end
12
-
13
- # Check
14
- store = Nanoc::Int::ChecksumStore.new
15
- store.load
16
- obj = Nanoc::Int::Item.new('Moo?', {}, '/moo/')
17
- assert_equal 'zomg', store[obj]
18
- end
19
-
20
- def test_get_with_nonexistant_object
21
- store = Nanoc::Int::ChecksumStore.new
22
- store.load
23
-
24
- # Check
25
- obj = Nanoc::Int::Item.new('Moo?', {}, '/animals/cow/')
26
- assert_equal nil, store[obj]
27
- end
28
- end