nanoc 4.11.0 → 4.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +6 -0
  3. data/lib/nanoc.rb +4 -7
  4. data/lib/nanoc/base.rb +3 -3
  5. data/lib/nanoc/base/assertions.rb +1 -1
  6. data/lib/nanoc/base/entities.rb +2 -20
  7. data/lib/nanoc/base/entities/action_sequence.rb +60 -64
  8. data/lib/nanoc/base/entities/checksum_collection.rb +23 -21
  9. data/lib/nanoc/base/entities/dependency.rb +24 -22
  10. data/lib/nanoc/base/entities/outdatedness_reasons.rb +74 -72
  11. data/lib/nanoc/base/entities/outdatedness_status.rb +19 -17
  12. data/lib/nanoc/base/entities/props.rb +119 -117
  13. data/lib/nanoc/base/entities/site.rb +46 -50
  14. data/lib/nanoc/base/errors.rb +183 -198
  15. data/lib/nanoc/base/repos.rb +4 -2
  16. data/lib/nanoc/base/repos/action_sequence_store.rb +44 -42
  17. data/lib/nanoc/base/repos/aggregate_data_source.rb +24 -22
  18. data/lib/nanoc/base/repos/checksum_store.rb +51 -49
  19. data/lib/nanoc/base/repos/compiled_content_cache.rb +47 -45
  20. data/lib/nanoc/base/repos/compiled_content_store.rb +76 -0
  21. data/lib/nanoc/base/repos/config_loader.rb +74 -72
  22. data/lib/nanoc/base/repos/dependency_store.rb +174 -172
  23. data/lib/nanoc/base/repos/in_mem_data_source.rb +17 -15
  24. data/lib/nanoc/base/repos/item_rep_repo.rb +26 -24
  25. data/lib/nanoc/base/repos/outdatedness_store.rb +50 -48
  26. data/lib/nanoc/base/repos/prefixed_data_source.rb +21 -19
  27. data/lib/nanoc/base/repos/site_loader.rb +75 -73
  28. data/lib/nanoc/base/repos/store.rb +93 -91
  29. data/lib/nanoc/base/services.rb +7 -3
  30. data/lib/nanoc/base/services/action_provider.rb +23 -21
  31. data/lib/nanoc/base/services/action_sequence_builder.rb +42 -34
  32. data/lib/nanoc/base/services/compilation_context.rb +49 -47
  33. data/lib/nanoc/base/services/compiler.rb +177 -170
  34. data/lib/nanoc/base/services/compiler/phases.rb +8 -1
  35. data/lib/nanoc/base/services/compiler/phases/abstract.rb +44 -38
  36. data/lib/nanoc/base/services/compiler/phases/cache.rb +34 -28
  37. data/lib/nanoc/base/services/compiler/phases/mark_done.rb +17 -11
  38. data/lib/nanoc/base/services/compiler/phases/notify.rb +21 -0
  39. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +37 -31
  40. data/lib/nanoc/base/services/compiler/phases/resume.rb +47 -48
  41. data/lib/nanoc/base/services/compiler/phases/write.rb +65 -59
  42. data/lib/nanoc/base/services/compiler/stage.rb +27 -8
  43. data/lib/nanoc/base/services/compiler/stages.rb +7 -1
  44. data/lib/nanoc/base/services/compiler/stages/build_reps.rb +25 -19
  45. data/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb +34 -28
  46. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +33 -27
  47. data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +79 -69
  48. data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +46 -40
  49. data/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb +15 -9
  50. data/lib/nanoc/base/services/compiler/stages/load_stores.rb +28 -22
  51. data/lib/nanoc/base/services/compiler/stages/postprocess.rb +16 -10
  52. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +25 -19
  53. data/lib/nanoc/base/services/compiler/stages/prune.rb +23 -17
  54. data/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb +15 -9
  55. data/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb +26 -20
  56. data/lib/nanoc/base/services/compiler_loader.rb +26 -24
  57. data/lib/nanoc/base/services/dependency_tracker.rb +47 -45
  58. data/lib/nanoc/base/services/executor.rb +16 -15
  59. data/lib/nanoc/base/services/filter.rb +37 -5
  60. data/lib/nanoc/base/services/instrumentor.rb +12 -10
  61. data/lib/nanoc/base/services/item_rep_builder.rb +21 -19
  62. data/lib/nanoc/base/services/item_rep_router.rb +72 -70
  63. data/lib/nanoc/base/services/item_rep_selector.rb +48 -46
  64. data/lib/nanoc/base/services/item_rep_writer.rb +58 -53
  65. data/lib/nanoc/base/services/outdatedness_checker.rb +181 -179
  66. data/lib/nanoc/base/services/outdatedness_rule.rb +23 -21
  67. data/lib/nanoc/base/services/outdatedness_rules.rb +5 -3
  68. data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +28 -24
  69. data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +20 -16
  70. data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +13 -9
  71. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +12 -8
  72. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +12 -8
  73. data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +10 -6
  74. data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +39 -35
  75. data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +19 -15
  76. data/lib/nanoc/base/services/pruner.rb +2 -2
  77. data/lib/nanoc/base/views.rb +7 -0
  78. data/lib/nanoc/base/views/basic_item_view.rb +1 -1
  79. data/lib/nanoc/base/views/compilation_item_rep_view.rb +2 -2
  80. data/lib/nanoc/base/views/identifiable_collection_view.rb +2 -2
  81. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +1 -1
  82. data/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb +5 -5
  83. data/lib/nanoc/base/views/mutable_item_collection_view.rb +3 -3
  84. data/lib/nanoc/base/views/mutable_layout_collection_view.rb +2 -2
  85. data/lib/nanoc/base/views/view_context_for_compilation.rb +6 -6
  86. data/lib/nanoc/base/views/view_context_for_pre_compilation.rb +2 -2
  87. data/lib/nanoc/base/views/view_context_for_shell.rb +2 -2
  88. data/lib/nanoc/checking/check.rb +1 -1
  89. data/lib/nanoc/cli/commands/compile_listeners/abstract.rb +24 -7
  90. data/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb +79 -15
  91. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +4 -7
  92. data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +15 -24
  93. data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +22 -18
  94. data/lib/nanoc/cli/commands/create-site.rb +2 -7
  95. data/lib/nanoc/cli/commands/shell.rb +1 -1
  96. data/lib/nanoc/cli/commands/show-data.rb +9 -9
  97. data/lib/nanoc/cli/logger.rb +1 -1
  98. data/lib/nanoc/data_sources/filesystem.rb +8 -8
  99. data/lib/nanoc/filters/erb.rb +1 -1
  100. data/lib/nanoc/filters/erubi.rb +1 -1
  101. data/lib/nanoc/filters/erubis.rb +1 -1
  102. data/lib/nanoc/filters/haml.rb +1 -1
  103. data/lib/nanoc/filters/sass.rb +1 -1
  104. data/lib/nanoc/filters/slim.rb +1 -1
  105. data/lib/nanoc/helpers/breadcrumbs.rb +2 -2
  106. data/lib/nanoc/helpers/capturing.rb +9 -8
  107. data/lib/nanoc/helpers/filtering.rb +2 -2
  108. data/lib/nanoc/helpers/rendering.rb +1 -1
  109. data/lib/nanoc/rule_dsl.rb +10 -0
  110. data/lib/nanoc/rule_dsl/action_provider.rb +3 -3
  111. data/lib/nanoc/rule_dsl/action_recorder.rb +3 -3
  112. data/lib/nanoc/rule_dsl/action_sequence_calculator.rb +7 -7
  113. data/lib/nanoc/rule_dsl/compilation_rule.rb +2 -2
  114. data/lib/nanoc/rule_dsl/compilation_rule_context.rb +9 -9
  115. data/lib/nanoc/rule_dsl/compiler_dsl.rb +4 -4
  116. data/lib/nanoc/rule_dsl/routing_rule.rb +3 -3
  117. data/lib/nanoc/rule_dsl/rule.rb +5 -5
  118. data/lib/nanoc/rule_dsl/rule_context.rb +3 -3
  119. data/lib/nanoc/rule_dsl/rules_collection.rb +4 -4
  120. data/lib/nanoc/spec.rb +15 -15
  121. data/lib/nanoc/version.rb +1 -1
  122. metadata +10 -111
  123. data/lib/nanoc/base/contracts_support.rb +0 -130
  124. data/lib/nanoc/base/core_ext.rb +0 -5
  125. data/lib/nanoc/base/core_ext/array.rb +0 -50
  126. data/lib/nanoc/base/core_ext/hash.rb +0 -54
  127. data/lib/nanoc/base/core_ext/string.rb +0 -16
  128. data/lib/nanoc/base/entities/code_snippet.rb +0 -53
  129. data/lib/nanoc/base/entities/configuration-schema.json +0 -122
  130. data/lib/nanoc/base/entities/configuration.rb +0 -206
  131. data/lib/nanoc/base/entities/content.rb +0 -112
  132. data/lib/nanoc/base/entities/context.rb +0 -70
  133. data/lib/nanoc/base/entities/directed_graph.rb +0 -195
  134. data/lib/nanoc/base/entities/document.rb +0 -125
  135. data/lib/nanoc/base/entities/identifiable_collection.rb +0 -141
  136. data/lib/nanoc/base/entities/identifier.rb +0 -222
  137. data/lib/nanoc/base/entities/item.rb +0 -10
  138. data/lib/nanoc/base/entities/item_collection.rb +0 -14
  139. data/lib/nanoc/base/entities/item_rep.rb +0 -91
  140. data/lib/nanoc/base/entities/layout.rb +0 -10
  141. data/lib/nanoc/base/entities/layout_collection.rb +0 -14
  142. data/lib/nanoc/base/entities/lazy_value.rb +0 -43
  143. data/lib/nanoc/base/entities/pattern.rb +0 -85
  144. data/lib/nanoc/base/entities/processing_action.rb +0 -21
  145. data/lib/nanoc/base/entities/processing_actions.rb +0 -5
  146. data/lib/nanoc/base/entities/processing_actions/filter.rb +0 -36
  147. data/lib/nanoc/base/entities/processing_actions/layout.rb +0 -36
  148. data/lib/nanoc/base/entities/processing_actions/snapshot.rb +0 -46
  149. data/lib/nanoc/base/entities/snapshot_def.rb +0 -22
  150. data/lib/nanoc/base/repos/data_source.rb +0 -168
  151. data/lib/nanoc/base/repos/snapshot_repo.rb +0 -67
  152. data/lib/nanoc/base/services/checksummer.rb +0 -274
  153. data/lib/nanoc/base/services/notification_center.rb +0 -87
  154. data/lib/nanoc/base/services/temp_filename_factory.rb +0 -52
