nanoc 4.4.5 → 4.4.6

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.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -2
  3. data/Gemfile.lock +37 -18
  4. data/NEWS.md +6 -0
  5. data/Rakefile +8 -20
  6. data/lib/nanoc/base/entities/code_snippet.rb +0 -2
  7. data/lib/nanoc/base/entities/item_rep.rb +4 -22
  8. data/lib/nanoc/base/entities/processing_actions/snapshot.rb +9 -7
  9. data/lib/nanoc/base/entities/rule_memory.rb +15 -7
  10. data/lib/nanoc/base/entities/snapshot_def.rb +2 -8
  11. data/lib/nanoc/base/repos/store.rb +2 -28
  12. data/lib/nanoc/base/services/checksummer.rb +9 -10
  13. data/lib/nanoc/base/services/compiler.rb +14 -16
  14. data/lib/nanoc/base/services/executor.rb +2 -13
  15. data/lib/nanoc/base/views/mixins/with_reps_view_mixin.rb +1 -1
  16. data/lib/nanoc/checking/checks/external_links.rb +2 -1
  17. data/lib/nanoc/cli/commands/compile.rb +8 -14
  18. data/lib/nanoc/extra/parallel_collection.rb +57 -0
  19. data/lib/nanoc/extra.rb +1 -0
  20. data/lib/nanoc/filters/mustache.rb +1 -1
  21. data/lib/nanoc/rule_dsl/recording_executor.rb +6 -34
  22. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +42 -12
  23. data/lib/nanoc/spec.rb +1 -1
  24. data/lib/nanoc/version.rb +1 -1
  25. data/nanoc.gemspec +1 -2
  26. data/spec/contributors_spec.rb +18 -0
  27. data/spec/nanoc/base/checksummer_spec.rb +381 -0
  28. data/spec/nanoc/base/compiler_spec.rb +181 -0
  29. data/spec/nanoc/base/entities/configuration_spec.rb +49 -0
  30. data/spec/nanoc/base/entities/content_spec.rb +193 -0
  31. data/spec/nanoc/base/entities/document_spec.rb +206 -0
  32. data/spec/nanoc/base/entities/identifier_spec.rb +460 -0
  33. data/spec/nanoc/base/entities/item_rep_spec.rb +226 -0
  34. data/spec/nanoc/base/entities/item_spec.rb +3 -0
  35. data/spec/nanoc/base/entities/layout_spec.rb +3 -0
  36. data/spec/nanoc/base/entities/lazy_value_spec.rb +106 -0
  37. data/spec/nanoc/base/entities/outdatedness_status_spec.rb +113 -0
  38. data/spec/nanoc/base/entities/pattern_spec.rb +125 -0
  39. data/spec/nanoc/base/entities/processing_action_spec.rb +9 -0
  40. data/spec/nanoc/base/entities/processing_actions/filter_spec.rb +18 -0
  41. data/spec/nanoc/base/entities/processing_actions/layout_spec.rb +18 -0
  42. data/spec/nanoc/base/entities/processing_actions/snapshot_spec.rb +32 -0
  43. data/spec/nanoc/base/entities/props_spec.rb +195 -0
  44. data/spec/nanoc/base/entities/rule_memory_spec.rb +131 -0
  45. data/spec/nanoc/base/entities/site_spec.rb +73 -0
  46. data/spec/nanoc/base/feature_spec.rb +107 -0
  47. data/spec/nanoc/base/filter_spec.rb +99 -0
  48. data/spec/nanoc/base/item_rep_writer_spec.rb +131 -0
  49. data/spec/nanoc/base/plugin_registry_spec.rb +29 -0
  50. data/spec/nanoc/base/repos/checksum_store_spec.rb +133 -0
  51. data/spec/nanoc/base/repos/compiled_content_cache_spec.rb +55 -0
  52. data/spec/nanoc/base/repos/config_loader_spec.rb +243 -0
  53. data/spec/nanoc/base/repos/dependency_store_spec.rb +195 -0
  54. data/spec/nanoc/base/repos/site_loader_spec.rb +214 -0
  55. data/spec/nanoc/base/services/dependency_tracker_spec.rb +238 -0
  56. data/spec/nanoc/base/services/executor_spec.rb +495 -0
  57. data/spec/nanoc/base/services/item_rep_router_spec.rb +134 -0
  58. data/spec/nanoc/base/services/item_rep_selector_spec.rb +169 -0
  59. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +370 -0
  60. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +432 -0
  61. data/spec/nanoc/base/services/pruner_spec.rb +105 -0
  62. data/spec/nanoc/base/services/temp_filename_factory_spec.rb +87 -0
  63. data/spec/nanoc/base/views/config_view_spec.rb +96 -0
  64. data/spec/nanoc/base/views/document_view_spec.rb +332 -0
  65. data/spec/nanoc/base/views/identifiable_collection_view_spec.rb +190 -0
  66. data/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb +18 -0
  67. data/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb +18 -0
  68. data/spec/nanoc/base/views/item_rep_collection_view_spec.rb +143 -0
  69. data/spec/nanoc/base/views/item_rep_view_spec.rb +265 -0
  70. data/spec/nanoc/base/views/item_view_spec.rb +341 -0
  71. data/spec/nanoc/base/views/layout_collection_view_spec.rb +18 -0
  72. data/spec/nanoc/base/views/layout_view_spec.rb +14 -0
  73. data/spec/nanoc/base/views/mutable_config_view_spec.rb +16 -0
  74. data/spec/nanoc/base/views/mutable_document_view_spec.rb +92 -0
  75. data/spec/nanoc/base/views/mutable_identifiable_collection_view_spec.rb +36 -0
  76. data/spec/nanoc/base/views/mutable_item_collection_view_spec.rb +49 -0
  77. data/spec/nanoc/base/views/mutable_item_view_spec.rb +22 -0
  78. data/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb +49 -0
  79. data/spec/nanoc/base/views/mutable_layout_view_spec.rb +13 -0
  80. data/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb +4 -0
  81. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +137 -0
  82. data/spec/nanoc/base/views/post_compile_item_view_spec.rb +56 -0
  83. data/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb +76 -0
  84. data/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb +66 -0
  85. data/spec/nanoc/cli/commands/compile_spec.rb +64 -0
  86. data/spec/nanoc/cli/commands/deploy_spec.rb +327 -0
  87. data/spec/nanoc/cli/commands/shell_spec.rb +54 -0
  88. data/spec/nanoc/cli/commands/show_data_spec.rb +126 -0
  89. data/spec/nanoc/cli/commands/show_rules_spec.rb +112 -0
  90. data/spec/nanoc/cli/commands/view_spec.rb +58 -0
  91. data/spec/nanoc/data_sources/filesystem_spec.rb +56 -0
  92. data/spec/nanoc/deploying/fog_spec.rb +193 -0
  93. data/spec/nanoc/extra/parallel_collection_spec.rb +108 -0
  94. data/spec/nanoc/filters/colorize_syntax/rouge_spec.rb +195 -0
  95. data/spec/nanoc/filters/less_spec.rb +120 -0
  96. data/spec/nanoc/helpers/blogging_spec.rb +216 -0
  97. data/spec/nanoc/helpers/breadcrumbs_spec.rb +133 -0
  98. data/spec/nanoc/helpers/capturing_spec.rb +181 -0
  99. data/spec/nanoc/helpers/child_parent_spec.rb +105 -0
  100. data/spec/nanoc/helpers/filtering_spec.rb +72 -0
  101. data/spec/nanoc/helpers/html_escape_spec.rb +35 -0
  102. data/spec/nanoc/helpers/link_to_spec.rb +275 -0
  103. data/spec/nanoc/helpers/rendering_spec.rb +141 -0
  104. data/spec/nanoc/helpers/tagging_spec.rb +104 -0
  105. data/spec/nanoc/helpers/text_spec.rb +58 -0
  106. data/spec/nanoc/integration/outdatedness_integration_spec.rb +208 -0
  107. data/spec/nanoc/regressions/gh_1015_spec.rb +17 -0
  108. data/spec/nanoc/regressions/gh_1031_spec.rb +54 -0
  109. data/spec/nanoc/regressions/gh_1035_spec.rb +33 -0
  110. data/spec/nanoc/regressions/gh_1040_spec.rb +22 -0
  111. data/spec/nanoc/regressions/gh_761_spec.rb +23 -0
  112. data/spec/nanoc/regressions/gh_767_spec.rb +19 -0
  113. data/spec/nanoc/regressions/gh_769_spec.rb +30 -0
  114. data/spec/nanoc/regressions/gh_776_spec.rb +43 -0
  115. data/spec/nanoc/regressions/gh_787_spec.rb +19 -0
  116. data/spec/nanoc/regressions/gh_795_spec.rb +19 -0
  117. data/spec/nanoc/regressions/gh_804_spec.rb +26 -0
  118. data/spec/nanoc/regressions/gh_807_spec.rb +17 -0
  119. data/spec/nanoc/regressions/gh_809_spec.rb +17 -0
  120. data/spec/nanoc/regressions/gh_813_spec.rb +22 -0
  121. data/spec/nanoc/regressions/gh_815_spec.rb +18 -0
  122. data/spec/nanoc/regressions/gh_828_spec.rb +23 -0
  123. data/spec/nanoc/regressions/gh_833_spec.rb +14 -0
  124. data/spec/nanoc/regressions/gh_841_spec.rb +15 -0
  125. data/spec/nanoc/regressions/gh_867_spec.rb +15 -0
  126. data/spec/nanoc/regressions/gh_882_spec.rb +29 -0
  127. data/spec/nanoc/regressions/gh_885_spec.rb +30 -0
  128. data/spec/nanoc/regressions/gh_891_spec.rb +26 -0
  129. data/spec/nanoc/regressions/gh_913_spec.rb +24 -0
  130. data/spec/nanoc/regressions/gh_928_spec.rb +5 -0
  131. data/spec/nanoc/regressions/gh_937_spec.rb +25 -0
  132. data/spec/nanoc/regressions/gh_942_spec.rb +21 -0
  133. data/spec/nanoc/regressions/gh_947_spec.rb +21 -0
  134. data/spec/nanoc/regressions/gh_948_spec.rb +16 -0
  135. data/spec/nanoc/regressions/gh_951_spec.rb +19 -0
  136. data/spec/nanoc/regressions/gh_954_spec.rb +33 -0
  137. data/spec/nanoc/regressions/gh_970a_spec.rb +17 -0
  138. data/spec/nanoc/regressions/gh_970b_spec.rb +50 -0
  139. data/spec/nanoc/regressions/gh_974_spec.rb +17 -0
  140. data/spec/nanoc/regressions/gh_981_spec.rb +21 -0
  141. data/spec/nanoc/rule_dsl/recording_executor_spec.rb +142 -0
  142. data/spec/nanoc/rule_dsl/rule_context_spec.rb +177 -0
  143. data/spec/nanoc/rule_dsl/rule_memory_calculator_spec.rb +233 -0
  144. data/spec/nanoc/rule_dsl/rules_collection_spec.rb +299 -0
  145. data/spec/regression_filenames_spec.rb +16 -0
  146. data/spec/spec_helper.rb +173 -0
  147. data/test/base/core_ext/array_spec.rb +2 -0
  148. data/test/base/core_ext/hash_spec.rb +2 -0
  149. data/test/base/core_ext/string_spec.rb +2 -0
  150. data/test/base/test_code_snippet.rb +2 -0
  151. data/test/base/test_compiler.rb +2 -0
  152. data/test/base/test_context.rb +4 -2
  153. data/test/base/test_data_source.rb +2 -0
  154. data/test/base/test_dependency_tracker.rb +2 -0
  155. data/test/base/test_directed_graph.rb +2 -0
  156. data/test/base/test_filter.rb +7 -5
  157. data/test/base/test_item.rb +2 -0
  158. data/test/base/test_item_array.rb +3 -1
  159. data/test/base/test_layout.rb +2 -0
  160. data/test/base/test_memoization.rb +2 -0
  161. data/test/base/test_notification_center.rb +2 -0
  162. data/test/base/test_outdatedness_checker.rb +2 -0
  163. data/test/base/test_plugin.rb +2 -0
  164. data/test/base/test_site.rb +2 -0
  165. data/test/base/test_store.rb +2 -0
  166. data/test/checking/checks/test_css.rb +2 -0
  167. data/test/checking/checks/test_external_links.rb +4 -2
  168. data/test/checking/checks/test_html.rb +2 -0
  169. data/test/checking/checks/test_internal_links.rb +5 -3
  170. data/test/checking/checks/test_mixed_content.rb +2 -0
  171. data/test/checking/checks/test_stale.rb +2 -0
  172. data/test/checking/test_check.rb +2 -0
  173. data/test/checking/test_dsl.rb +2 -0
  174. data/test/checking/test_runner.rb +2 -0
  175. data/test/cli/commands/test_check.rb +2 -0
  176. data/test/cli/commands/test_compile.rb +2 -0
  177. data/test/cli/commands/test_create_site.rb +2 -0
  178. data/test/cli/commands/test_help.rb +2 -0
  179. data/test/cli/commands/test_info.rb +2 -0
  180. data/test/cli/commands/test_prune.rb +2 -0
  181. data/test/cli/test_cleaning_stream.rb +2 -0
  182. data/test/cli/test_cli.rb +11 -9
  183. data/test/cli/test_error_handler.rb +2 -0
  184. data/test/cli/test_logger.rb +2 -0
  185. data/test/data_sources/test_filesystem.rb +8 -6
  186. data/test/data_sources/test_filesystem_tools.rb +2 -0
  187. data/test/deploying/test_fog.rb +2 -0
  188. data/test/deploying/test_rsync.rb +4 -2
  189. data/test/extra/core_ext/test_pathname.rb +2 -0
  190. data/test/extra/core_ext/test_time.rb +2 -0
  191. data/test/extra/test_link_collector.rb +2 -0
  192. data/test/extra/test_piper.rb +2 -0
  193. data/test/filters/colorize_syntax/test_coderay.rb +2 -0
  194. data/test/filters/colorize_syntax/test_common.rb +2 -0
  195. data/test/filters/colorize_syntax/test_pygmentize.rb +2 -0
  196. data/test/filters/colorize_syntax/test_pygments.rb +2 -0
  197. data/test/filters/colorize_syntax/test_simon.rb +2 -0
  198. data/test/filters/test_asciidoc.rb +2 -0
  199. data/test/filters/test_bluecloth.rb +2 -0
  200. data/test/filters/test_coffeescript.rb +2 -0
  201. data/test/filters/test_erb.rb +7 -5
  202. data/test/filters/test_erubis.rb +6 -4
  203. data/test/filters/test_haml.rb +7 -5
  204. data/test/filters/test_handlebars.rb +2 -0
  205. data/test/filters/test_kramdown.rb +2 -0
  206. data/test/filters/test_markaby.rb +2 -0
  207. data/test/filters/test_maruku.rb +2 -0
  208. data/test/filters/test_mustache.rb +4 -2
  209. data/test/filters/test_pandoc.rb +2 -0
  210. data/test/filters/test_rainpress.rb +2 -0
  211. data/test/filters/test_rdiscount.rb +2 -0
  212. data/test/filters/test_rdoc.rb +2 -0
  213. data/test/filters/test_redcarpet.rb +2 -0
  214. data/test/filters/test_redcloth.rb +2 -0
  215. data/test/filters/test_relativize_paths.rb +2 -0
  216. data/test/filters/test_rubypants.rb +2 -0
  217. data/test/filters/test_sass.rb +4 -2
  218. data/test/filters/test_slim.rb +4 -2
  219. data/test/filters/test_typogruby.rb +2 -0
  220. data/test/filters/test_uglify_js.rb +2 -0
  221. data/test/filters/test_xsl.rb +2 -0
  222. data/test/filters/test_yui_compressor.rb +5 -3
  223. data/test/helpers/test_blogging.rb +2 -0
  224. data/test/helpers/test_capturing.rb +2 -0
  225. data/test/helpers/test_link_to.rb +2 -0
  226. data/test/helpers/test_xml_sitemap.rb +2 -0
  227. data/test/rule_dsl/test_action_provider.rb +2 -0
  228. data/test/rule_dsl/test_compiler_dsl.rb +6 -4
  229. data/test/rule_dsl/test_rule.rb +2 -0
  230. data/test/rule_dsl/test_rules_collection.rb +2 -0
  231. data/test/test_gem.rb +2 -0
  232. metadata +124 -17
  233. data/test/base/test_item_rep.rb +0 -156
