nanoc 4.7.13 → 4.7.14

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
  SHA1:
3
- metadata.gz: d6113ac8b3ca8085d1247d4e880144d62af62037
4
- data.tar.gz: 557d2ae493c26da9ebe71735fcb19da59f9aeba4
3
+ metadata.gz: 95f87711482fb7881b63a2a4d0a7fca8fecede30
4
+ data.tar.gz: 6d5b0673fa14f07f4081cc473e24bdd0d558b481
5
5
  SHA512:
6
- metadata.gz: 7a0f046fd0f6b324dfea8451b0ab89142ff32a572e3e948cbf23e13337de70726097069101ed5484805d105f72ccd245ab8de0db2568f8310878e09eb083db4e
7
- data.tar.gz: 06e63734588725c3260fa543ad6844fb94dd7369092bea7249415f1096f363eed66267b752b0cb309e52377d730737688ef8b445b5b19b4029ed13889e7c6894
6
+ metadata.gz: 1ea685c54608f0c56af24542324c2cc2f3a4c7f84718c22d3abfde40288695290b45c83106283570be844b5183b12ca82c9a9239fefe34c47b8e73d9414755ad
7
+ data.tar.gz: cd48b21ea8577192f94e990a462d5237a81ea8a54bf3e60012e8552c69344b43abedafe5d70824d7f3732e95b7963542d59b55a2c331cb1df3e137475d6f89a5
data/NEWS.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Nanoc news
2
2
 