@@ -13,24 +13,24 @@ module Nanoc
13
13
  filter = filter_for_filtering(@rep, filter_name)
14
14
 
15
15
  begin
16
- Nanoc::Int::NotificationCenter.post(:filtering_started, @rep, filter_name)
16
+ Nanoc::Core::NotificationCenter.post(:filtering_started, @rep, filter_name)
17
17
 
18
18
  # Run filter
19
- last = @compilation_context.snapshot_repo.get(@rep, :last)
19
+ last = @compilation_context.compiled_content_store.get_current(@rep)
20
20
  source = last.binary? ? last.filename : last.string
21
21
  filter_args.freeze
22
22
  result = filter.setup_and_run(source, filter_args)
23
23
  last =
24
24
  if filter.class.to_binary?
25
- Nanoc::Int::BinaryContent.new(filter.output_filename).tap(&:freeze)
25
+ Nanoc::Core::BinaryContent.new(filter.output_filename).tap(&:freeze)
26
26
  else
27
- Nanoc::Int::TextualContent.new(result).tap(&:freeze)
27
+ Nanoc::Core::TextualContent.new(result).tap(&:freeze)
28
28
  end
29
29
 
30
30
  # Store
31
- @compilation_context.snapshot_repo.set(@rep, :last, last)
31
+ @compilation_context.compiled_content_store.set_current(@rep, last)
32
32
  ensure