@@ -2,17 +2,6 @@ usage 'compile [options]'
2
2
  summary 'compile items of this site'
3
3
  description <<-EOS
4
4
  Compile all items of the current site.
5
-
6
- The compile command will show all items of the site as they are processed. The time spent compiling the item will be printed, as well as a status message, which can be one of the following:
7
-
8
- CREATED - The compiled item did not yet exist and has been created
9
-
10
- UPDATED - The compiled item did already exist and has been modified
11
-
12
- IDENTICAL - The item was deemed outdated and has been recompiled, but the compiled version turned out to be identical to the already existing version
13
-
14
- SKIP - The item was deemed not outdated and was therefore not recompiled
15
-
16
5
  EOS
17
6
  flag nil, :profile, 'profile compilation' if Nanoc::Feature.enabled?(Nanoc::Feature::PROFILER)
18
7
 
@@ -328,16 +317,16 @@ module Nanoc::CLI::Commands
328
317
 
329
318
  # @see Listener#start
330
319
  def start
331
- Nanoc::Int::NotificationCenter.on(:compilation_started) do |rep|
320
+ Nanoc::Int::NotificationCenter.on(:compilation_started, self) do |rep|
332
321
  @start_times[rep] = Time.now
333
322
  @acc_durations[rep] ||= 0.0
