nanoc 4.0.2 → 4.1.0a1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +17 -0
  3. data/Gemfile +50 -46
  4. data/Gemfile.lock +365 -0
  5. data/Guardfile +3 -0
  6. data/NEWS.md +21 -0
  7. data/README.md +1 -1
  8. data/lib/nanoc/base.rb +3 -15
  9. data/lib/nanoc/base/checksummer.rb +3 -14
  10. data/lib/nanoc/base/compilation/compiler.rb +112 -283
  11. data/lib/nanoc/base/compilation/compiler_dsl.rb +29 -37
  12. data/lib/nanoc/base/compilation/dependency_tracker.rb +25 -170
  13. data/lib/nanoc/base/compilation/filter.rb +3 -4
  14. data/lib/nanoc/base/compilation/item_rep_repo.rb +33 -0
  15. data/lib/nanoc/base/compilation/outdatedness_checker.rb +39 -53
  16. data/lib/nanoc/base/compilation/rule.rb +13 -24
  17. data/lib/nanoc/base/compilation/rule_context.rb +29 -15
  18. data/lib/nanoc/base/entities.rb +10 -0
  19. data/lib/nanoc/base/{source_data → entities}/code_snippet.rb +1 -4
  20. data/lib/nanoc/base/{source_data → entities}/configuration.rb +1 -1
  21. data/lib/nanoc/base/entities/content.rb +8 -9
  22. data/lib/nanoc/base/{identifiable_collection.rb → entities/identifiable_collection.rb} +0 -0
  23. data/lib/nanoc/base/entities/identifier.rb +11 -2
  24. data/lib/nanoc/base/{source_data → entities}/item.rb +0 -18
  25. data/lib/nanoc/base/{result_data → entities}/item_rep.rb +15 -13
  26. data/lib/nanoc/base/entities/rule_memory.rb +54 -0
  27. data/lib/nanoc/base/entities/rule_memory_action.rb +19 -0
  28. data/lib/nanoc/base/entities/rule_memory_actions.rb +3 -0
  29. data/lib/nanoc/base/entities/rule_memory_actions/filter.rb +22 -0
  30. data/lib/nanoc/base/entities/rule_memory_actions/layout.rb +22 -0
  31. data/lib/nanoc/base/entities/rule_memory_actions/snapshot.rb +26 -0
  32. data/lib/nanoc/base/entities/rules_collection.rb +120 -0
  33. data/lib/nanoc/base/{source_data → entities}/site.rb +11 -10
  34. data/lib/nanoc/base/repos.rb +2 -0
  35. data/lib/nanoc/base/repos/checksum_store.rb +3 -9
  36. data/lib/nanoc/base/repos/compiled_content_cache.rb +0 -5
  37. data/lib/nanoc/base/{source_data → repos}/data_source.rb +3 -6
  38. data/lib/nanoc/base/repos/dependency_store.rb +118 -0
  39. data/lib/nanoc/base/repos/rule_memory_store.rb +1 -5
  40. data/lib/nanoc/base/repos/site_loader.rb +0 -28
  41. data/lib/nanoc/base/repos/store.rb +0 -12
  42. data/lib/nanoc/base/services.rb +8 -0
  43. data/lib/nanoc/base/services/compiler_loader.rb +49 -0
  44. data/lib/nanoc/base/services/executor.rb +4 -4
  45. data/lib/nanoc/base/services/item_rep_builder.rb +30 -0
  46. data/lib/nanoc/base/services/item_rep_router.rb +55 -0
  47. data/lib/nanoc/base/services/item_rep_selector.rb +39 -0
  48. data/lib/nanoc/base/services/item_rep_writer.rb +2 -0
  49. data/lib/nanoc/base/services/postprocessor.rb +26 -0
  50. data/lib/nanoc/base/services/preprocessor.rb +26 -0
  51. data/lib/nanoc/base/services/recording_executor.rb +36 -22
  52. data/lib/nanoc/base/services/rule_memory_calculator.rb +84 -0
  53. data/lib/nanoc/base/services/rules_loader.rb +29 -0
  54. data/lib/nanoc/base/views.rb +6 -0
  55. data/lib/nanoc/base/views/config_view.rb +8 -2
  56. data/lib/nanoc/base/views/identifiable_collection_view.rb +5 -4
  57. data/lib/nanoc/base/views/item_rep_collection_view.rb +7 -6
  58. data/lib/nanoc/base/views/item_rep_view.rb +13 -12
  59. data/lib/nanoc/base/views/item_view.rb +18 -12
  60. data/lib/nanoc/base/views/layout_view.rb +1 -1
  61. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +2 -1
  62. data/lib/nanoc/base/views/mutable_identifiable_collection_view.rb +1 -1
  63. data/lib/nanoc/base/views/mutable_item_collection_view.rb +4 -7
  64. data/lib/nanoc/base/views/post_compile_item_collection_view.rb +8 -0
  65. data/lib/nanoc/base/views/post_compile_item_view.rb +7 -0
  66. data/lib/nanoc/base/views/site_view.rb +3 -2
  67. data/lib/nanoc/base/views/view.rb +12 -0
  68. data/lib/nanoc/base/views/view_context.rb +12 -0
  69. data/lib/nanoc/cli/commands/compile.rb +13 -15
  70. data/lib/nanoc/cli/commands/create-site.rb +15 -0
  71. data/lib/nanoc/cli/commands/prune.rb +1 -1
  72. data/lib/nanoc/cli/commands/shell.rb +3 -3
  73. data/lib/nanoc/cli/commands/show-data.rb +5 -5
  74. data/lib/nanoc/cli/commands/show-rules.rb +2 -1
  75. data/lib/nanoc/cli/error_handler.rb +28 -30
  76. data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +1 -1
  77. data/lib/nanoc/data_sources/filesystem.rb +1 -1
  78. data/lib/nanoc/extra/checking/check.rb +8 -7
  79. data/lib/nanoc/extra/checking/checks/external_links.rb +14 -1
  80. data/lib/nanoc/extra/checking/runner.rb +1 -1
  81. data/lib/nanoc/extra/deployer.rb +3 -3
  82. data/lib/nanoc/extra/piper.rb +5 -5
  83. data/lib/nanoc/extra/pruner.rb +8 -7
  84. data/lib/nanoc/filters/relativize_paths.rb +48 -32
  85. data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +0 -1
  86. data/lib/nanoc/helpers/blogging.rb +15 -7
  87. data/lib/nanoc/helpers/capturing.rb +56 -13
  88. data/lib/nanoc/helpers/link_to.rb +2 -2
  89. data/lib/nanoc/helpers/tagging.rb +5 -10
  90. data/lib/nanoc/helpers/text.rb +9 -11
  91. data/lib/nanoc/version.rb +1 -1
  92. data/nanoc-4.0.2.gem +0 -0
  93. data/tags +1175 -0
  94. data/test/base/test_compiler.rb +48 -98
  95. data/test/base/test_compiler_dsl.rb +113 -39
  96. data/test/base/test_dependency_tracker.rb +80 -79
  97. data/test/base/test_outdatedness_checker.rb +39 -26
  98. data/test/base/test_site.rb +0 -97
  99. data/test/cli/commands/test_compile.rb +2 -3
  100. data/test/extra/checking/checks/test_external_links.rb +25 -0
  101. data/test/extra/deployers/test_fog.rb +12 -6
  102. data/test/filters/test_erb.rb +1 -1
  103. data/test/filters/test_erubis.rb +1 -1
  104. data/test/filters/test_haml.rb +1 -1
  105. data/test/filters/test_less.rb +4 -4
  106. data/test/filters/test_sass.rb +1 -0
  107. data/test/filters/test_xsl.rb +7 -8
  108. data/test/helper.rb +0 -2
  109. data/test/helpers/test_blogging.rb +26 -23
  110. data/test/helpers/test_capturing.rb +131 -12
  111. data/test/helpers/test_filtering.rb +6 -6
  112. data/test/helpers/test_link_to.rb +1 -1
  113. data/test/helpers/test_rendering.rb +16 -24
  114. data/test/helpers/test_tagging.rb +13 -10
  115. data/test/helpers/test_xml_sitemap.rb +25 -21
  116. metadata +36 -14
  117. data/lib/nanoc/base/compilation/rule_memory_calculator.rb +0 -35
  118. data/lib/nanoc/base/compilation/rules_collection.rb +0 -245
  119. data/test/base/test_rule_context.rb +0 -78