3
+ ## 4.7.14 (2017-07-16)
4
+
5
+ Enhancements:
6
+
7
+ * Various speed improvements (#1195, #1198)
8
+
3
9
  ## 4.7.13 (2017-07-02)
4
10
 
5
11
  Enhancements:
data/bin/nanoc CHANGED
@@ -2,6 +2,13 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'nanoc'
5
+
6
+ begin
7
+ require 'nanoc-rust'
8
+ NanocRust.activate!
9
+ rescue LoadError
10
+ end
11
+
5
12
  require 'nanoc/cli'
6
13
 
7
14
  if File.file?('Gemfile') && !defined?(Bundler)
@@ -43,7 +43,7 @@ module Nanoc::Int
43
43
  #
44
44
  # @return [Object] An unique reference to this object
45
45
  def reference
46
- [:code_snippet, filename]
46
+ "code_snippet:#{filename}"
47
47
  end
48
48
 
49
49
  def inspect
@@ -164,7 +164,7 @@ module Nanoc::Int
164
164
  #
165
165
  # @return [Object] An unique reference to this object
166
166
  def reference
167
- :config
167
+ 'configuration'
168
168
  end
169
169
 
170
170
  def inspect
@@ -7,27 +7,28 @@ module Nanoc::Int
7
7
  # @example Creating and using a directed graph
8
8
  #
9
9
  # # Create a graph with three vertices
10
- # graph = Nanoc::Int::DirectedGraph.new(%w( a b c d ))
10
+ # graph = Nanoc::Int::DirectedGraph.new(%w( a b c d e ))
11
11
  #
12
12
  # # Add edges
13
13
  # graph.add_edge('a', 'b')
14
14
  # graph.add_edge('b', 'c')
15
15
  # graph.add_edge('c', 'd')
16
+ # graph.add_edge('b', 'e')
16
17
  #
17
- # # Get (direct) predecessors
18
- # graph.direct_predecessors_of('d').sort
19
- # # => %w( c )
20
- # graph.predecessors_of('d').sort
21
- # # => %w( a b c )
18
+ # # Get (direct) successors
19
+ # graph.direct_successors_of('a').sort
20
+ # # => %w( b )
21
+ # graph.successors_of('a').sort
22
+ # # => %w( b c d e )
22
23
  #
23
24
  # # Modify edges
24
- # graph.delete_edge('a', 'b')
25
+ # graph.delete_edges_to('c')
25
26
  #
26
- # # Get (direct) predecessors again
27
- # graph.direct_predecessors_of('d').sort
28
- # # => %w( c )
29
- # graph.predecessors_of('d').sort
30
- # # => %w( b c )
27
+ # # Get (direct) successors again
28
+ # graph.direct_successors_of('a').sort
29
+ # # => %w( b )
30
+ # graph.successors_of('a').sort
31
+ # # => %w( b e )
31
32
  #
32
33
  # @api private
33
34
  class DirectedGraph
@@ -36,8 +37,9 @@ module Nanoc::Int
36
37
  # Creates a new directed graph with the given vertices.
37
38
  def initialize(vertices)
38
39
  @vertices = {}
39
- vertices.each_with_index do |v, i|
40
- @vertices[v] = i
40
+ @next_vertex_idx = 0
41
+ vertices.each do |v|
42
+ @vertices[v] = @next_vertex_idx.tap { @next_vertex_idx += 1 }
41
43
  end
42
44
 
43
45
  @from_graph = {}
@@ -45,8 +47,6 @@ module Nanoc::Int
45
47
 
46
48
  @edge_props = {}
47
49
 
48
- @roots = Set.new(@vertices.keys)
49
-
50
50
  invalidate_caches
51
51
  end
52
52
 
@@ -85,30 +85,6 @@ module Nanoc::Int
85
85
  @edge_props[[from, to]] = props
86
86
  end
87
87
 
88
- @roots.delete(to)
89
-
90
- invalidate_caches
91
- end
92
-
93
- # Removes the edge from the first vertex to the second vertex. If the
94
- # edge does not exist, nothing is done.
95
- #
96
- # @param from Start vertex of the edge
97
- #
98
- # @param to End vertex of the edge
99
- #
100
- # @return [void]
101
- def delete_edge(from, to)
102
- @from_graph[from] ||= Set.new
103
- @from_graph[from].delete(to)
104
-
105
- @to_graph[to] ||= Set.new
106
- @to_graph[to].delete(from)
107
-
108
- @edge_props.delete([from, to])
109
-
110
- @roots.add(to) if @to_graph[to].empty?
111
-
112
88
  invalidate_caches
113
89
  end
114
90
 
@@ -120,25 +96,7 @@ module Nanoc::Int
120
96
  def add_vertex(v)
121
97
  return if @vertices.key?(v)
122
98
 
123
- @vertices[v] = @vertices.size
124
-
125
- @roots << v
126
- end
127
-
128
- # Deletes all edges coming from the given vertex.
129
- #
130
- # @param from Vertex from which all edges should be removed
131
- #
132
- # @return [void]
133
- def delete_edges_from(from)
134
- return if @from_graph[from].nil?
135
-
136
- @from_graph[from].each do |to|
137
- @to_graph[to].delete(from)
138
- @edge_props.delete([from, to])
139
- @roots.add(to) if @to_graph[to].empty?
140
- end
141
- @from_graph.delete(from)
99
+ @vertices[v] = @next_vertex_idx.tap { @next_vertex_idx += 1 }
142
100
  end
143
101
 
144
102
  # Deletes all edges going to the given vertex.
@@ -154,64 +112,12 @@ module Nanoc::Int
154
112
  @edge_props.delete([from, to])
155
113
  end
156
114
  @to_graph.delete(to)
157
- @roots.add(to)
158
- end
159
-
160
- # Removes the given vertex from the graph.
161
- #
162
- # @param v Vertex to remove from the graph
163
- #
164
- # @return [void]
165
- def delete_vertex(v)
166
- delete_edges_to(v)
167
- delete_edges_from(v)
168
115
 
169
- @vertices.delete(v)
170
- @roots.delete(v)
116
+ invalidate_caches
171
117
  end
172
118
 
173
119
  # @group Querying the graph
174
120
 
175
- # Returns a cycle if there is any.
176
- def any_cycle
177
- all_paths.lazy.map { |path| cycle_in_path(path) }.find(&:itself)
178
- end
179
-
180
- # Given a potentially closed path, returns a cycle if there is any.
181
- def cycle_in_path(path)
182
- vertex = path.last
183
- index = path.index(vertex)
184
-
185
- if index < path.size - 1
186
- path[index..-2]
187
- end
188
- end
189
-
190
- # Yields all paths (including potentially closed ones).
191
- def all_paths
192
- Enumerator.new do |y|
193
- @vertices.keys.each do |vertex|
194
- dfs_from(vertex) do |path|
195
- y << path
196
- end
197
- end
198
- end
199
- end
200
-
201
- # Yields all paths (including potentially closed ones) starting from the given vertex.
202
- def dfs_from(vertex, path_so_far = [])
203
- new_path = path_so_far + [vertex]
204
- yield(new_path)
205
-
206
- unless path_so_far.include?(vertex)
207
- direct_successors_of(vertex).each do |next_vertex|
208
- dfs_from(next_vertex, new_path) do |path|
209
- yield(path)
210
- end
211
- end
212
- end
213
- end
214
-
215
121
  # Returns the direct predecessors of the given vertex, i.e. the vertices
216
122
  # x where there is an edge from x to the given vertex y.
217
123
  #
@@ -275,13 +181,6 @@ module Nanoc::Int
275
181
  result
276
182
  end
277
183
 
278
- # Returns all root vertices, i.e. vertices where no edge points to.
279
- #
280
- # @return [Set] The set of all root vertices in this graph.
281
- def roots
282
- @roots
283
- end
284
-
285
184
  private
286
185
 
287
186
  # Invalidates cached data. This method should be called when the internal
@@ -4,7 +4,7 @@ module Nanoc::Int
4
4
  # @api private
5
5
  class Item < ::Nanoc::Int::Document
6
6
  def reference
7
- [:item, identifier.to_s]
7
+ "item:#{identifier}"
8
8
  end
9
9
  end
10
10
  end
@@ -8,7 +8,7 @@ module Nanoc::Int
8
8
  end
9
9
 
10
10
  def reference
11
- :items
11
+ 'items'
12
12
  end
13
13
  end
14
14
  end
@@ -79,7 +79,7 @@ module Nanoc::Int
79
79
 
80
80
  # Returns an object that can be used for uniquely identifying objects.
81
81
  def reference
82
- [:item_rep, item.identifier, name]
82
+ "item_rep:#{item.identifier}:#{name}"
83
83
  end
84
84
 
85
85
  def inspect
@@ -4,7 +4,7 @@ module Nanoc::Int
4
4
  # @api private
5
5
  class Layout < ::Nanoc::Int::Document
6
6
  def reference
7
- [:layout, identifier.to_s]
7
+ "layout:#{identifier}"
8
8
  end
9
9
  end
10
10
  end
@@ -8,7 +8,7 @@ module Nanoc::Int
8
8
  end
9
9
 
10
10
  def reference
11
- :layouts
11
+ 'layouts'
12
12
  end
13
13
  end
14
14
  end
@@ -71,13 +71,14 @@ module Nanoc::Int
71
71
  # Error that is raised during site compilation when an item (directly or
72
72
  # indirectly) includes its own item content, leading to endless recursion.
73
73
  class DependencyCycle < Generic
74
- def initialize(graph)
75
- cycle = graph.any_cycle
74
+ def initialize(stack)
75
+ start_idx = stack.index(stack.last)
76
+ cycle = stack[start_idx..-2]
76
77
 
77
78
  msg_bits = []
78
79
  msg_bits << 'The site cannot be compiled because there is a dependency cycle:'
79
80
  msg_bits << ''
80
- cycle.reverse_each.with_index do |r, i|
81
+ cycle.each.with_index do |r, i|
81
82
  msg_bits << " (#{i + 1}) item #{r.item.identifier}, rep #{r.name.inspect}, uses compiled content of"
82
83
  end
83
84
  msg_bits << msg_bits.pop + ' (1)'
@@ -9,79 +9,58 @@ module Nanoc::Int
9
9
  @reps = reps
10
10
  end
11
11
 
12
- NONE = Object.new
13
-
14
- def each
15
- graph = Nanoc::Int::DirectedGraph.new(@reps)
16
-
17
- prio_dependent = Set.new
18
- prio_in_progress = Set.new
19
- loop do
20
- rep = find(graph, prio_dependent, prio_in_progress)
21
- break if NONE.equal?(rep)
22
-
23
- begin
24
- prio_in_progress << rep
25
- yield(rep)
26
- prio_in_progress.delete(rep)
27
- graph.delete_vertex(rep)
28
- rescue => e
29
- handle_error(e, rep, graph, prio_dependent)
30
- end
12
+ class MicroGraph
13
+ def initialize(reps)
14
+ @reps = Set.new(reps)
15
+ @stack = []
31
16
  end
32
17
 
33
- # Check whether everything was compiled
34
- unless graph.vertices.empty?
35
- raise Nanoc::Int::Errors::DependencyCycle.new(graph)
36
- end
37
- end
38
-
39
- def find(graph, prio_dependent, prio_in_progress)
40
- if graph.roots.empty?
41
- NONE
42
- elsif prio_dependent.any?
43
- find_prio(graph, prio_dependent, prio_dependent, prio_in_progress)
44
- elsif prio_in_progress.any?
45
- find_prio(graph, prio_in_progress, prio_dependent, prio_in_progress)
46
- else
47
- graph.roots.each { |e| break e }
48
- end
49
- end
50
-
51
- def find_prio(graph, prio, prio_dependent, prio_in_progress)
52
- until prio.empty?
53
- rep = prio.each { |e| break e }
54
- if graph.roots.include?(rep)
55
- return rep
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
56
26
  else
57
- prio.delete(rep)
27
+ nil
58
28
  end
59
29
  end
60
30
 
61
- find(graph, prio_dependent, prio_in_progress)
62
- end
31
+ def mark_ok
32
+ @stack.pop
33
+ end
63
34
 
64
- def handle_error(e, rep, graph, prio_dependent)
65
- actual_error =
66
- if e.is_a?(Nanoc::Int::Errors::CompilationError)
67
- e.unwrap
68
- else
69
- e
35
+ def mark_failed(dep)
36
+ if @stack.include?(dep)
37
+ raise Nanoc::Int::Errors::DependencyCycle.new(@stack + [dep])
70
38
  end
71
39
 
72
- if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency)
73
- handle_dependency_error(actual_error, rep, graph, prio_dependent)
74
- else
75
- raise(e)
40
+ @reps.delete(dep)
41
+ @stack.push(dep)
76
42
  end
77
43
  end
78
44
 
79
- def handle_dependency_error(e, rep, graph, prio_dependent)
80
- other_rep = e.rep
81
- prio_dependent << other_rep
82
- graph.add_edge(other_rep, rep)
83
- unless graph.vertices.include?(other_rep)
84
- graph.add_vertex(other_rep)
45
+ def each
46
+ mg = MicroGraph.new(@reps)
47
+
48
+ loop do
49
+ rep = mg.next
50
+ break if rep.nil?
51
+
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
57
+
58
+ if actual_error.is_a?(Nanoc::Int::Errors::UnmetDependency)
59
+ mg.mark_failed(actual_error.rep)
60
+ else
61
+ raise(e)
62
+ end
63
+ end
85
64
  end
86
65
  end
87
66
  end