334
323
  end
335
324
 
336
- Nanoc::Int::NotificationCenter.on(:compilation_suspended) do |rep|
325
+ Nanoc::Int::NotificationCenter.on(:compilation_suspended, self) do |rep|
337
326
  @acc_durations[rep] += Time.now - @start_times[rep]
338
327
  end
339
328
 
340
- Nanoc::Int::NotificationCenter.on(:rep_written) do |rep, path, is_created, is_modified|
329
+ Nanoc::Int::NotificationCenter.on(:rep_written, self) do |rep, path, is_created, is_modified|
341
330
  @acc_durations[rep] += Time.now - @start_times[rep]
342
331
  duration = @acc_durations[rep]
343
332
 
@@ -358,6 +347,11 @@ module Nanoc::CLI::Commands
358
347
  # @see Listener#stop
359
348
  def stop
360
349
  super
350
+
351
+ Nanoc::Int::NotificationCenter.remove(:compilation_started, self)
352
+ Nanoc::Int::NotificationCenter.remove(:compilation_suspended, self)
353
+ Nanoc::Int::NotificationCenter.remove(:rep_written, self)
354
+
361
355
  @reps.select { |r| !r.compiled? }.each do |rep|
362
356
  rep.raw_paths.each do |_snapshot_name, raw_path|