@@ -1,5 +1,13 @@
1
+ require_relative 'services/compiler_loader'
1
2
  require_relative 'services/executor'
3
+ require_relative 'services/item_rep_builder'
4
+ require_relative 'services/item_rep_router'
5
+ require_relative 'services/item_rep_selector'
2
6
  require_relative 'services/item_rep_writer'
3
7
  require_relative 'services/notification_center'
8
+ require_relative 'services/preprocessor'
9
+ require_relative 'services/postprocessor'
4
10
  require_relative 'services/recording_executor'
11
+ require_relative 'services/rule_memory_calculator'
12
+ require_relative 'services/rules_loader'
5
13
  require_relative 'services/temp_filename_factory'
@@ -0,0 +1,49 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class CompilerLoader
4
+ def load(site)
5
+ rules_collection = Nanoc::Int::RulesCollection.new
6
+
7
+ rule_memory_store = Nanoc::Int::RuleMemoryStore.new
8
+
9
+ rule_memory_calculator =
10
+ Nanoc::Int::RuleMemoryCalculator.new(
11
+ rules_collection: rules_collection, site: site)
12
+
13
+ dependency_store =
14
+ Nanoc::Int::DependencyStore.new(site.items.to_a + site.layouts.to_a)
15
+
16
+ checksum_store =
17
+ Nanoc::Int::ChecksumStore.new(site: site)
18
+
19
+ item_rep_repo = Nanoc::Int::ItemRepRepo.new
20
+
21
+ outdatedness_checker =
22
+ Nanoc::Int::OutdatednessChecker.new(
23
+ site: site,
24
+ checksum_store: checksum_store,
25
+ dependency_store: dependency_store,
26
+ rules_collection: rules_collection,
27
+ rule_memory_store: rule_memory_store,
28
+ rule_memory_calculator: rule_memory_calculator,
29
+ reps: item_rep_repo,
30
+ )
31
+
32
+ params = {
33
+ compiled_content_cache: Nanoc::Int::CompiledContentCache.new,
34
+ checksum_store: checksum_store,
35
+ rule_memory_store: rule_memory_store,
36
+ rule_memory_calculator: rule_memory_calculator,
37
+ dependency_store: dependency_store,
38
+ outdatedness_checker: outdatedness_checker,
39
+ reps: item_rep_repo,
40
+ }
41
+
42
+ compiler = Nanoc::Int::Compiler.new(site, rules_collection, params)
43
+
44
+ Nanoc::Int::RulesLoader.new(site.config, rules_collection).load
45
+
46
+ compiler
47
+ end
48
+ end
49
+ end
@@ -98,18 +98,18 @@ module Nanoc
98
98
  end