33
- Nanoc::Int::NotificationCenter.post(:filtering_ended, @rep, filter_name)
33
+ Nanoc::Core::NotificationCenter.post(:filtering_ended, @rep, filter_name)
34
34
  end
35
35
  end
36
36
 
@@ -45,7 +45,7 @@ module Nanoc
45
45
  filter_args.freeze
46
46
 
47
47
  # Check whether item can be laid out
48
- last = @compilation_context.snapshot_repo.get(@rep, :last)
48
+ last = @compilation_context.compiled_content_store.get_current(@rep)
49
49
  raise Nanoc::Int::Errors::CannotLayoutBinaryItem.new(@rep) if last.binary?
50
50
 
51
51
  # Create filter
@@ -58,7 +58,7 @@ module Nanoc
58
58
  @dependency_tracker.bounce(layout, raw_content: true)
59
59
 
60
60
  begin
61
- Nanoc::Int::NotificationCenter.post(:filtering_started, @rep, filter_name)
61
+ Nanoc::Core::NotificationCenter.post(:filtering_started, @rep, filter_name)
62
62
 
63
63
  # Layout
64
64
  content = layout.content
@@ -66,16 +66,17 @@ module Nanoc
66
66
  res = filter.setup_and_run(arg, filter_args)
67
67
 