363
357
  log(:low, :skip, raw_path, nil)
@@ -0,0 +1,57 @@
1
+ require 'thread'
2
+
3
+ module Nanoc::Extra
4
+ # @api private
5
+ class ParallelCollection
6
+ STOP = Object.new
7
+
8
+ include Nanoc::Int::ContractsSupport
9
+
10
+ contract C::RespondTo[:each], C::KeywordArgs[parallelism: Fixnum] => C::Any
11
+ def initialize(enum, parallelism: 2)
12
+ @enum = enum
13
+ @parallelism = parallelism
14
+ end
15
+
16
+ contract C::Func[C::Any => C::Any] => self
17
+ def each
18
+ queue = SizedQueue.new(2 * @parallelism)
19
+ error = nil
20
+
21
+ threads = (1..@parallelism).map do
22
+ Thread.new do
23
+ loop do
24
+ begin
25
+ elem = queue.pop
26
+ break if error
27
+ break if STOP.equal?(elem)
28
+ yield elem
29
+ rescue => err
30
+ error = err
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ @enum.each { |e| queue << e }
38
+ @parallelism.times { queue << STOP }
39
+
40
+ threads.each(&:join)
41
+
42
+ raise error if error
43
+ self
44
+ end
45
+
46
+ contract C::Func[C::Any => C::Any] => C::RespondTo[:each]
47
+ def map
48
+ [].tap do |all|
49
+ mutex = Mutex.new
50
+ each do |e|
51
+ res = yield(e)
52
+ mutex.synchronize { all << res }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/nanoc/extra.rb CHANGED
@@ -18,3 +18,4 @@ module Nanoc::Extra
18
18
  end