99
99
  end
100
100
 
101
- def snapshot(rep, snapshot_name, params = {})
102
- is_final = params.fetch(:final, true)
101
+ def snapshot(rep, snapshot_name, final: true, path: nil) # rubocop:disable Lint/UnusedMethodArgument
102
+ # NOTE: :path is irrelevant
103
103
 
104
104
  unless rep.binary?
105
105
  rep.snapshot_contents[snapshot_name] = rep.snapshot_contents[:last]
106
106
  end
107
107
 
108
- if snapshot_name == :pre && is_final
108
+ if snapshot_name == :pre && final
109
109
  rep.snapshot_defs << Nanoc::Int::SnapshotDef.new(:pre, true)
110
110
  end
111
111
 
112
- if is_final
112
+ if final
113
113
  raw_path = rep.raw_path(snapshot: snapshot_name)
114
114
  if raw_path
115
115
  ItemRepWriter.new.write(rep, raw_path)
@@ -0,0 +1,30 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class ItemRepBuilder
4
+ attr_reader :reps
5
+
6
+ def initialize(site, rules_collection, rule_memory_calculator, reps)
7
+ @site = site
8
+ @rules_collection = rules_collection
9
+ @rule_memory_calculator = rule_memory_calculator
10
+ @reps = reps
11
+ end
12
+
13
+ def run
14
+ @site.items.each do |item|
15
+ rep_names_for(item).each do |rep_name|
16
+ @reps << Nanoc::Int::ItemRep.new(item, rep_name)
17
+ end
18
+ end
19
+
20
+ Nanoc::Int::ItemRepRouter.new(@reps, @rule_memory_calculator, @site).run
21
+ end
22
+
23
+ def rep_names_for(item)
24
+ matching_rules = @rules_collection.item_compilation_rules_for(item)
25
+ raise Nanoc::Int::Errors::NoMatchingCompilationRuleFound.new(item) if matching_rules.empty?
26
+
27
+ matching_rules.map(&:rep_name).uniq
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ module Nanoc::Int
2
+ # Assigns paths to reps.
3
+ #
4
+ # @api private
5
+ class ItemRepRouter
6
+ class IdenticalRoutesError < ::Nanoc::Error
7
+ def initialize(output_path, rep_a, rep_b)
8
+ super("The item representations #{rep_a.inspect} and #{rep_b.inspect} are both routed to #{output_path}.")
9
+ end
10
+ end
11
+
12
+ # TODO: Replace rule_memory_calculator with { rep => rule_memory }
13
+ def initialize(reps, rule_memory_calculator, site)
14
+ @reps = reps
15
+ @rule_memory_calculator = rule_memory_calculator
16
+ @site = site
17
+ end
18
+
19
+ def run
20
+ paths_to_reps = {}
21
+ @reps.each do |rep|
22
+ mem = @rule_memory_calculator[rep]
23
+ mem.snapshot_actions.each do |snapshot_action|
24
+ route_rep(rep, snapshot_action, paths_to_reps)
25
+ end
26
+ end
27
+ end
28
+
29
+ def route_rep(rep, snapshot_action, paths_to_reps)
30
+ basic_path = snapshot_action.path
31
+ return if basic_path.nil?
32
+
33
+ # Check for duplicate paths
34
+ if paths_to_reps.key?(basic_path)
35
+ raise IdenticalRoutesError.new(basic_path, paths_to_reps[basic_path], rep)
36
+ else
37
+ paths_to_reps[basic_path] = rep
38
+ end
39
+
40
+ rep.raw_paths[snapshot_action.snapshot_name] = @site.config[:output_dir] + basic_path
41
+ rep.paths[snapshot_action.snapshot_name] = strip_index_filename(basic_path)
42
+ end
43
+
44
+ def strip_index_filename(basic_path)
45
+ @site.config[:index_filenames].each do |index_filename|
46
+ rep_path_ending = basic_path[-index_filename.length..-1]
47
+ next unless rep_path_ending == index_filename
48
+
49
+ return basic_path[0..-index_filename.length - 1]
50
+ end
51
+
52
+ basic_path
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,39 @@
1
+ module Nanoc::Int
2
+ # Yields item reps to compile.
3
+ #
4
+ # @api private
5
+ class ItemRepSelector
6
+ def initialize(reps)
7
+ @reps = reps
8
+ end
9
+
10
+ def each
11
+ graph = Nanoc::Int::DirectedGraph.new(@reps)
12
+
13
+ loop do
14
+ break if graph.roots.empty?
15
+ rep = graph.roots.each { |e| break e }
16
+
17
+ begin
18
+ yield(rep)
19
+ graph.delete_vertex(rep)
20
+ rescue Nanoc::Int::Errors::UnmetDependency => e
21
+ handle_dependency_error(e, rep, graph)
22
+ end
23
+ end
24
+
25
+ # Check whether everything was compiled
26
+ unless graph.vertices.empty?
27
+ raise Nanoc::Int::Errors::RecursiveCompilation.new(graph.vertices)
28
+ end
29
+ end
30
+
31
+ def handle_dependency_error(e, rep, graph)
32
+ other_rep = e.rep
33
+ graph.add_edge(other_rep, rep)
34
+ unless graph.vertices.include?(other_rep)
35
+ graph.add_vertex(other_rep)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -28,6 +28,8 @@ module Nanoc::Int
28
28
  # Write