68
68
  # Store
69
- last = Nanoc::Int::TextualContent.new(res).tap(&:freeze)
70
- @compilation_context.snapshot_repo.set(@rep, :last, last)
69
+ last = Nanoc::Core::TextualContent.new(res).tap(&:freeze)
70
+ @compilation_context.compiled_content_store.set_current(@rep, last)
71
71
  ensure
72
- Nanoc::Int::NotificationCenter.post(:filtering_ended, @rep, filter_name)
72
+ Nanoc::Core::NotificationCenter.post(:filtering_ended, @rep, filter_name)
73
73
  end
74
74
  end
75
75
 
76
76
  def snapshot(snapshot_name)
77
- last = @compilation_context.snapshot_repo.get(@rep, :last)
78
- @compilation_context.snapshot_repo.set(@rep, snapshot_name, last)
77
+ last = @compilation_context.compiled_content_store.get_current(@rep)
78
+ @compilation_context.compiled_content_store.set(@rep, snapshot_name, last)
79
+ Nanoc::Core::NotificationCenter.post(:snapshot_created, @rep, snapshot_name)
79
80
  end
80
81
 
81
82
  def assigns_for(rep)
@@ -92,7 +93,7 @@ module Nanoc
92
93
  return layout if layout
93
94
 
94
95
  if use_globs?
95
- pat = Nanoc::Int::Pattern.from(arg)
96
+ pat = Nanoc::Core::Pattern.from(arg)
96
97
  layout = layouts.find { |l| pat.match?(l.identifier) }
97
98
  return layout if layout
98
99
  end
@@ -103,7 +104,7 @@ module Nanoc
103
104
  def filter_for_filtering(rep, filter_name)
104
105
  klass = Nanoc::Filter.named!(filter_name)
105
106
 
106
- last = @compilation_context.snapshot_repo.get(@rep, :last)
107
+ last = @compilation_context.compiled_content_store.get_current(@rep)
107
108
  if klass.from_binary? && !last.binary?
108
109
  raise Nanoc::Int::Errors::CannotUseBinaryFilter.new(rep, klass)
109
110
  elsif !klass.from_binary? && last.binary?
@@ -25,12 +25,41 @@ module Nanoc
25
25
  # # => 'bar'
26
26
  #
27
27
  # @abstract Subclass and override {#run} to implement a custom filter.
28
- class Filter < Nanoc::Int::Context
28
+ class Filter < Nanoc::Core::Context
29
29
  # @api private