19
19
 
20
20
  require 'nanoc/extra/core_ext'
21
+ require 'nanoc/extra/parallel_collection'
@@ -11,7 +11,7 @@ module Nanoc::Filters
11
11
  #
12
12
  # @return [String] The filtered content
13
13
  def run(content, _params = {})
14
- context = item.attributes.merge({ yield: assigns[:content] })
14
+ context = item.attributes.merge(yield: assigns[:content])
15
15
  ::Mustache.render(content, context)
16
16
  end
17
17
  end
@@ -3,20 +3,8 @@ module Nanoc
3
3
  class RecordingExecutor
4
4
  include Nanoc::Int::ContractsSupport
5
5
 
6
- class PathWithoutInitialSlashError < ::Nanoc::Error
7
- def initialize(rep, basic_path)
8
- super("The path returned for the #{rep.inspect} item representation, “#{basic_path}”, does not start with a slash. Please ensure that all routing rules return a path that starts with a slash.")
9
- end
10
- end
11
-
12
- attr_reader :rule_memory
13
-
14
- def initialize(item_rep, rules_collection, site)
15
- @item_rep = item_rep
16
- @rules_collection = rules_collection
17
- @site = site
18
-
19
- @rule_memory = Nanoc::Int::RuleMemory.new(item_rep)
6
+ def initialize(rule_memory)
7
+ @rule_memory = rule_memory
20
8
  end