29
29
  FileUtils.cp(temp_path, raw_path) if is_modified
30
30
 
31
+ item_rep.modified = is_modified
32
+
31
33
  # Notify
32
34
  Nanoc::Int::NotificationCenter.post(
33
35
  :rep_written, item_rep, raw_path, is_created, is_modified)
@@ -0,0 +1,26 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class Postprocessor
4
+ def initialize(context, site:, rules_collection:)
5
+ @context = context
6
+ @site = site
7
+ @rules_collection = rules_collection
8
+ end
9
+
10
+ def run
11
+ ctx = new_postprocessor_context
12
+
13
+ @rules_collection.postprocessors.each_value do |postprocessor|
14
+ ctx.instance_eval(&postprocessor)
15
+ end
16
+ end
17
+
18
+ # @api private
19
+ def new_postprocessor_context
20
+ Nanoc::Int::Context.new(
21
+ config: Nanoc::ConfigView.new(@site.config, @context),
22
+ items: Nanoc::PostCompileItemCollectionView.new(@site.items, @context),
23
+ )
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class Preprocessor
4
+ def initialize(site:, rules_collection:)
5
+ @site = site
6
+ @rules_collection = rules_collection
7
+ end
8
+
9
+ def run
10
+ ctx = new_preprocessor_context
11
+
12
+ @rules_collection.preprocessors.each_value do |preprocessor|
13
+ ctx.instance_eval(&preprocessor)
14
+ end
15
+ end
16
+
17
+ # @api private
18
+ def new_preprocessor_context
19
+ Nanoc::Int::Context.new(
20
+ config: Nanoc::MutableConfigView.new(@site.config, nil),
21
+ items: Nanoc::MutableItemCollectionView.new(@site.items, nil),
22
+ layouts: Nanoc::MutableLayoutCollectionView.new(@site.layouts, nil),
23
+ )
24
+ end
25
+ end
26
+ end
@@ -1,40 +1,54 @@
1
1
  module Nanoc