30
30
  TMP_BINARY_ITEMS_DIR = 'binary_items'
31
31
 
32
32
  extend DDPlugin::Plugin
33
33
 
34
+ include Nanoc::Core::ContractsSupport
35
+
36
+ class UnknownFilterError < Nanoc::Core::Error
37
+ include Nanoc::Core::ContractsSupport
38
+
39
+ contract C::Or[String, Symbol] => self
40
+ def initialize(filter_name)
41
+ super("The requested filter, “#{filter_name}”, does not exist.")
42
+ end
43
+ end
44
+
45
+ class OutputNotWrittenError < Nanoc::Core::Error
46
+ include Nanoc::Core::ContractsSupport
47
+
48
+ contract C::Or[String, Symbol], String => self
49
+ def initialize(filter_name, output_filename)
50
+ super("The #{filter_name.inspect} filter did not write anything to the required output file, #{output_filename}.")
51
+ end
52
+ end
53
+
54
+ class FilterReturnedNilError < Nanoc::Core::Error
55
+ include Nanoc::Core::ContractsSupport
56
+
57
+ contract C::Or[String, Symbol] => self
58
+ def initialize(filter_name)
59
+ super("The #{filter_name.inspect} filter returned nil, but is required to return a String.")
60
+ end
61
+ end
62
+
34
63
  class << self
35
64
  def define(ident, &block)
36
65
  filter_class = Class.new(::Nanoc::Filter) { identifier(ident) }
@@ -41,7 +70,7 @@ module Nanoc
41
70
 
42
71
  def named!(name)
43
72
  klass = named(name)
44
- raise Nanoc::Int::Errors::UnknownFilter.new(name) if klass.nil?
73
+ raise UnknownFilterError.new(name) if klass.nil?
45
74
 
46
75
  klass
47
76
  end
@@ -179,15 +208,16 @@ module Nanoc
179
208
  def verify(res)
180
209
  if self.class.to_binary?
181
210
  unless File.file?(output_filename)
182
- raise Nanoc::Int::Errors::OutputNotWritten.new(self.class.identifier, output_filename)
211
+ raise Nanoc::Filter::OutputNotWrittenError.new(self.class.identifier, output_filename)
183
212
  end
184
213
  elsif self.class.to_text?
185
214
  unless res
186
- raise Nanoc::Int::Errors::FilterReturnedNil.new(self.class.identifier)
215
+ raise Nanoc::Filter::FilterReturnedNilError.new(self.class.identifier)
187
216
  end
188
217
  end
189
218
  end
190
219
 
220
+ contract C::None => String
191
221
  # Returns a filename that is used to write data to. This method is only
192
222
  # used on binary items. When running a binary filter on a file, the
193
223
  # resulting file must end up in the location returned by this method.
@@ -198,9 +228,10 @@ module Nanoc
198
228
  # @return [String] The output filename
199
229
  def output_filename
200
230
  @output_filename ||=
201
- Nanoc::Int::TempFilenameFactory.instance.create(TMP_BINARY_ITEMS_DIR)
231
+ Nanoc::Core::TempFilenameFactory.instance.create(TMP_BINARY_ITEMS_DIR)
202
232
  end
203
233
 
234
+ contract C::None => String
204
235
  # Returns the filename associated with the item that is being filtered.
205
236
  # It is in the format `item <identifier> (rep <name>)`.
206
237
  #
@@ -222,6 +253,7 @@ module Nanoc
222
253
  Fiber.yield(block)
223
254
  end
224
255
 
256
+ contract C::ArrayOf[C::Named['Nanoc::BasicItemView']] => C::Any
225
257
  # Creates a dependency from the item that is currently being filtered onto
226
258
  # the given collection of items. In other words, require the given items