21
9
 
22
10
  def filter(filter_name, filter_args = {})
@@ -29,34 +17,18 @@ module Nanoc
29
17
  end
30
18
 
31
19
  unless @rule_memory.any_layouts?
32
- @rule_memory.add_snapshot(:pre, true, nil)
20
+ @rule_memory.add_snapshot(:pre, nil)
33
21
  end
34
22
 
35
23
  @rule_memory.add_layout(layout_identifier, extra_filter_args)
36
24
  end
37
25
 
38
26
  Pathlike = C::Maybe[C::Or[String, Nanoc::Identifier]]
39
- contract Symbol, C::KeywordArgs[path: C::Optional[Pathlike], final: C::Optional[C::Bool]] => nil
40
- def snapshot(snapshot_name, final: true, path: nil)
41
- pathlike = final ? (path || basic_path_from_rules_for(@item_rep, snapshot_name)) : nil
42
- actual_path = pathlike && pathlike.to_s
43
- @rule_memory.add_snapshot(snapshot_name, final, actual_path)
27
+ contract Symbol, C::KeywordArgs[path: C::Optional[Pathlike]] => nil
28
+ def snapshot(snapshot_name, path: nil)
29
+ @rule_memory.add_snapshot(snapshot_name, path && path.to_s)
44
30
  nil