2
2
  module Int
3
3
  class RecordingExecutor
4
+ class NonFinalSnapshotWithPathError < ::Nanoc::Error
5
+ def initialize
6
+ super('This call to #snapshot specifies `final: false`, but it also specifies a path, which is an impossible combination.')
7
+ end
8
+ end
9
+
10
+ class PathWithoutInitialSlashError < ::Nanoc::Error
11
+ def initialize(rep, basic_path)
12
+ 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.")
13
+ end
14
+ end
15
+
4
16
  attr_reader :rule_memory
5
17
 
6
- def initialize
7
- @rule_memory = []
18
+ def initialize(item_rep, rules_collection, site)
19
+ @item_rep = item_rep
20
+ @rules_collection = rules_collection
21
+ @site = site
22
+
23
+ @rule_memory = Nanoc::Int::RuleMemory.new(item_rep)
8
24
  end
9
25
 
10
26
  def filter(_rep, filter_name, filter_args = {})
11
- @rule_memory << [:filter, filter_name, filter_args]
27
+ @rule_memory.add_filter(filter_name, filter_args)
12
28
  end
13
29
 
14
- def layout(_rep, layout_identifier, extra_filter_args = nil)
15
- if extra_filter_args
16
- @rule_memory << [:layout, layout_identifier, extra_filter_args]
17
- else
18
- @rule_memory << [:layout, layout_identifier]
19
- end
30
+ def layout(_rep, layout_identifier, extra_filter_args = {})
31
+ @rule_memory.add_layout(layout_identifier, extra_filter_args)
20
32
  end
21
33
 
22
- def snapshot(_rep, snapshot_name, params = {})
23
- @rule_memory << [:snapshot, snapshot_name, params]
24
-
25
- # Count
26
- existing = Set.new
27
- names = @rule_memory.select { |r| r[0] == :snapshot }.map { |r| r[1] }
28
- names.each do |n|
29
- if existing.include?(n)
30
- raise Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName.new(@item_rep, snapshot_name)
31
- end
32
- existing << n
34
+ def snapshot(rep, snapshot_name, final: true, path: nil)
35
+ actual_path = path || basic_path_from_rules_for(rep, snapshot_name)
36
+ if !final && actual_path
37
+ raise NonFinalSnapshotWithPathError
33
38
  end
39
+ @rule_memory.add_snapshot(snapshot_name, final, actual_path)
34
40
  end
35
41
 
