nanoc-core 4.12.11 → 4.12.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7fc026255728ddb8de8c0756afdfbdc7548e47938d9c4fb464023c0811ae4e2
4
- data.tar.gz: a8531e9c3920f81c9caa88996b1f195eedec21ef392cda04cd2fcf76c0f83106
3
+ metadata.gz: 94f41a5b7ba9b534f61e42a82dc9df7bebed20e7f2aadc6610d6b9523e2a3e8a
4
+ data.tar.gz: a40f9d8498cf715052ba691850e0e59c0877c107a7b0973594645ce7548cc289
5
5
  SHA512:
6
- metadata.gz: f819fe95a0d25831e51ba4ce360ca76921c01517402bf67d3407d369b1fc8c7f05a7262fe0df1dbfd03e3c3f12d72281d818db19746f294f135e8b017a21a07d
7
- data.tar.gz: c0de0aef8f83c0a7723d755bf804a25f3ca574e308b54b36cac6e0a91ac5b0b2c4658635cd899d18fdc830d51250a151cbb23d69dfdd4b4abd1cde5b12c96a2c
6
+ metadata.gz: 9c28483387d092e48b15f568fb910b60aa237dde2c152938ed4e36174ada46f56edbb29742ad7da98e903d5ed44066b40bc0821891ee48b1e1d48ff607d08370
7
+ data.tar.gz: b1d14a6cdbb245eb97b7820060406aa545571430214d835110f15d47bd721c49b28a66ee0473130699f4c4be2493cbd8267c81938c4dbc5981b5ce763a3a9437
@@ -72,10 +72,7 @@ module Nanoc
72
72
  # Error that is raised during site compilation when an item (directly or
73
73
  # indirectly) includes its own item content, leading to endless recursion.
74
74
  class DependencyCycle < ::Nanoc::Core::Error
75
- def initialize(stack)
76
- start_idx = stack.index(stack.last)
77
- cycle = stack[start_idx..-2]
78
-
75
+ def initialize(cycle)
79
76
  msg_bits = []
80
77
  msg_bits << 'The site cannot be compiled because there is a dependency cycle:'
81
78
  msg_bits << ''
@@ -8,58 +8,47 @@ module Nanoc
8
8
  @reps = reps
9
9
  end
10
10
 
11
- # An iterator (FIFO) over an array, with ability to ignore certain
12
- # elements.
13
- class ItemRepIgnorableIterator
14
- def initialize(array)
15
- @array = array.dup
16
- end
17
-
18
- def next_ignoring(ignored)
19
- elem = @array.shift
20
- elem = @array.shift while ignored.include?(elem)
21
- elem
22
- end
23
- end
24
-
25
11
  # A priority queue that tracks dependencies and can detect circular
26
12
  # dependencies.
27
13
  class ItemRepPriorityQueue
28
14
  def initialize(reps)
29
15
  # Prio A: most important; prio C: least important.
30
- @prio_a = []
31
- @prio_b = ItemRepIgnorableIterator.new(reps)
16
+ @prio_a = nil
17
+ @prio_b = reps.dup
32
18
  @prio_c = []
33
19
 
34
- # Stack of things that depend on each other. This is used for
35
- # detecting and reporting circular dependencies.
36
- @stack = []
37
-
38
20
  # List of reps that we’ve already seen. Reps from `reps` will end up
39
21
  # in here. Reps can end up in here even *before* they come from
40
22
  # `reps`, when they are part of a dependency.
41
23
  @seen = Set.new
24
+
25
+ # List of reps that have already been completed (yielded followed by
26
+ # `#mark_ok`).
27
+ @completed = Set.new
28
+
29
+ # Record (hard) dependencies. Used for detecting cycles.
30
+ @dependencies = Hash.new { |hash, key| hash[key] = Set.new }
42
31
  end
43
32
 
44
33
  def next
45
34
  # Read prio A
46
- @this = @prio_a.pop
35
+ @this = @prio_a
47
36
  if @this
48
- @stack.push(@this)
37
+ @prio_a = nil
49
38
  return @this
50
39
  end
51
40
 
52
41
  # Read prio B
53
- @this = @prio_b.next_ignoring(@seen)
42
+ @this = @prio_b.shift
43
+ @this = @prio_b.shift while @seen.include?(@this)
54
44
  if @this
55
- @stack.push(@this)
56
45
  return @this
57
46
  end
58
47
 
59
48
  # Read prio C
60
49
  @this = @prio_c.pop
50
+ @this = @prio_c.pop while @completed.include?(@this)
61
51
  if @this
62
- @stack.push(@this)
63
52
  return @this
64
53
  end
65
54
 
@@ -67,30 +56,49 @@ module Nanoc
67
56
  end
68
57
 
69
58
  def mark_ok
70
- @stack.pop
59
+ @completed << @this
71
60
  end
72
61
 
73
62
  def mark_failed(dep)
74
- if @stack.include?(dep)
75
- raise Nanoc::Core::Errors::DependencyCycle.new(@stack + [dep])
76
- end
63
+ record_dependency(dep)
77
64
 
78
65
  # `@this` depends on `dep`, so `dep` has to be compiled first. Thus,
79
66
  # move `@this` into priority C, and `dep` into priority A.
80
67
 
81
68
  # Put `@this` (item rep that needs `dep` to be compiled first) into
82
69
  # priority C (lowest prio).
83
- @prio_c.push(@this)
70
+ @prio_c.push(@this) unless @prio_c.include?(@this)
84
71
 
85
72
  # Put `dep` (item rep that needs to be compiled first, before
86
73
  # `@this`) into priority A (highest prio).
87
- @prio_a.push(dep)
74
+ @prio_a = dep
88
75
 
89
76
  # Remember that we’ve prioritised `dep`. This particular element will
90
77
  # come from @prio_b at some point in the future, so we’ll have to skip
91
78
  # it then.
92
79
  @seen << dep
93
80
  end
81
+
82
+ private
83
+
84
+ def record_dependency(dep)
85
+ @dependencies[@this] << dep
86
+
87
+ find_cycle(@this, [@this])
88
+ end
89
+
90
+ def find_cycle(dep, path)
91
+ @dependencies[dep].each do |dep1|
92
+ # Check whether this dependency path ends in `@this` again. If it
93
+ # does, we have a cycle (because we started from `@this`).
94
+ if dep1 == @this
95
+ raise Nanoc::Core::Errors::DependencyCycle.new(path)
96
+ end
97
+
98
+ # Continue checking, starting from `dep1` this time.
99
+ find_cycle(dep1, [*path, dep1])
100
+ end
101
+ end
94
102
  end
95
103
 
96
104
  def each
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Nanoc
4
4
  module Core
5
- VERSION = '4.12.11'
5
+ VERSION = '4.12.13'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.12.11
4
+ version: 4.12.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-12 00:00:00.000000000 Z
11
+ date: 2022-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -316,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
316
316
  - !ruby/object:Gem::Version
317
317
  version: '0'
318
318
  requirements: []
319
- rubygems_version: 3.3.25
319
+ rubygems_version: 3.4.0.dev
320
320
  signing_key:
321
321
  specification_version: 4
322
322
  summary: Core of Nanoc