227
259
  # to be compiled first before this items is processed.
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class Instrumentor
6
- def self.call(key, *args)
7
- stopwatch = DDMetrics::Stopwatch.new
8
- stopwatch.start
9
- yield
10
- ensure
11
- stopwatch.stop
12
- Nanoc::Int::NotificationCenter.post(key, stopwatch.duration, *args)
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class Instrumentor
7
+ def self.call(key, *args)
8
+ stopwatch = DDMetrics::Stopwatch.new
9
+ stopwatch.start
10
+ yield
11
+ ensure
12
+ stopwatch.stop
13
+ Nanoc::Core::NotificationCenter.post(key, stopwatch.duration, *args)
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -1,30 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class ItemRepBuilder
6
- attr_reader :reps
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class ItemRepBuilder
7
+ attr_reader :reps
7
8
 
8
- def initialize(site, action_provider, reps)
9
- @site = site
10
- @action_provider = action_provider
11
- @reps = reps
12
- end
9
+ def initialize(site, action_provider, reps)
10
+ @site = site
11
+ @action_provider = action_provider
12
+ @reps = reps
13
+ end
13
14
 
14
- def run
15
- @site.items.each do |item|
16
- @action_provider.rep_names_for(item).each do |rep_name|
17
- @reps << Nanoc::Int::ItemRep.new(item, rep_name)
15
+ def run
16
+ @site.items.each do |item|
17
+ @action_provider.rep_names_for(item).each do |rep_name|
18
+ @reps << Nanoc::Core::ItemRep.new(item, rep_name)
19
+ end
18
20
  end
19
- end
20
21
 
21
- action_sequences = Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
22
+ action_sequences = Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
22
23
 
23
- @reps.each do |rep|
24
- rep.snapshot_defs = action_sequences[rep].snapshots_defs
25
- end
24
+ @reps.each do |rep|
25
+ rep.snapshot_defs = action_sequences[rep].snapshots_defs
26
+ end
26
27
 
27
- action_sequences
28
+ action_sequences
29
+ end
28
30
  end
29
31
  end
30
32
  end
@@ -1,96 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # Assigns paths to reps.
5
- #
6
- # @api private
7
- class ItemRepRouter
8
- include Nanoc::Int::ContractsSupport
3
+ module Nanoc
4
+ module Int
5
+ # Assigns paths to reps.
6
+ #
7
+ # @api private
8
+ class ItemRepRouter
9
+ include Nanoc::Core::ContractsSupport
9
10
 
10
- class IdenticalRoutesError < ::Nanoc::Error
11
- def initialize(output_path, rep_a, rep_b)
12
- super("The item representations #{rep_a} and #{rep_b} are both routed to #{output_path}.")
11
+ class IdenticalRoutesError < ::Nanoc::Error
12
+ def initialize(output_path, rep_a, rep_b)
13
+ super("The item representations #{rep_a} and #{rep_b} are both routed to #{output_path}.")
14
+ end
13
15
  end
14
- end
15
16
 
16
- class RouteWithoutSlashError < ::Nanoc::Error
17
- def initialize(output_path, rep)
18
- super("The item representation #{rep} is routed to #{output_path}, which does not start with a slash, as required.")
17
+ class RouteWithoutSlashError < ::Nanoc::Error
18
+ def initialize(output_path, rep)
19
+ super("The item representation #{rep} is routed to #{output_path}, which does not start with a slash, as required.")
20
+ end
19
21
  end
20
- end
21
22
 
22
- def initialize(reps, action_provider, site)
23
- @reps = reps
24
- @action_provider = action_provider
25
- @site = site
26
- end
23
+ def initialize(reps, action_provider, site)
24
+ @reps = reps
25
+ @action_provider = action_provider
26
+ @site = site
27
+ end
27
28
 
28
- def run
29
- action_sequences = {}
30
- assigned_paths = {}
31
- @reps.each do |rep|
32
- # Sigh. We route reps twice, because the first time, the paths might not have converged
33
- # yet. This isn’t ideal, but it’s the only way to work around the divergence issues that
34
- # I can think of. For details, see
35
- # https://github.com/nanoc/nanoc/pull/1085#issuecomment-280628426.
29
+ def run
30
+ action_sequences = {}
31
+ assigned_paths = {}
32
+ @reps.each do |rep|
33
+ # Sigh. We route reps twice, because the first time, the paths might not have converged
34
+ # yet. This isn’t ideal, but it’s the only way to work around the divergence issues that
35
+ # I can think of. For details, see
36
+ # https://github.com/nanoc/nanoc/pull/1085#issuecomment-280628426.
36
37
 