45
31
  end
46
-
47
- def basic_path_from_rules_for(rep, snapshot_name)
48
- routing_rules = @rules_collection.routing_rules_for(rep)
49
- routing_rule = routing_rules[snapshot_name]
50
- return nil if routing_rule.nil?
51
-
52
- dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
53
- view_context = Nanoc::ViewContext.new(reps: nil, items: nil, dependency_tracker: dependency_tracker, compilation_context: nil)
54
- basic_path = routing_rule.apply_to(rep, executor: nil, site: @site, view_context: view_context)
55
- if basic_path && !basic_path.start_with?('/')
56
- raise PathWithoutInitialSlashError.new(rep, basic_path)
57
- end
58
- basic_path
59
- end
60
32
  end
61
33
  end
62
34
  end
@@ -24,6 +24,12 @@ module Nanoc::RuleDSL
24
24
  end
25
25
  end
26
26
 
27
+ class PathWithoutInitialSlashError < ::Nanoc::Error
28
+ def initialize(rep, basic_path)
29
+ super("The path returned for the #{rep.inspect} item representation, “#{basic_path}”, does not start with a slash. Please ensure that all routing rules return a path that starts with a slash.")
30
+ end
31
+ end
32
+
27
33
  # @api private
28
34
  attr_accessor :rules_collection
29
35
 
@@ -48,15 +54,9 @@ module Nanoc::RuleDSL
48
54
  end
49
55
  end
50
56
 
51
- # @param [Nanoc::Int::ItemRep] rep The item representation for which to fetch
52
- # the list of snapshots
53
- #
54
- # @return [Array] A list of snapshots, represented as arrays where the
55
- # first element is the snapshot name (a Symbol) and the last element is
56
- # a Boolean indicating whether the snapshot is final or not
57
57
  def snapshots_defs_for(rep)
58
58
  self[rep].snapshot_actions.map do |a|
59
- Nanoc::Int::SnapshotDef.new(a.snapshot_name, a.final?)
59
+ Nanoc::Int::SnapshotDef.new(a.snapshot_name)
60
60
  end
61
61
  end
62
62
 
@@ -68,7 +68,8 @@ module Nanoc::RuleDSL
68
68
  dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
69
69
  view_context = @site.compiler.compilation_context.create_view_context(dependency_tracker)
70
70
 
71
- executor = Nanoc::RuleDSL::RecordingExecutor.new(rep, @rules_collection, @site)
71
+ rule_memory = Nanoc::Int::RuleMemory.new(rep)
72
+ executor = Nanoc::RuleDSL::RecordingExecutor.new(rule_memory)
72
73
  rule = @rules_collection.compilation_rule_for(rep)
73
74
 
74
75
  unless rule
@@ -76,16 +77,15 @@ module Nanoc::RuleDSL
76
77
  end
77
78
 
78
79
  executor.snapshot(:raw)
79
- executor.snapshot(:pre, final: false)
80
80
  rule.apply_to(rep, executor: executor, site: @site, view_context: view_context)
81
- if executor.rule_memory.any_layouts?
81
+ if rule_memory.any_layouts?
82
82
  executor.snapshot(:post)
83
83
  end
84
- unless executor.rule_memory.snapshot_actions.any? { |sa| sa.snapshot_name == :last }
84
+ unless rule_memory.snapshot_actions.any? { |sa| sa.snapshot_name == :last }
85
85
  executor.snapshot(:last)
86
86
  end
87
87
 
88
- executor.rule_memory
88
+ assign_paths_to_mem(rule_memory, rep: rep)
89
89
  end
90
90
 