36
- def record_write(_rep, path)
37
- @rule_memory << [:write, path]
42
+ def basic_path_from_rules_for(rep, snapshot_name)
43
+ routing_rules = @rules_collection.routing_rules_for(rep)
44
+ routing_rule = routing_rules[snapshot_name]
45
+ return nil if routing_rule.nil?
46
+
47
+ basic_path = routing_rule.apply_to(rep, executor: nil, site: @site, view_context: nil)
48
+ if basic_path && !basic_path.start_with?('/')
49
+ raise PathWithoutInitialSlashError.new(rep, basic_path)
50
+ end
51
+ basic_path
38
52
  end
39
53
  end
40
54
  end
@@ -0,0 +1,84 @@
1
+ module Nanoc::Int
2
+ # Calculates rule memories for objects that can be run through a rule (item
3
+ # representations and layouts).
4
+ #
5
+ # @api private
6
+ class RuleMemoryCalculator
7
+ extend Nanoc::Int::Memoization
8
+
9
+ class UnsupportedObjectTypeException < ::Nanoc::Error
10
+ def initialize(obj)
11
+ super("Do not know how to calculate the rule memory for #{obj.inspect}")
12
+ end
13
+ end
14
+
15
+ # @api private
16
+ attr_accessor :rules_collection
17
+
18
+ # @param [Nanoc::Int::Site] site
19
+ # @param [Nanoc::Int::RulesCollection] rules_collection
20
+ def initialize(site:, rules_collection:)
21
+ @site = site
22
+ @rules_collection = rules_collection
23
+ end
24
+
25
+ # @param [#reference] obj
26
+ #
27
+ # @return [Nanoc::Int::RuleMemory]
28
+ def [](obj)
29
+ case obj
30
+ when Nanoc::Int::ItemRep
31
+ new_rule_memory_for_rep(obj)
32
+ when Nanoc::Int::Layout
33
+ new_rule_memory_for_layout(obj)
34
+ else
35
+ raise UnsupportedObjectTypeException.new(obj)
36
+ end
37
+ end
38
+ memoize :[]
39
+
40
+ # @param [Nanoc::Int::ItemRep] rep The item representation for which to fetch
41
+ # the list of snapshots
42
+ #
43
+ # @return [Array] A list of snapshots, represented as arrays where the
44
+ # first element is the snapshot name (a Symbol) and the last element is
45
+ # a Boolean indicating whether the snapshot is final or not
46
+ def snapshots_defs_for(rep)
47
+ self[rep].snapshot_actions.map do |a|
48
+ Nanoc::Int::SnapshotDef.new(a.snapshot_name, a.final?)
49
+ end
50
+ end
51
+
52
+ # @param [Nanoc::Int::ItemRep] rep The item representation to get the rule
53
+ # memory for
54
+ #
55
+ # @return [Nanoc::Int::RuleMemory]
56
+ def new_rule_memory_for_rep(rep)
57
+ # FIXME: This is more-or-less duplicated from Compiler#recalculate_content_for_rep.
58
+ # Letting the compiler use the rule memory would fix this.
59
+
60
+ # FIXME: What if #compilation_rule_for returns nil?
61
+
62
+ executor = Nanoc::Int::RecordingExecutor.new(rep, @rules_collection, @site)
63
+ executor.snapshot(rep, :raw)
64
+ executor.snapshot(rep, :pre, final: false)
65
+ @rules_collection
66
+ .compilation_rule_for(rep)
67
+ .apply_to(rep, executor: executor, site: @site, view_context: nil)
68
+ executor.snapshot(rep, :post) if rep.has_snapshot?(:post)
69
+ executor.snapshot(rep, :last) unless executor.rule_memory.snapshot_actions.any? { |sa| sa.snapshot_name == :last }
70
+ executor.rule_memory
71
+ end
72
+
73
+ # @param [Nanoc::Int::Layout]
74
+ #
75
+ # @return [Nanoc::Int::RuleMemory]
76
+ def new_rule_memory_for_layout(layout)
77
+ res = @rules_collection.filter_for_layout(layout)
78
+ # FIXME: what if res is nil?
79
+ Nanoc::Int::RuleMemory.new(layout).tap do |rm|
80
+ rm.add_filter(res[0], res[1])
81
+ end
82
+ end
83
+ end
84
+ end