nanoc 4.4.5 → 4.4.6

Sign up to get free protection for your applications and to get access to all the features.
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