91
91
  # @param [Nanoc::Int::Layout] layout
@@ -102,5 +102,35 @@ module Nanoc::RuleDSL
102
102
  rm.add_filter(res[0], res[1])
103
103
  end
104
104
  end
105
+
106
+ def assign_paths_to_mem(mem, rep:)
107
+ mem.map do |action|
108
+ if action.is_a?(Nanoc::Int::ProcessingActions::Snapshot) && action.path.nil?
109
+ path_from_rules = basic_path_from_rules_for(rep, action.snapshot_name)
110
+ if path_from_rules
111
+ action.copy(path: path_from_rules.to_s)
112
+ else
113
+ action
114
+ end
115
+ else
116
+ action
117
+ end
118
+ end
119
+ end
120
+
121
+ # FIXME: ugly
122
+ def basic_path_from_rules_for(rep, snapshot_name)
123
+ routing_rules = @rules_collection.routing_rules_for(rep)
124
+ routing_rule = routing_rules[snapshot_name]
125
+ return nil if routing_rule.nil?
126
+
127
+ dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
128
+ view_context = Nanoc::ViewContext.new(reps: nil, items: nil, dependency_tracker: dependency_tracker, compilation_context: nil)
129
+ basic_path = routing_rule.apply_to(rep, executor: nil, site: @site, view_context: view_context)
130
+ if basic_path && !basic_path.start_with?('/')
131
+ raise PathWithoutInitialSlashError.new(rep, basic_path)
132
+ end
133
+ basic_path
134
+ end
105
135
  end
106
136
  end
data/lib/nanoc/spec.rb CHANGED
@@ -141,7 +141,7 @@ module Nanoc
141
141
  end
142
142
 
143
143
  def snapshots_defs_for(_rep)
144
- [Nanoc::Int::SnapshotDef.new(:last, false)]
144
+ [Nanoc::Int::SnapshotDef.new(:last)]
145
145
  end
146
146
  end.new(self)
147
147
  end
data/lib/nanoc/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Nanoc
2
2
  # The current Nanoc version.
3
- VERSION = '4.4.5'.freeze
3
+ VERSION = '4.4.6'.freeze
4
4
  end
data/nanoc.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.files =
15
15
  Dir['[A-Z]*'] +
16
16
  Dir['doc/yardoc_{templates,handlers}/**/*'] +
17
- Dir['{bin,lib,tasks,test}/**/*'] +
17
+ Dir['{bin,lib,tasks,test,spec}/**/*'] +
18
18
  ['nanoc.gemspec']
19
19
  s.executables = ['nanoc']
20
20
  s.require_paths = ['lib']
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency('cri', '~> 2.3')
28
28
  s.add_runtime_dependency('hamster', '~> 3.0')
29
29
  s.add_runtime_dependency('ref', '~> 2.0')
30
- s.add_runtime_dependency('parallel', '~> 1.9')
31
30
 
32
31
  s.add_development_dependency('bundler', '>= 1.7.10', '< 2.0')
33
32
  s.add_development_dependency('appraisal', '~> 2.1')
@@ -0,0 +1,18 @@
1
+ describe 'list of contributors in README', chdir: false do
2
+ let(:contributors_in_readme) do
3
+ File.readlines('README.md').last.chomp("\n").split(', ')
4
+ end
5
+
6
+ let(:contributors_in_release_notes) do
7
+ File.read('NEWS.md').scan(/\[[^\]]+\]$/).map { |s| s[1..-2].split(', ') }.flatten
8
+ end
9
+
10
+ it 'should include everyone mentioned in NEWS.md' do
11
+ diff = (contributors_in_release_notes - contributors_in_readme).uniq.sort
12
+ expect(diff).to be_empty, "some contributors are missing from the README: #{diff.join(', ')}"
13
+ end
14
+
15
+ it 'should be sorted' do
16
+ expect(contributors_in_readme).to be_humanly_sorted
17
+ end
18
+ end