37
- @action_provider.action_sequence_for(rep).paths.each do |(snapshot_names, paths)|
38
- route_rep(rep, paths, snapshot_names, {})
39
- end
38
+ @action_provider.action_sequence_for(rep).paths.each do |(snapshot_names, paths)|
39
+ route_rep(rep, paths, snapshot_names, {})
40
+ end
40
41
 
41
- seq = @action_provider.action_sequence_for(rep)
42
- action_sequences[rep] = seq
43
- seq.paths.each do |(snapshot_names, paths)|
44
- route_rep(rep, paths, snapshot_names, assigned_paths)
42
+ seq = @action_provider.action_sequence_for(rep)
43
+ action_sequences[rep] = seq
44
+ seq.paths.each do |(snapshot_names, paths)|
45
+ route_rep(rep, paths, snapshot_names, assigned_paths)
46
+ end
47
+
48
+ # TODO: verify that paths converge
45
49
  end
46
50
 
47
- # TODO: verify that paths converge
51
+ action_sequences
48
52
  end
49
53
 
50
- action_sequences
51
- end
52
-
53
- contract Nanoc::Int::ItemRep, C::IterOf[String], C::IterOf[Symbol], C::HashOf[String => Nanoc::Int::ItemRep] => C::Any
54
- def route_rep(rep, paths, snapshot_names, assigned_paths)
55
- # Encode
56
- paths = paths.map { |path| path.encode('UTF-8') }
54
+ contract Nanoc::Core::ItemRep, C::IterOf[String], C::IterOf[Symbol], C::HashOf[String => Nanoc::Core::ItemRep] => C::Any
55
+ def route_rep(rep, paths, snapshot_names, assigned_paths)
56
+ # Encode
57
+ paths = paths.map { |path| path.encode('UTF-8') }
57
58
 
58
- # Validate format
59
- paths.each do |path|
60
- unless path.start_with?('/')
61
- raise RouteWithoutSlashError.new(path, rep)
59
+ # Validate format
60
+ paths.each do |path|
61
+ unless path.start_with?('/')
62
+ raise RouteWithoutSlashError.new(path, rep)
63
+ end
62
64
  end
63
- end
64
65
 
65
- # Validate uniqueness
66
- paths.each do |path|
67
- if assigned_paths.include?(path)
68
- # TODO: Include snapshot names in error message
69
- reps = [assigned_paths[path], rep].sort_by { |r| [r.item.identifier, r.name] }
70
- raise IdenticalRoutesError.new(path, *reps)
66
+ # Validate uniqueness
67
+ paths.each do |path|
68
+ if assigned_paths.include?(path)
69
+ # TODO: Include snapshot names in error message
70
+ reps = [assigned_paths[path], rep].sort_by { |r| [r.item.identifier, r.name] }
71
+ raise IdenticalRoutesError.new(path, *reps)
72
+ end
73
+ end
74
+ paths.each do |path|
75
+ assigned_paths[path] = rep
71
76
  end
72
- end
73
- paths.each do |path|
74
- assigned_paths[path] = rep
75
- end
76
77
 
77
- # Assign
78
- snapshot_names.each do |snapshot_name|
79
- rep.raw_paths[snapshot_name] = paths.map { |path| @site.config.output_dir + path }
80
- rep.paths[snapshot_name] = paths.map { |path| strip_index_filename(path) }
78
+ # Assign
79
+ snapshot_names.each do |snapshot_name|
80
+ rep.raw_paths[snapshot_name] = paths.map { |path| @site.config.output_dir + path }
81
+ rep.paths[snapshot_name] = paths.map { |path| strip_index_filename(path) }
82
+ end
81
83
  end
