nanoc 4.11.0 → 4.11.1
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.
- checksums.yaml +4 -4
- data/NEWS.md +6 -0
- data/lib/nanoc.rb +4 -7
- data/lib/nanoc/base.rb +3 -3
- data/lib/nanoc/base/assertions.rb +1 -1
- data/lib/nanoc/base/entities.rb +2 -20
- data/lib/nanoc/base/entities/action_sequence.rb +60 -64
- data/lib/nanoc/base/entities/checksum_collection.rb +23 -21
- data/lib/nanoc/base/entities/dependency.rb +24 -22
- data/lib/nanoc/base/entities/outdatedness_reasons.rb +74 -72
- data/lib/nanoc/base/entities/outdatedness_status.rb +19 -17
- data/lib/nanoc/base/entities/props.rb +119 -117
- data/lib/nanoc/base/entities/site.rb +46 -50
- data/lib/nanoc/base/errors.rb +183 -198
- data/lib/nanoc/base/repos.rb +4 -2
- data/lib/nanoc/base/repos/action_sequence_store.rb +44 -42
- data/lib/nanoc/base/repos/aggregate_data_source.rb +24 -22
- data/lib/nanoc/base/repos/checksum_store.rb +51 -49
- data/lib/nanoc/base/repos/compiled_content_cache.rb +47 -45
- data/lib/nanoc/base/repos/compiled_content_store.rb +76 -0
- data/lib/nanoc/base/repos/config_loader.rb +74 -72
- data/lib/nanoc/base/repos/dependency_store.rb +174 -172
- data/lib/nanoc/base/repos/in_mem_data_source.rb +17 -15
- data/lib/nanoc/base/repos/item_rep_repo.rb +26 -24
- data/lib/nanoc/base/repos/outdatedness_store.rb +50 -48
- data/lib/nanoc/base/repos/prefixed_data_source.rb +21 -19
- data/lib/nanoc/base/repos/site_loader.rb +75 -73
- data/lib/nanoc/base/repos/store.rb +93 -91
- data/lib/nanoc/base/services.rb +7 -3
- data/lib/nanoc/base/services/action_provider.rb +23 -21
- data/lib/nanoc/base/services/action_sequence_builder.rb +42 -34
- data/lib/nanoc/base/services/compilation_context.rb +49 -47
- data/lib/nanoc/base/services/compiler.rb +177 -170
- data/lib/nanoc/base/services/compiler/phases.rb +8 -1
- data/lib/nanoc/base/services/compiler/phases/abstract.rb +44 -38
- data/lib/nanoc/base/services/compiler/phases/cache.rb +34 -28
- data/lib/nanoc/base/services/compiler/phases/mark_done.rb +17 -11
- data/lib/nanoc/base/services/compiler/phases/notify.rb +21 -0
- data/lib/nanoc/base/services/compiler/phases/recalculate.rb +37 -31
- data/lib/nanoc/base/services/compiler/phases/resume.rb +47 -48
- data/lib/nanoc/base/services/compiler/phases/write.rb +65 -59
- data/lib/nanoc/base/services/compiler/stage.rb +27 -8
- data/lib/nanoc/base/services/compiler/stages.rb +7 -1
- data/lib/nanoc/base/services/compiler/stages/build_reps.rb +25 -19
- data/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb +34 -28
- data/lib/nanoc/base/services/compiler/stages/cleanup.rb +33 -27
- data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +79 -69
- data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +46 -40
- data/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb +15 -9
- data/lib/nanoc/base/services/compiler/stages/load_stores.rb +28 -22
- data/lib/nanoc/base/services/compiler/stages/postprocess.rb +16 -10
- data/lib/nanoc/base/services/compiler/stages/preprocess.rb +25 -19
- data/lib/nanoc/base/services/compiler/stages/prune.rb +23 -17
- data/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb +15 -9
- data/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb +26 -20
- data/lib/nanoc/base/services/compiler_loader.rb +26 -24
- data/lib/nanoc/base/services/dependency_tracker.rb +47 -45
- data/lib/nanoc/base/services/executor.rb +16 -15
- data/lib/nanoc/base/services/filter.rb +37 -5
- data/lib/nanoc/base/services/instrumentor.rb +12 -10
- data/lib/nanoc/base/services/item_rep_builder.rb +21 -19
- data/lib/nanoc/base/services/item_rep_router.rb +72 -70
- data/lib/nanoc/base/services/item_rep_selector.rb +48 -46
- data/lib/nanoc/base/services/item_rep_writer.rb +58 -53
- data/lib/nanoc/base/services/outdatedness_checker.rb +181 -179
- data/lib/nanoc/base/services/outdatedness_rule.rb +23 -21
- data/lib/nanoc/base/services/outdatedness_rules.rb +5 -3
- data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +28 -24
- data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +20 -16
- data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +13 -9
- data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +12 -8
- data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +12 -8
- data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +10 -6
- data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +39 -35
- data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +19 -15
- data/lib/nanoc/base/services/pruner.rb +2 -2
- data/lib/nanoc/base/views.rb +7 -0
- data/lib/nanoc/base/views/basic_item_view.rb +1 -1
- data/lib/nanoc/base/views/compilation_item_rep_view.rb +2 -2
- data/lib/nanoc/base/views/identifiable_collection_view.rb +2 -2
- data/lib/nanoc/base/views/mixins/document_view_mixin.rb +1 -1
- data/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb +5 -5
- data/lib/nanoc/base/views/mutable_item_collection_view.rb +3 -3
- data/lib/nanoc/base/views/mutable_layout_collection_view.rb +2 -2
- data/lib/nanoc/base/views/view_context_for_compilation.rb +6 -6
- data/lib/nanoc/base/views/view_context_for_pre_compilation.rb +2 -2
- data/lib/nanoc/base/views/view_context_for_shell.rb +2 -2
- data/lib/nanoc/checking/check.rb +1 -1
- data/lib/nanoc/cli/commands/compile_listeners/abstract.rb +24 -7
- data/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb +79 -15
- data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +4 -7
- data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +15 -24
- data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +22 -18
- data/lib/nanoc/cli/commands/create-site.rb +2 -7
- data/lib/nanoc/cli/commands/shell.rb +1 -1
- data/lib/nanoc/cli/commands/show-data.rb +9 -9
- data/lib/nanoc/cli/logger.rb +1 -1
- data/lib/nanoc/data_sources/filesystem.rb +8 -8
- data/lib/nanoc/filters/erb.rb +1 -1
- data/lib/nanoc/filters/erubi.rb +1 -1
- data/lib/nanoc/filters/erubis.rb +1 -1
- data/lib/nanoc/filters/haml.rb +1 -1
- data/lib/nanoc/filters/sass.rb +1 -1
- data/lib/nanoc/filters/slim.rb +1 -1
- data/lib/nanoc/helpers/breadcrumbs.rb +2 -2
- data/lib/nanoc/helpers/capturing.rb +9 -8
- data/lib/nanoc/helpers/filtering.rb +2 -2
- data/lib/nanoc/helpers/rendering.rb +1 -1
- data/lib/nanoc/rule_dsl.rb +10 -0
- data/lib/nanoc/rule_dsl/action_provider.rb +3 -3
- data/lib/nanoc/rule_dsl/action_recorder.rb +3 -3
- data/lib/nanoc/rule_dsl/action_sequence_calculator.rb +7 -7
- data/lib/nanoc/rule_dsl/compilation_rule.rb +2 -2
- data/lib/nanoc/rule_dsl/compilation_rule_context.rb +9 -9
- data/lib/nanoc/rule_dsl/compiler_dsl.rb +4 -4
- data/lib/nanoc/rule_dsl/routing_rule.rb +3 -3
- data/lib/nanoc/rule_dsl/rule.rb +5 -5
- data/lib/nanoc/rule_dsl/rule_context.rb +3 -3
- data/lib/nanoc/rule_dsl/rules_collection.rb +4 -4
- data/lib/nanoc/spec.rb +15 -15
- data/lib/nanoc/version.rb +1 -1
- metadata +10 -111
- data/lib/nanoc/base/contracts_support.rb +0 -130
- data/lib/nanoc/base/core_ext.rb +0 -5
- data/lib/nanoc/base/core_ext/array.rb +0 -50
- data/lib/nanoc/base/core_ext/hash.rb +0 -54
- data/lib/nanoc/base/core_ext/string.rb +0 -16
- data/lib/nanoc/base/entities/code_snippet.rb +0 -53
- data/lib/nanoc/base/entities/configuration-schema.json +0 -122
- data/lib/nanoc/base/entities/configuration.rb +0 -206
- data/lib/nanoc/base/entities/content.rb +0 -112
- data/lib/nanoc/base/entities/context.rb +0 -70
- data/lib/nanoc/base/entities/directed_graph.rb +0 -195
- data/lib/nanoc/base/entities/document.rb +0 -125
- data/lib/nanoc/base/entities/identifiable_collection.rb +0 -141
- data/lib/nanoc/base/entities/identifier.rb +0 -222
- data/lib/nanoc/base/entities/item.rb +0 -10
- data/lib/nanoc/base/entities/item_collection.rb +0 -14
- data/lib/nanoc/base/entities/item_rep.rb +0 -91
- data/lib/nanoc/base/entities/layout.rb +0 -10
- data/lib/nanoc/base/entities/layout_collection.rb +0 -14
- data/lib/nanoc/base/entities/lazy_value.rb +0 -43
- data/lib/nanoc/base/entities/pattern.rb +0 -85
- data/lib/nanoc/base/entities/processing_action.rb +0 -21
- data/lib/nanoc/base/entities/processing_actions.rb +0 -5
- data/lib/nanoc/base/entities/processing_actions/filter.rb +0 -36
- data/lib/nanoc/base/entities/processing_actions/layout.rb +0 -36
- data/lib/nanoc/base/entities/processing_actions/snapshot.rb +0 -46
- data/lib/nanoc/base/entities/snapshot_def.rb +0 -22
- data/lib/nanoc/base/repos/data_source.rb +0 -168
- data/lib/nanoc/base/repos/snapshot_repo.rb +0 -67
- data/lib/nanoc/base/services/checksummer.rb +0 -274
- data/lib/nanoc/base/services/notification_center.rb +0 -87
- 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::
|
16
|
+
Nanoc::Core::NotificationCenter.post(:filtering_started, @rep, filter_name)
|
17
17
|
|
18
18
|
# Run filter
|
19
|
-
last = @compilation_context.
|
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::
|
25
|
+
Nanoc::Core::BinaryContent.new(filter.output_filename).tap(&:freeze)
|
26
26
|
else
|
27
|
-
Nanoc::
|
27
|
+
Nanoc::Core::TextualContent.new(result).tap(&:freeze)
|
28
28
|
end
|
29
29
|
|
30
30
|
# Store
|
31
|
-
@compilation_context.
|
31
|
+
@compilation_context.compiled_content_store.set_current(@rep, last)
|
32
32
|
ensure
|
33
|
-
Nanoc::
|
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.
|
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::
|
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::
|
70
|
-
@compilation_context.
|
69
|
+
last = Nanoc::Core::TextualContent.new(res).tap(&:freeze)
|
70
|
+
@compilation_context.compiled_content_store.set_current(@rep, last)
|
71
71
|
ensure
|
72
|
-
Nanoc::
|
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.
|
78
|
-
@compilation_context.
|
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::
|
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.
|
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::
|
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
|
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::
|
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::
|
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::
|
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
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Nanoc
|
4
|
+
module Int
|
5
|
+
# @api private
|
6
|
+
class ItemRepBuilder
|
7
|
+
attr_reader :reps
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def initialize(site, action_provider, reps)
|
10
|
+
@site = site
|
11
|
+
@action_provider = action_provider
|
12
|
+
@reps = reps
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
22
|
+
action_sequences = Nanoc::Int::ItemRepRouter.new(@reps, @action_provider, @site).run
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
@reps.each do |rep|
|
25
|
+
rep.snapshot_defs = action_sequences[rep].snapshots_defs
|
26
|
+
end
|
26
27
|
|
27
|
-
|
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
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def initialize(reps, action_provider, site)
|
24
|
+
@reps = reps
|
25
|
+
@action_provider = action_provider
|
26
|
+
@site = site
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
51
|
+
action_sequences
|
48
52
|
end
|
49
53
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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
|
-
|
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
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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 =
|
15
|
-
@stack = []
|
10
|
+
@reps = reps
|
16
11
|
end
|
17
12
|
|
18
|
-
|
19
|
-
|
20
|
-
@
|
21
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
36
|
-
|
37
|
-
raise Nanoc::Int::Errors::DependencyCycle.new(@stack + [dep])
|
32
|
+
def mark_ok
|
33
|
+
@stack.pop
|
38
34
|
end
|
39
35
|
|
40
|
-
|
41
|
-
|
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
|
-
|
46
|
-
|
46
|
+
def each
|
47
|
+
mg = MicroGraph.new(@reps)
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
49
|
+
loop do
|
50
|
+
rep = mg.next
|
51
|
+
break if rep.nil?
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|