nanoc-core 4.14.0 → 4.14.2
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/lib/nanoc/core/compilation_item_rep_view.rb +1 -1
- data/lib/nanoc/core/compilation_phases/notify.rb +3 -0
- data/lib/nanoc/core/compilation_phases/recalculate.rb +16 -3
- data/lib/nanoc/core/compilation_stages/compile_reps.rb +7 -6
- data/lib/nanoc/core/compiled_content_store.rb +2 -3
- data/lib/nanoc/core/directed_graph.rb +7 -3
- data/lib/nanoc/core/filter.rb +0 -5
- data/lib/nanoc/core/item_rep_selector.rb +29 -19
- data/lib/nanoc/core/notification_center.rb +5 -54
- data/lib/nanoc/core/version.rb +1 -1
- metadata +3 -4
- data/lib/nanoc/core/compilation_phases/resume.rb +0 -52
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1eb383ecd0b9f70dab794c7cbbeaea2000372252ec7fca79a88977f4b9ee52e4
|
|
4
|
+
data.tar.gz: 10b983997d7836e81a8d9926f8ccaf2f2208e557fce3a61d67675dc954d8dd4a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2a05d9133dfcea7375b3b2dbc86d876701f86d29298bc029eae947b59893071f06df12aeb0491179ec3b6f725770de9ff7af940d16ffbd978c02859acb50e2cb
|
|
7
|
+
data.tar.gz: e374dd038fb6535c7e48ec2228f872ec06a70022a82306da0a4ac35c11ec2133e88aea1bee4f0ec5fbe339965a63e67f2054a34d1afacb8b7275c26de7e5e6c1
|
|
@@ -27,7 +27,7 @@ module Nanoc
|
|
|
27
27
|
res = @item_rep.raw_path(snapshot:)
|
|
28
28
|
|
|
29
29
|
unless @item_rep.compiled?
|
|
30
|
-
|
|
30
|
+
raise Nanoc::Core::Errors::UnmetDependency.new(@item_rep, snapshot)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# Wait for file to exist
|
|
@@ -12,6 +12,9 @@ module Nanoc
|
|
|
12
12
|
Nanoc::Core::NotificationCenter.post(:compilation_started, rep)
|
|
13
13
|
yield
|
|
14
14
|
Nanoc::Core::NotificationCenter.post(:compilation_ended, rep)
|
|
15
|
+
rescue Nanoc::Core::Errors::UnmetDependency
|
|
16
|
+
Nanoc::Core::NotificationCenter.post(:compilation_suspended, rep)
|
|
17
|
+
raise
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
20
|
end
|
|
@@ -23,10 +23,16 @@ module Nanoc
|
|
|
23
23
|
|
|
24
24
|
executor = Nanoc::Core::Executor.new(rep, @compilation_context, dependency_tracker)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
# Set initial content, if not already present
|
|
27
|
+
compiled_content_store = @compilation_context.compiled_content_store
|
|
28
|
+
unless compiled_content_store.get_current(rep)
|
|
29
|
+
compiled_content_store.set_current(rep, rep.item.content)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
actions = pending_action_sequence_for(rep:)
|
|
33
|
+
until actions.empty?
|
|
34
|
+
action = actions.first
|
|
27
35
|
|
|
28
|
-
actions = @action_sequences[rep]
|
|
29
|
-
actions.each do |action|
|
|
30
36
|
case action
|
|
31
37
|
when Nanoc::Core::ProcessingActions::Filter
|
|
32
38
|
executor.filter(action.filter_name, action.params)
|
|
@@ -39,10 +45,17 @@ module Nanoc
|
|
|
39
45
|
else
|
|
40
46
|
raise Nanoc::Core::Errors::InternalInconsistency, "unknown action #{action.inspect}"
|
|
41
47
|
end
|
|
48
|
+
|
|
49
|
+
actions.shift
|
|
42
50
|
end
|
|
43
51
|
ensure
|
|
44
52
|
dependency_tracker.exit
|
|
45
53
|
end
|
|
54
|
+
|
|
55
|
+
def pending_action_sequence_for(rep:)
|
|
56
|
+
@_pending_action_sequences ||= {}
|
|
57
|
+
@_pending_action_sequences[rep] ||= @action_sequences[rep].to_a
|
|
58
|
+
end
|
|
46
59
|
end
|
|
47
60
|
end
|
|
48
61
|
end
|
|
@@ -33,7 +33,12 @@ module Nanoc
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
selector = Nanoc::Core::ItemRepSelector.new(
|
|
36
|
+
selector = Nanoc::Core::ItemRepSelector.new(
|
|
37
|
+
outdated_reps:,
|
|
38
|
+
reps: @reps,
|
|
39
|
+
dependency_store: @dependency_store,
|
|
40
|
+
)
|
|
41
|
+
|
|
37
42
|
run_phase_stack do |phase_stack|
|
|
38
43
|
selector.each do |rep|
|
|
39
44
|
handle_errors_while(rep) do
|
|
@@ -87,13 +92,9 @@ module Nanoc
|
|
|
87
92
|
wrapped: recalculate_phase,
|
|
88
93
|
)
|
|
89
94
|
|
|
90
|
-
resume_phase = Nanoc::Core::CompilationPhases::Resume.new(
|
|
91
|
-
wrapped: cache_phase,
|
|
92
|
-
)
|
|
93
|
-
|
|
94
95
|
write_phase = Nanoc::Core::CompilationPhases::Write.new(
|
|
95
96
|
compiled_content_store: @compilation_context.compiled_content_store,
|
|
96
|
-
wrapped:
|
|
97
|
+
wrapped: cache_phase,
|
|
97
98
|
)
|
|
98
99
|
|
|
99
100
|
mark_done_phase = Nanoc::Core::CompilationPhases::MarkDone.new(
|
|
@@ -57,9 +57,8 @@ module Nanoc
|
|
|
57
57
|
content = get(rep, snapshot_name)
|
|
58
58
|
return content if content
|
|
59
59
|
|
|
60
|
-
# Content is unavailable
|
|
61
|
-
|
|
62
|
-
get(rep, snapshot_name)
|
|
60
|
+
# Content is unavailable
|
|
61
|
+
raise Nanoc::Core::Errors::UnmetDependency.new(rep, snapshot_name)
|
|
63
62
|
end
|
|
64
63
|
|
|
65
64
|
contract C::KeywordArgs[rep: Nanoc::Core::ItemRep, snapshot: C::Optional[C::Maybe[Symbol]]] => String
|
|
@@ -33,6 +33,8 @@ module Nanoc
|
|
|
33
33
|
# graph.predecessors_of('e').sort
|
|
34
34
|
# # => %w( c d )
|
|
35
35
|
class DirectedGraph
|
|
36
|
+
EMPTY_SET = Set.new.freeze
|
|
37
|
+
|
|
36
38
|
# @group Creating a graph
|
|
37
39
|
|
|
38
40
|
# Creates a new directed graph with the given vertices.
|
|
@@ -40,7 +42,8 @@ module Nanoc
|
|
|
40
42
|
@vertices = {}
|
|
41
43
|
@next_vertex_idx = 0
|
|
42
44
|
vertices.each do |v|
|
|
43
|
-
@vertices[v] = @next_vertex_idx
|
|
45
|
+
@vertices[v] = @next_vertex_idx
|
|
46
|
+
@next_vertex_idx += 1
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
@to_graph = {}
|
|
@@ -93,7 +96,8 @@ module Nanoc
|
|
|
93
96
|
def add_vertex(vertex)
|
|
94
97
|
return if @vertices.key?(vertex)
|
|
95
98
|
|
|
96
|
-
@vertices[vertex] = @next_vertex_idx
|
|
99
|
+
@vertices[vertex] = @next_vertex_idx
|
|
100
|
+
@next_vertex_idx += 1
|
|
97
101
|
end
|
|
98
102
|
|
|
99
103
|
# Deletes all edges going to the given vertex.
|
|
@@ -121,7 +125,7 @@ module Nanoc
|
|
|
121
125
|
#
|
|
122
126
|
# @return [Array] Direct predecessors of the given vertex
|
|
123
127
|
def direct_predecessors_of(to)
|
|
124
|
-
@to_graph.fetch(to,
|
|
128
|
+
@to_graph.fetch(to, EMPTY_SET)
|
|
125
129
|
end
|
|
126
130
|
|
|
127
131
|
# Returns the predecessors of the given vertex, i.e. the vertices x for
|
data/lib/nanoc/core/filter.rb
CHANGED
|
@@ -249,11 +249,6 @@ module Nanoc
|
|
|
249
249
|
end
|
|
250
250
|
end
|
|
251
251
|
|
|
252
|
-
# @api private
|
|
253
|
-
def on_main_fiber(&block)
|
|
254
|
-
Fiber.yield(block)
|
|
255
|
-
end
|
|
256
|
-
|
|
257
252
|
contract C::ArrayOf[C::Named['Nanoc::Core::BasicItemView']] => C::Any
|
|
258
253
|
# Creates a dependency from the item that is currently being filtered onto
|
|
259
254
|
# the given collection of items. In other words, require the given items
|
|
@@ -4,17 +4,22 @@ module Nanoc
|
|
|
4
4
|
module Core
|
|
5
5
|
# Yields item reps to compile.
|
|
6
6
|
class ItemRepSelector
|
|
7
|
-
def initialize(reps)
|
|
7
|
+
def initialize(outdated_reps:, reps:, dependency_store:)
|
|
8
|
+
@outdated_reps = outdated_reps
|
|
8
9
|
@reps = reps
|
|
10
|
+
@dependency_store = dependency_store
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
# A priority queue that tracks dependencies and can detect circular
|
|
12
14
|
# dependencies.
|
|
13
15
|
class ItemRepPriorityQueue
|
|
14
|
-
def initialize(reps)
|
|
16
|
+
def initialize(outdated_reps:, reps:, dependency_store:)
|
|
17
|
+
@reps = reps
|
|
18
|
+
@dependency_store = dependency_store
|
|
19
|
+
|
|
15
20
|
# Prio A: most important; prio C: least important.
|
|
16
21
|
@prio_a = nil
|
|
17
|
-
@prio_b =
|
|
22
|
+
@prio_b = outdated_reps.dup
|
|
18
23
|
@prio_c = []
|
|
19
24
|
|
|
20
25
|
# List of reps that we’ve already seen. Reps from `reps` will end up
|
|
@@ -59,30 +64,31 @@ module Nanoc
|
|
|
59
64
|
@completed << @this
|
|
60
65
|
end
|
|
61
66
|
|
|
62
|
-
def mark_failed(
|
|
63
|
-
record_dependency(
|
|
67
|
+
def mark_failed(needed_rep:)
|
|
68
|
+
record_dependency(needed_rep)
|
|
64
69
|
|
|
65
|
-
# `@this` depends on `
|
|
66
|
-
# move `@this` into priority C, and `
|
|
70
|
+
# `@this` depends on `needed_rep`, so `needed_rep` has to be compiled
|
|
71
|
+
# first. Thus, move `@this` into priority C, and `needed_rep` into
|
|
72
|
+
# priority A.
|
|
67
73
|
|
|
68
|
-
# Put `@this` (item rep that needs `
|
|
69
|
-
# priority C (lowest prio).
|
|
74
|
+
# Put `@this` (item rep that needs `needed_rep` to be compiled first)
|
|
75
|
+
# into priority C (lowest prio).
|
|
70
76
|
@prio_c.push(@this) unless @prio_c.include?(@this)
|
|
71
77
|
|
|
72
|
-
# Put `
|
|
78
|
+
# Put `needed_rep` (item rep that needs to be compiled first, before
|
|
73
79
|
# `@this`) into priority A (highest prio).
|
|
74
|
-
@prio_a =
|
|
80
|
+
@prio_a = needed_rep
|
|
75
81
|
|
|
76
|
-
# Remember that we’ve prioritised `
|
|
77
|
-
# come from @prio_b at some point in the future, so we’ll
|
|
78
|
-
# it then.
|
|
79
|
-
@seen <<
|
|
82
|
+
# Remember that we’ve prioritised `needed_rep`. This particular
|
|
83
|
+
# element will come from @prio_b at some point in the future, so we’ll
|
|
84
|
+
# have to skip it then.
|
|
85
|
+
@seen << needed_rep
|
|
80
86
|
end
|
|
81
87
|
|
|
82
88
|
private
|
|
83
89
|
|
|
84
|
-
def record_dependency(
|
|
85
|
-
@dependencies[@this] <<
|
|
90
|
+
def record_dependency(rep)
|
|
91
|
+
@dependencies[@this] << rep
|
|
86
92
|
|
|
87
93
|
find_cycle(@this, [@this])
|
|
88
94
|
end
|
|
@@ -102,7 +108,11 @@ module Nanoc
|
|
|
102
108
|
end
|
|
103
109
|
|
|
104
110
|
def each
|
|
105
|
-
pq = ItemRepPriorityQueue.new(
|
|
111
|
+
pq = ItemRepPriorityQueue.new(
|
|
112
|
+
outdated_reps: @outdated_reps,
|
|
113
|
+
reps: @reps,
|
|
114
|
+
dependency_store: @dependency_store,
|
|
115
|
+
)
|
|
106
116
|
|
|
107
117
|
loop do
|
|
108
118
|
rep = pq.next
|
|
@@ -115,7 +125,7 @@ module Nanoc
|
|
|
115
125
|
actual_error = e.is_a?(Nanoc::Core::Errors::CompilationError) ? e.unwrap : e
|
|
116
126
|
|
|
117
127
|
if actual_error.is_a?(Nanoc::Core::Errors::UnmetDependency)
|
|
118
|
-
pq.mark_failed(actual_error.rep)
|
|
128
|
+
pq.mark_failed(needed_rep: actual_error.rep)
|
|
119
129
|
else
|
|
120
130
|
raise(e)
|
|
121
131
|
end
|
|
@@ -10,46 +10,9 @@ module Nanoc
|
|
|
10
10
|
# table of subscribers is not stored in the observable object itself, but in
|
|
11
11
|
# the notification center.
|
|
12
12
|
class NotificationCenter
|
|
13
|
-
DONE = Object.new
|
|
14
|
-
SYNC = Object.new
|
|
15
|
-
|
|
16
13
|
def initialize
|
|
17
|
-
@thread = nil
|
|
18
|
-
|
|
19
14
|
# name => observers dictionary
|
|
20
15
|
@notifications = Hash.new { |hash, name| hash[name] = [] }
|
|
21
|
-
|
|
22
|
-
@queue = Queue.new
|
|
23
|
-
|
|
24
|
-
@sync_queue = Queue.new
|
|
25
|
-
on(SYNC, self) { @sync_queue << true }
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def start
|
|
29
|
-
@thread ||= Thread.new do # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
30
|
-
Thread.current.abort_on_exception = true
|
|
31
|
-
|
|
32
|
-
loop do
|
|
33
|
-
elem = @queue.pop
|
|
34
|
-
break if DONE.equal?(elem)
|
|
35
|
-
|
|
36
|
-
name = elem[0]
|
|
37
|
-
args = elem[1]
|
|
38
|
-
|
|
39
|
-
@notifications[name].each do |observer|
|
|
40
|
-
observer[:block].call(*args)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def stop
|
|
47
|
-
@queue << DONE
|
|
48
|
-
@thread.join
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def force_stop
|
|
52
|
-
@queue << DONE
|
|
53
16
|
end
|
|
54
17
|
|
|
55
18
|
def on(name, id = nil, &block)
|
|
@@ -61,18 +24,16 @@ module Nanoc
|
|
|
61
24
|
end
|
|
62
25
|
|
|
63
26
|
def post(name, *args)
|
|
64
|
-
@
|
|
65
|
-
|
|
66
|
-
|
|
27
|
+
@notifications[name].each do |observer|
|
|
28
|
+
observer[:block].call(*args)
|
|
29
|
+
end
|
|
67
30
|
|
|
68
|
-
|
|
69
|
-
post(SYNC)
|
|
70
|
-
@sync_queue.pop
|
|
31
|
+
self
|
|
71
32
|
end
|
|
72
33
|
|
|
73
34
|
class << self
|
|
74
35
|
def instance
|
|
75
|
-
@_instance ||= new
|
|
36
|
+
@_instance ||= new
|
|
76
37
|
end
|
|
77
38
|
|
|
78
39
|
def on(name, id = nil, &)
|
|
@@ -88,18 +49,8 @@ module Nanoc
|
|
|
88
49
|
end
|
|
89
50
|
|
|
90
51
|
def reset
|
|
91
|
-
instance.stop
|
|
92
52
|
@_instance = nil
|
|
93
53
|
end
|
|
94
|
-
|
|
95
|
-
def force_reset
|
|
96
|
-
instance.force_stop
|
|
97
|
-
@_instance = nil
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def sync
|
|
101
|
-
instance.sync
|
|
102
|
-
end
|
|
103
54
|
end
|
|
104
55
|
end
|
|
105
56
|
end
|
data/lib/nanoc/core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nanoc-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.14.
|
|
4
|
+
version: 4.14.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Defreyne
|
|
@@ -185,7 +185,6 @@ files:
|
|
|
185
185
|
- lib/nanoc/core/compilation_phases/mark_done.rb
|
|
186
186
|
- lib/nanoc/core/compilation_phases/notify.rb
|
|
187
187
|
- lib/nanoc/core/compilation_phases/recalculate.rb
|
|
188
|
-
- lib/nanoc/core/compilation_phases/resume.rb
|
|
189
188
|
- lib/nanoc/core/compilation_phases/write.rb
|
|
190
189
|
- lib/nanoc/core/compilation_stage.rb
|
|
191
190
|
- lib/nanoc/core/compilation_stages/build_reps.rb
|
|
@@ -304,7 +303,7 @@ licenses:
|
|
|
304
303
|
- MIT
|
|
305
304
|
metadata:
|
|
306
305
|
rubygems_mfa_required: 'true'
|
|
307
|
-
source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-core-v4.14.
|
|
306
|
+
source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-core-v4.14.2/nanoc-core
|
|
308
307
|
rdoc_options: []
|
|
309
308
|
require_paths:
|
|
310
309
|
- lib
|
|
@@ -319,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
319
318
|
- !ruby/object:Gem::Version
|
|
320
319
|
version: '0'
|
|
321
320
|
requirements: []
|
|
322
|
-
rubygems_version: 3.
|
|
321
|
+
rubygems_version: 3.6.9
|
|
323
322
|
specification_version: 4
|
|
324
323
|
summary: Core of Nanoc
|
|
325
324
|
test_files: []
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Nanoc
|
|
4
|
-
module Core
|
|
5
|
-
module CompilationPhases
|
|
6
|
-
# Provides functionality for suspending and resuming item rep compilation (using fibers).
|
|
7
|
-
class Resume < Abstract
|
|
8
|
-
include Nanoc::Core::ContractsSupport
|
|
9
|
-
|
|
10
|
-
DONE = Object.new
|
|
11
|
-
|
|
12
|
-
contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
|
|
13
|
-
def run(rep, is_outdated:, &)
|
|
14
|
-
fiber = fiber_for(rep, is_outdated:, &)
|
|
15
|
-
while fiber.alive?
|
|
16
|
-
res = fiber.resume
|
|
17
|
-
|
|
18
|
-
case res
|
|
19
|
-
when Nanoc::Core::Errors::UnmetDependency
|
|
20
|
-
Nanoc::Core::NotificationCenter.post(:compilation_suspended, rep, res.rep, res.snapshot_name)
|
|
21
|
-
raise(res)
|
|
22
|
-
when Proc
|
|
23
|
-
fiber.resume(res.call)
|
|
24
|
-
when DONE
|
|
25
|
-
# ignore
|
|
26
|
-
else
|
|
27
|
-
raise Nanoc::Core::Errors::InternalInconsistency.new(
|
|
28
|
-
"Fiber yielded object of unexpected type #{res.class}",
|
|
29
|
-
)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => Fiber
|
|
37
|
-
def fiber_for(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
|
|
38
|
-
@fibers ||= {}
|
|
39
|
-
|
|
40
|
-
@fibers[rep] ||=
|
|
41
|
-
Fiber.new do
|
|
42
|
-
yield
|
|
43
|
-
@fibers.delete(rep)
|
|
44
|
-
DONE
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
@fibers[rep]
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|