82
- end
83
84
 
84
- contract String => String
85
- def strip_index_filename(basic_path)
86
- @site.config[:index_filenames].each do |index_filename|
87
- slashed_index_filename = '/' + index_filename
88
- if basic_path.end_with?(slashed_index_filename)
89
- return basic_path[0..-index_filename.length - 1]
85
+ contract String => String
86
+ def strip_index_filename(basic_path)
87
+ @site.config[:index_filenames].each do |index_filename|
88
+ slashed_index_filename = '/' + index_filename
89
+ if basic_path.end_with?(slashed_index_filename)
90
+ return basic_path[0..-index_filename.length - 1]
91
+ end
90
92
  end
91
- end
92
93
 
93
- basic_path
94
+ basic_path
95
+ end
94
96
  end
95
97
  end
96
98
  end
@@ -1,64 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # Yields item reps to compile.
5
- #
6
- # @api private
7
- class ItemRepSelector
8
- def initialize(reps)
9
- @reps = reps
10
- end
11
-
12
- class MicroGraph
3
+ module Nanoc
4
+ module Int
5
+ # Yields item reps to compile.
6
+ #
7
+ # @api private
8
+ class ItemRepSelector
13
9
  def initialize(reps)
14
- @reps = Set.new(reps)
15
- @stack = []
10
+ @reps = reps
16
11
  end
17
12
 
18
- def next
19
- if @stack.any?
20
- @stack.last
21
- elsif @reps.any?
22
- @reps.each { |rep| break rep }.tap do |rep|
23
- @reps.delete(rep)
24
- @stack.push(rep)
25
- end
26
- else
27
- nil
13
+ class MicroGraph
14
+ def initialize(reps)
15
+ @reps = Set.new(reps)
16
+ @stack = []
28
17
  end
29
- end
30
18
 
31
- def mark_ok
32
- @stack.pop
33
- end
19
+ def next
20
+ if @stack.any?
21
+ @stack.last
22
+ elsif @reps.any?
23
+ @reps.each { |rep| break rep }.tap do |rep|
24
+ @reps.delete(rep)
25
+ @stack.push(rep)
26
+ end
27
+ else
28
+ nil
29
+ end
30
+ end
34
31
 
35
- def mark_failed(dep)
36
- if @stack.include?(dep)
37
- raise Nanoc::Int::Errors::DependencyCycle.new(@stack + [dep])
32
+ def mark_ok
33
+ @stack.pop
38
34
  end
39
35
 
40
- @reps.delete(dep)
41
- @stack.push(dep)
36
+ def mark_failed(dep)
37
+ if @stack.include?(dep)
38
+ raise Nanoc::Int::Errors::DependencyCycle.new(@stack + [dep])
39
+ end
40
+
41
+ @reps.delete(dep)
42
+ @stack.push(dep)
43
+ end
42
44
  end
43
- end
44
45
 
45
- def each
46
- mg = MicroGraph.new(@reps)
46
+ def each
47
+ mg = MicroGraph.new(@reps)
47
48
 
48
- loop do
49
- rep = mg.next
50
- break if rep.nil?
49
+ loop do
50
+ rep = mg.next
51
+ break if rep.nil?
51
52
 
52
- begin
53
- yield(rep)
54
- mg.mark_ok
55
- rescue => e
56
- actual_error = e.is_a?(Nanoc::Int::Errors::CompilationError) ? e.unwrap : e
53
+ begin
54
+ yield(rep)
55
+ mg.mark_ok
56
+ rescue => e
57
+ actual_error = e.is_a?(Nanoc::Int::Errors::CompilationError) ? e.unwrap : e
57
58
 
58
- if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency)
59
- mg.mark_failed(actual_error.rep)
60
- else
61
- raise(e)
59
+ if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency)
60
+ mg.mark_failed(actual_error.rep)
61
+ else
62
+ raise(e)
63
+ end
62
64
  end
63
65
  end
64
66
  end