nanoc3 3.0.9 → 3.1.0a1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/NEWS.md +360 -0
- data/README.md +85 -0
- data/Rakefile +2 -2
- data/bin/nanoc3 +0 -4
- data/lib/nanoc3/base/code_snippet.rb +14 -6
- data/lib/nanoc3/base/compiler.rb +68 -49
- data/lib/nanoc3/base/compiler_dsl.rb +70 -29
- data/lib/nanoc3/base/context.rb +47 -0
- data/lib/nanoc3/base/core_ext/array.rb +4 -0
- data/lib/nanoc3/base/core_ext/hash.rb +5 -1
- data/lib/nanoc3/base/core_ext/string.rb +2 -0
- data/lib/nanoc3/base/data_source.rb +132 -96
- data/lib/nanoc3/base/dependency_tracker.rb +160 -185
- data/lib/nanoc3/base/directed_graph.rb +252 -0
- data/lib/nanoc3/base/errors.rb +52 -4
- data/lib/nanoc3/base/filter.rb +43 -28
- data/lib/nanoc3/base/item.rb +93 -25
- data/lib/nanoc3/base/item_rep.rb +166 -55
- data/lib/nanoc3/base/layout.rb +16 -13
- data/lib/nanoc3/base/notification_center.rb +28 -12
- data/lib/nanoc3/base/plugin_registry.rb +158 -0
- data/lib/nanoc3/base/rule.rb +27 -8
- data/lib/nanoc3/base/rule_context.rb +59 -46
- data/lib/nanoc3/base/site.rb +124 -77
- data/lib/nanoc3/base.rb +7 -2
- data/lib/nanoc3/cli/base.rb +4 -1
- data/lib/nanoc3/cli/commands/autocompile.rb +5 -4
- data/lib/nanoc3/cli/commands/compile.rb +28 -7
- data/lib/nanoc3/cli/commands/create_item.rb +1 -1
- data/lib/nanoc3/cli/commands/create_layout.rb +1 -1
- data/lib/nanoc3/cli/commands/create_site.rb +46 -22
- data/lib/nanoc3/cli/commands/debug.rb +100 -0
- data/lib/nanoc3/cli/commands/help.rb +1 -1
- data/lib/nanoc3/cli/commands/info.rb +1 -1
- data/lib/nanoc3/cli/commands/view.rb +85 -0
- data/lib/nanoc3/cli/commands.rb +2 -0
- data/lib/nanoc3/cli/logger.rb +7 -0
- data/lib/nanoc3/cli.rb +0 -3
- data/lib/nanoc3/data_sources/{delicious.rb → deprecated/delicious.rb} +1 -24
- data/lib/nanoc3/data_sources/{last_fm.rb → deprecated/last_fm.rb} +1 -27
- data/lib/nanoc3/data_sources/{twitter.rb → deprecated/twitter.rb} +1 -14
- data/lib/nanoc3/data_sources/filesystem.rb +188 -176
- data/lib/nanoc3/data_sources/filesystem_unified.rb +107 -0
- data/lib/nanoc3/data_sources/filesystem_verbose.rb +80 -0
- data/lib/nanoc3/data_sources.rb +18 -9
- data/lib/nanoc3/extra/core_ext/enumerable.rb +39 -0
- data/lib/nanoc3/extra/core_ext/time.rb +2 -2
- data/lib/nanoc3/extra/core_ext.rb +1 -0
- data/lib/nanoc3/extra/deployers/rsync.rb +49 -3
- data/lib/nanoc3/extra/file_proxy.rb +7 -0
- data/lib/nanoc3/extra/vcs.rb +25 -24
- data/lib/nanoc3/extra/vcses/bazaar.rb +4 -0
- data/lib/nanoc3/extra/vcses/dummy.rb +4 -0
- data/lib/nanoc3/extra/vcses/git.rb +4 -0
- data/lib/nanoc3/extra/vcses/mercurial.rb +4 -0
- data/lib/nanoc3/extra/vcses/subversion.rb +4 -0
- data/lib/nanoc3/extra.rb +4 -1
- data/lib/nanoc3/filters/erb.rb +1 -1
- data/lib/nanoc3/filters/erubis.rb +1 -1
- data/lib/nanoc3/filters/haml.rb +1 -1
- data/lib/nanoc3/filters/kramdown.rb +14 -0
- data/lib/nanoc3/filters/maruku.rb +1 -1
- data/lib/nanoc3/filters/rainpress.rb +1 -1
- data/lib/nanoc3/filters/rdiscount.rb +3 -1
- data/lib/nanoc3/filters.rb +2 -0
- data/lib/nanoc3/helpers/blogging.rb +91 -75
- data/lib/nanoc3/helpers/breadcrumbs.rb +18 -10
- data/lib/nanoc3/helpers/capturing.rb +24 -29
- data/lib/nanoc3/helpers/filtering.rb +20 -17
- data/lib/nanoc3/helpers/html_escape.rb +7 -4
- data/lib/nanoc3/helpers/link_to.rb +51 -41
- data/lib/nanoc3/helpers/rendering.rb +15 -8
- data/lib/nanoc3/helpers/tagging.rb +27 -21
- data/lib/nanoc3/helpers/text.rb +12 -8
- data/lib/nanoc3/helpers/xml_sitemap.rb +13 -15
- data/lib/nanoc3/tasks/deploy/rsync.rake +4 -1
- data/lib/nanoc3/tasks.rb +2 -1
- data/lib/nanoc3.rb +24 -1
- metadata +43 -87
- data/NEWS.rdoc +0 -328
- data/README.rdoc +0 -83
- data/lib/nanoc3/base/plugin.rb +0 -88
- data/lib/nanoc3/base/preprocessor_context.rb +0 -37
- data/lib/nanoc3/data_sources/filesystem_combined.rb +0 -214
- data/lib/nanoc3/data_sources/filesystem_common.rb +0 -22
- data/lib/nanoc3/data_sources/filesystem_compact.rb +0 -256
- data/lib/nanoc3/extra/context.rb +0 -24
- data/lib/nanoc3/package.rb +0 -107
- data/vendor/cri/ChangeLog +0 -0
- data/vendor/cri/LICENSE +0 -19
- data/vendor/cri/NEWS +0 -0
- data/vendor/cri/README +0 -4
- data/vendor/cri/Rakefile +0 -25
- data/vendor/cri/lib/cri/base.rb +0 -153
- data/vendor/cri/lib/cri/command.rb +0 -105
- data/vendor/cri/lib/cri/core_ext/string.rb +0 -41
- data/vendor/cri/lib/cri/core_ext.rb +0 -8
- data/vendor/cri/lib/cri/option_parser.rb +0 -186
- data/vendor/cri/lib/cri.rb +0 -12
- data/vendor/cri/test/test_base.rb +0 -6
- data/vendor/cri/test/test_command.rb +0 -6
- data/vendor/cri/test/test_core_ext.rb +0 -21
- data/vendor/cri/test/test_option_parser.rb +0 -279
@@ -4,38 +4,47 @@ require 'pstore'
|
|
4
4
|
|
5
5
|
module Nanoc3
|
6
6
|
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# Responsible for remembering dependencies between items. It is used to
|
8
|
+
# speed up compilation by only letting an item be recompiled when it is
|
9
|
+
# outdated or any of its dependencies (or dependencies’ dependencies, etc)
|
10
|
+
# is outdated.
|
11
11
|
#
|
12
12
|
# The dependencies tracked by the dependency tracker are not dependencies
|
13
|
-
# based on an item
|
13
|
+
# based on an item’s content. When one item uses an attribute of another
|
14
14
|
# item, then this is also treated as a dependency. While dependencies based
|
15
|
-
# on an item
|
15
|
+
# on an item’s content (handled in {Nanoc3::Compiler}) cannot be mutually
|
16
16
|
# recursive, the more general dependencies in Nanoc3::DependencyTracker can
|
17
17
|
# (e.g. item A can use an attribute of item B and vice versa without
|
18
18
|
# problems).
|
19
|
+
#
|
20
|
+
# The dependency tracker remembers the dependency information between runs.
|
21
|
+
# Dependency information is stored in the `tmp/dependencies` file. This file
|
22
|
+
# also contains a version number; when a dependencies file with an
|
23
|
+
# incompatible version is found, it is ignored.
|
19
24
|
class DependencyTracker
|
20
25
|
|
26
|
+
# @return [String] The name of the file in which dependency information is
|
27
|
+
# stored
|
21
28
|
attr_accessor :filename
|
22
29
|
|
23
|
-
#
|
24
|
-
|
25
|
-
# with, and it would not require an inverse graph to be maintained.
|
30
|
+
# The version of the file format used to store dependencies.
|
31
|
+
STORE_VERSION = 2
|
26
32
|
|
27
33
|
# Creates a new dependency tracker for the given items.
|
34
|
+
#
|
35
|
+
# @param [Array<Nanoc3::Item>] item The list of items whose dependencies
|
36
|
+
# should be managed
|
28
37
|
def initialize(items)
|
29
|
-
@items
|
30
|
-
|
31
|
-
@
|
32
|
-
|
33
|
-
@graph = {}
|
34
|
-
@inverse_graph = {}
|
38
|
+
@items = items
|
39
|
+
@filename = 'tmp/dependencies'
|
40
|
+
@graph = Nanoc3::DirectedGraph.new([ nil ] + @items)
|
41
|
+
@previous_items = []
|
35
42
|
end
|
36
43
|
|
37
|
-
# Starts listening for dependency messages (
|
38
|
-
#
|
44
|
+
# Starts listening for dependency messages (`:visit_started` and
|
45
|
+
# `:visit_ended`) and start recording dependencies.
|
46
|
+
#
|
47
|
+
# @return [void]
|
39
48
|
def start
|
40
49
|
# Initialize dependency stack. An item will be pushed onto this stack
|
41
50
|
# when it is visited. Therefore, an item on the stack always depends on
|
@@ -44,8 +53,11 @@ module Nanoc3
|
|
44
53
|
|
45
54
|
# Register start of visits
|
46
55
|
Nanoc3::NotificationCenter.on(:visit_started, self) do |item|
|
56
|
+
$stderr.puts "*** IN stack.size=#{@stack.size} item=#{item.inspect}" if $DEBUG
|
57
|
+
|
47
58
|
# Record possible dependency
|
48
59
|
unless @stack.empty?
|
60
|
+
$stderr.puts "*** Recording dependency #{@stack[-1].inspect} -> #{item.inspect}" if $DEBUG
|
49
61
|
self.record_dependency(@stack[-1], item)
|
50
62
|
end
|
51
63
|
|
@@ -54,236 +66,199 @@ module Nanoc3
|
|
54
66
|
|
55
67
|
# Register end of visits
|
56
68
|
Nanoc3::NotificationCenter.on(:visit_ended, self) do |item|
|
69
|
+
$stderr.puts "*** OUT stack.size=#{@stack.size} item=#{item.inspect}" if $DEBUG
|
70
|
+
|
57
71
|
@stack.pop
|
58
72
|
end
|
59
73
|
end
|
60
74
|
|
61
75
|
# Stop listening for dependency messages and stop recording dependencies.
|
76
|
+
#
|
77
|
+
# @return [void]
|
62
78
|
def stop
|
63
79
|
# Unregister
|
64
80
|
Nanoc3::NotificationCenter.remove(:visit_started, self)
|
65
81
|
Nanoc3::NotificationCenter.remove(:visit_ended, self)
|
66
82
|
end
|
67
83
|
|
68
|
-
# Returns the direct dependencies for
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
|
73
|
-
|
84
|
+
# Returns the direct dependencies for `item`.
|
85
|
+
#
|
86
|
+
# The direct dependencies of `item` include the items that, when outdated
|
87
|
+
# will cause `item` to be marked as outdated. Indirect dependencies will
|
88
|
+
# not be returned (e.g. if A depends on B which depends on C, then the
|
89
|
+
# direct dependencies of A do not include C).
|
90
|
+
#
|
91
|
+
# @param [Nanoc3::Item] item The item for which to fetch the direct
|
92
|
+
# predecessors
|
93
|
+
#
|
94
|
+
# @return [Array<Nanoc3::Item>] The direct predecessors of the given item
|
95
|
+
def direct_predecessors_of(item)
|
96
|
+
@graph.direct_predecessors_of(item).compact
|
74
97
|
end
|
75
98
|
|
76
|
-
# Returns all dependencies (direct and indirect) for
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
99
|
+
# Returns all dependencies (direct and indirect) for `item`.
|
100
|
+
#
|
101
|
+
# The dependencies of `item` include the items that, when outdated, will
|
102
|
+
# cause `item` to be marked as outdated.
|
103
|
+
#
|
104
|
+
# @param [Nanoc3::Item] item The item for which to fetch all direct and
|
105
|
+
# indirect predecessors
|
106
|
+
#
|
107
|
+
# @return [Array<Nanoc3::Item>] The predecessors of the given item
|
108
|
+
def predecessors_of(item)
|
109
|
+
@graph.predecessors_of(item).compact
|
85
110
|
end
|
86
111
|
|
87
|
-
# Returns the direct inverse dependencies for
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
|
92
|
-
|
112
|
+
# Returns the direct inverse dependencies for `item`.
|
113
|
+
#
|
114
|
+
# The direct inverse dependencies of `item` include the items that will be
|
115
|
+
# marked as outdated when`+item` is outdated. Indirect dependencies will
|
116
|
+
# not be returned (e.g. if A depends on B which depends on C, then the
|
117
|
+
# direct inverse dependencies of C do not include A).
|
118
|
+
#
|
119
|
+
# @param [Nanoc3::Item] item The item for which to fetch the direct
|
120
|
+
# successors
|
121
|
+
#
|
122
|
+
# @return [Array<Nanoc3::Item>] The direct successors of the given item
|
123
|
+
def direct_successors_of(item)
|
124
|
+
@graph.direct_successors_of(item).compact
|
93
125
|
end
|
94
126
|
|
95
|
-
# Returns all inverse dependencies (direct and indirect) for
|
96
|
-
#
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
# Get next unchecked dependency
|
107
|
-
dependency = pending_direct_dependencies.shift
|
108
|
-
next if checked_direct_dependencies.include?(dependency)
|
109
|
-
|
110
|
-
# Add dependencies of this unchecked dependency
|
111
|
-
pending_direct_dependencies += direct_inverse_dependencies_for(dependency)
|
112
|
-
|
113
|
-
# Mark this dependency as handled
|
114
|
-
all_dependencies << dependency
|
115
|
-
checked_direct_dependencies << dependency
|
116
|
-
end
|
117
|
-
|
118
|
-
all_dependencies
|
127
|
+
# Returns all inverse dependencies (direct and indirect) for `item`.
|
128
|
+
#
|
129
|
+
# The inverse dependencies of `item` include the items that will be marked
|
130
|
+
# as outdated when `item` is outdated.
|
131
|
+
#
|
132
|
+
# @param [Nanoc3::Item] item The item for which to fetch all direct and
|
133
|
+
# indirect successors
|
134
|
+
#
|
135
|
+
# @return [Array<Nanoc3::Item>] The successors of the given item
|
136
|
+
def successors_of(item)
|
137
|
+
@graph.successors_of(item).compact
|
119
138
|
end
|
120
139
|
|
121
|
-
# Records a dependency from
|
122
|
-
#
|
140
|
+
# Records a dependency from `src` to `dst` in the dependency graph. When
|
141
|
+
# `dst` is oudated, `src` will also become outdated.
|
142
|
+
#
|
143
|
+
# @param [Nanoc3::Item] src The source of the dependency, i.e. the item
|
144
|
+
# that will become outdated if dst is outdated
|
145
|
+
#
|
146
|
+
# @param [Nanoc3::Item] dst The destination of the dependency, i.e. the
|
147
|
+
# item that will cause the source to become outdated if the destination
|
148
|
+
# is outdated
|
149
|
+
#
|
150
|
+
# @return [void]
|
123
151
|
def record_dependency(src, dst)
|
124
|
-
#
|
125
|
-
@graph
|
126
|
-
|
127
|
-
# Don't include self or doubles in dependencies
|
128
|
-
return if src == dst
|
129
|
-
return if @graph[src].include?(dst)
|
130
|
-
|
131
|
-
# Record dependency
|
132
|
-
invalidate_inverted_graph
|
133
|
-
@graph[src] << dst
|
152
|
+
# Warning! dst and src are *reversed* here!
|
153
|
+
@graph.add_edge(dst, src) unless src == dst
|
134
154
|
end
|
135
155
|
|
136
|
-
# Stores the dependency graph into the file specified by the
|
156
|
+
# Stores the dependency graph into the file specified by the {#filename}
|
137
157
|
# attribute.
|
158
|
+
#
|
159
|
+
# @return [void]
|
138
160
|
def store_graph
|
139
|
-
# Create dir
|
140
161
|
FileUtils.mkdir_p(File.dirname(self.filename))
|
141
|
-
|
142
|
-
# Complete the graph
|
143
|
-
complete_graph
|
144
|
-
|
145
|
-
# Convert graph of items into graph of item identifiers
|
146
|
-
new_graph = {}
|
147
|
-
@graph.each_pair do |second_item, first_items|
|
148
|
-
# Don't store nil because that would be pointless (if first_item is
|
149
|
-
# outdated, something that does not exist is also outdated… makes no
|
150
|
-
# sense).
|
151
|
-
# FIXME can second_item really be nil?
|
152
|
-
next if second_item.nil?
|
153
|
-
|
154
|
-
new_graph[second_item.identifier] = first_items.map { |f| f && f.identifier }.compact
|
155
|
-
end
|
156
|
-
|
157
|
-
# Store dependencies
|
158
162
|
store = PStore.new(self.filename)
|
159
163
|
store.transaction do
|
160
|
-
store[:
|
164
|
+
store[:version] = STORE_VERSION
|
165
|
+
store[:vertices] = @graph.vertices.map { |i| i && i.identifier }
|
166
|
+
store[:edges] = @graph.edges
|
161
167
|
end
|
162
168
|
end
|
163
169
|
|
164
|
-
# Loads the dependency graph from the file specified by the
|
170
|
+
# Loads the dependency graph from the file specified by the {#filename}
|
165
171
|
# attribute. This method will overwrite an existing dependency graph.
|
172
|
+
#
|
173
|
+
# @return [void]
|
166
174
|
def load_graph
|
167
175
|
# Create new graph
|
168
|
-
@graph =
|
176
|
+
@graph = Nanoc3::DirectedGraph.new([ nil ] + @items)
|
169
177
|
|
170
|
-
#
|
178
|
+
# Get store
|
171
179
|
return if !File.file?(self.filename)
|
180
|
+
store = PStore.new(self.filename)
|
172
181
|
|
173
182
|
# Load dependencies
|
174
|
-
store = PStore.new(self.filename)
|
175
183
|
store.transaction do
|
176
|
-
#
|
177
|
-
store[:
|
178
|
-
|
179
|
-
|
180
|
-
|
184
|
+
# Verify version
|
185
|
+
return if store[:version] != STORE_VERSION
|
186
|
+
|
187
|
+
# Load vertices
|
188
|
+
@previous_items = store[:vertices].map do |v|
|
189
|
+
@items.find { |i| i.identifier == v }
|
190
|
+
end
|
181
191
|
|
182
|
-
|
192
|
+
# Load edges
|
193
|
+
store[:edges].each do |edge|
|
194
|
+
from_index, to_index = *edge
|
195
|
+
from, to = @previous_items[from_index], @previous_items[to_index]
|
196
|
+
@graph.add_edge(from, to)
|
183
197
|
end
|
184
198
|
end
|
185
199
|
end
|
186
200
|
|
187
201
|
# Traverses the dependency graph and marks all items that (directly or
|
188
202
|
# indirectly) depend on an outdated item as outdated.
|
203
|
+
#
|
204
|
+
# @return [void]
|
189
205
|
def mark_outdated_items
|
190
206
|
# Unmark everything
|
191
|
-
@items.each { |i| i.
|
192
|
-
|
193
|
-
# Mark
|
194
|
-
added_items = @items - @
|
195
|
-
added_items.each { |i| i.
|
196
|
-
|
197
|
-
#
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
if first_item.nil? || # item was removed
|
208
|
-
first_item.outdated? || # item itself is outdated
|
209
|
-
first_item.dependencies_outdated? # item is outdated because of its dependencies
|
210
|
-
second_items.each do |item|
|
211
|
-
# Ignore this item
|
212
|
-
next if item.nil?
|
213
|
-
|
214
|
-
something_changed = true if !item.dependencies_outdated?
|
215
|
-
item.dependencies_outdated = true
|
216
|
-
end
|
217
|
-
end
|
207
|
+
@items.each { |i| i.outdated_due_to_dependencies = false }
|
208
|
+
|
209
|
+
# Mark new items as outdated
|
210
|
+
added_items = @items - @previous_items
|
211
|
+
added_items.each { |i| i.outdated_due_to_dependencies = true }
|
212
|
+
|
213
|
+
# Mark successors of nil as outdated
|
214
|
+
self.successors_of(nil).each do |i|
|
215
|
+
i.outdated_due_to_dependencies = true
|
216
|
+
end
|
217
|
+
|
218
|
+
# For each outdated item...
|
219
|
+
@items.select { |i| i.outdated? }.each do |outdated_item|
|
220
|
+
# ... mark all its successors as outdated
|
221
|
+
self.successors_of(outdated_item).each do |i|
|
222
|
+
i.outdated_due_to_dependencies = true
|
218
223
|
end
|
219
224
|
end
|
220
225
|
end
|
221
226
|
|
222
227
|
# Empties the list of dependencies for the given item. This is necessary
|
223
228
|
# before recompiling the given item, because otherwise old dependencies
|
224
|
-
# will stick around and new dependencies will appear twice.
|
229
|
+
# will stick around and new dependencies will appear twice. This function
|
230
|
+
# removes all incoming edges for the given vertex.
|
231
|
+
#
|
232
|
+
# @param [Nanoc3::Item] item The item for which to forget all dependencies
|
233
|
+
#
|
234
|
+
# @return [void]
|
225
235
|
def forget_dependencies_for(item)
|
226
|
-
@graph
|
227
|
-
|
228
|
-
|
229
|
-
private
|
230
|
-
|
231
|
-
# Returns the item with the given identifier, or nil if no item is found.
|
232
|
-
def item_with_identifier(identifier)
|
233
|
-
@items.find { |i| i.identifier == identifier }
|
234
|
-
end
|
235
|
-
|
236
|
-
# Returns the inverted dependency graph, creating it first if it does not
|
237
|
-
# exist yet or is outdated. In this graph, the keys will be outdated when
|
238
|
-
# any of the values are outdated.
|
239
|
-
def inverted_graph
|
240
|
-
@inverted_graph ||= invert_graph(@graph)
|
241
|
-
end
|
242
|
-
|
243
|
-
# Marks the inverted graph as outdated so that it will be regenerated the
|
244
|
-
# next time it is used.
|
245
|
-
def invalidate_inverted_graph
|
246
|
-
@inverted_graph = nil
|
236
|
+
@graph.vertices.each do |v|
|
237
|
+
@graph.remove_edge(v, item)
|
238
|
+
end
|
247
239
|
end
|
248
240
|
|
249
|
-
#
|
250
|
-
#
|
251
|
-
# For example, this graph
|
252
|
-
#
|
253
|
-
# {
|
254
|
-
# :a => [ :b, :c ],
|
255
|
-
# :b => [ :x, :c ]
|
256
|
-
# }
|
257
|
-
#
|
258
|
-
# is turned into
|
241
|
+
# Prints the dependency graph in human-readable form.
|
259
242
|
#
|
260
|
-
#
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
graph.each_pair do |key, values|
|
269
|
-
values.each do |v|
|
270
|
-
inverted_graph[v] ||= []
|
271
|
-
inverted_graph[v] << key
|
243
|
+
# @return [void]
|
244
|
+
def print_graph
|
245
|
+
@items.each do |item|
|
246
|
+
puts "#{item.inspect} depends on:"
|
247
|
+
|
248
|
+
predecessors = direct_predecessors_of(item)
|
249
|
+
predecessors.each do |pred|
|
250
|
+
puts " #{pred.inspect}"
|
272
251
|
end
|
252
|
+
puts " (nothing!)" if predecessors.empty?
|
253
|
+
puts
|
273
254
|
end
|
274
|
-
|
275
|
-
inverted_graph
|
276
255
|
end
|
277
256
|
|
278
|
-
|
279
|
-
# dependecies, even if it is empty. Items without a list of dependencies
|
280
|
-
# will be treated as "added" and will depend on all other pages, which is
|
281
|
-
# not necessary for non-added items.
|
282
|
-
def complete_graph
|
283
|
-
@items.each do |item|
|
284
|
-
@graph[item] ||= []
|
285
|
-
end
|
257
|
+
private
|
286
258
|
|
259
|
+
# Returns the item with the given identifier, or nil if no item is found.
|
260
|
+
def item_with_identifier(identifier)
|
261
|
+
@items.find { |i| i.identifier == identifier }
|
287
262
|
end
|
288
263
|
|
289
264
|
end
|