nanoc3 3.2.0a1 → 3.2.0a2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +2 -2
- data/NEWS.md +14 -0
- data/README.md +20 -12
- data/doc/yardoc_templates/default/layout/html/footer.erb +10 -0
- data/lib/nanoc3/base/compilation/checksum_store.rb +130 -0
- data/lib/nanoc3/base/compilation/checksummer.rb +68 -0
- data/lib/nanoc3/base/compilation/compiled_content_cache.rb +57 -0
- data/lib/nanoc3/base/{compiler.rb → compilation/compiler.rb} +255 -55
- data/lib/nanoc3/base/{compiler_dsl.rb → compilation/compiler_dsl.rb} +11 -6
- data/lib/nanoc3/base/{dependency_tracker.rb → compilation/dependency_tracker.rb} +62 -92
- data/lib/nanoc3/base/{filter.rb → compilation/filter.rb} +0 -0
- data/lib/nanoc3/base/compilation/item_rep_proxy.rb +87 -0
- data/lib/nanoc3/base/compilation/outdatedness_checker.rb +86 -0
- data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +43 -0
- data/lib/nanoc3/base/{rule.rb → compilation/rule.rb} +8 -2
- data/lib/nanoc3/base/{rule_context.rb → compilation/rule_context.rb} +17 -14
- data/lib/nanoc3/base/directed_graph.rb +8 -0
- data/lib/nanoc3/base/errors.rb +9 -17
- data/lib/nanoc3/base/plugin_registry.rb +1 -1
- data/lib/nanoc3/base/result_data/item_rep.rb +447 -0
- data/lib/nanoc3/base/{code_snippet.rb → source_data/code_snippet.rb} +7 -22
- data/lib/nanoc3/base/{data_source.rb → source_data/data_source.rb} +0 -0
- data/lib/nanoc3/base/{item.rb → source_data/item.rb} +20 -30
- data/lib/nanoc3/base/{layout.rb → source_data/layout.rb} +7 -26
- data/lib/nanoc3/base/source_data/site.rb +314 -0
- data/lib/nanoc3/base/store.rb +126 -0
- data/lib/nanoc3/base.rb +26 -15
- data/lib/nanoc3/cli/base.rb +2 -1
- data/lib/nanoc3/cli/commands/compile.rb +116 -48
- data/lib/nanoc3/cli/commands/create_item.rb +0 -1
- data/lib/nanoc3/cli/commands/create_layout.rb +0 -1
- data/lib/nanoc3/cli/commands/create_site.rb +11 -1
- data/lib/nanoc3/cli/commands/debug.rb +11 -6
- data/lib/nanoc3/cli/commands/info.rb +1 -2
- data/lib/nanoc3/cli/commands/update.rb +0 -1
- data/lib/nanoc3/cli/commands/watch.rb +27 -32
- data/lib/nanoc3/cli/logger.rb +2 -2
- data/lib/nanoc3/data_sources/filesystem.rb +1 -6
- data/lib/nanoc3/extra/auto_compiler.rb +2 -3
- data/lib/nanoc3/extra/deployers/rsync.rb +1 -0
- data/lib/nanoc3/extra/validators/links.rb +45 -26
- data/lib/nanoc3/filters/asciidoc.rb +58 -0
- data/lib/nanoc3/filters/colorize_syntax.rb +47 -9
- data/lib/nanoc3/filters/less.rb +6 -0
- data/lib/nanoc3/filters/sass.rb +8 -5
- data/lib/nanoc3/filters.rb +2 -0
- data/lib/nanoc3/helpers/blogging.rb +8 -0
- data/lib/nanoc3/helpers/html_escape.rb +37 -7
- data/lib/nanoc3/helpers/link_to.rb +15 -4
- data/lib/nanoc3/helpers/rendering.rb +6 -2
- data/lib/nanoc3/tasks/clean.rb +0 -4
- data/lib/nanoc3.rb +1 -1
- data/nanoc3.gemspec +42 -0
- metadata +35 -19
- data/lib/nanoc3/base/checksummer.rb +0 -40
- data/lib/nanoc3/base/compiled_content_cache.rb +0 -86
- data/lib/nanoc3/base/item_rep.rb +0 -537
- data/lib/nanoc3/base/site.rb +0 -490
@@ -21,29 +21,28 @@ module Nanoc3
|
|
21
21
|
# Dependency information is stored in the `tmp/dependencies` file. This file
|
22
22
|
# also contains a version number; when a dependencies file with an
|
23
23
|
# incompatible version is found, it is ignored.
|
24
|
-
class DependencyTracker
|
25
|
-
|
26
|
-
# @return [String] The name of the file in which dependency information is
|
27
|
-
# stored
|
28
|
-
attr_accessor :filename
|
24
|
+
class DependencyTracker < ::Nanoc3::Store
|
29
25
|
|
30
26
|
# @return [Array<Nanoc3::Item, Nanoc3::Layout>] The list of items and
|
31
27
|
# layouts that are being tracked by the dependency tracker
|
32
28
|
attr_reader :objects
|
33
29
|
|
34
|
-
#
|
35
|
-
|
30
|
+
# @return [Nanoc3::Compiler] The compiler that corresponds to this
|
31
|
+
# dependency tracker
|
32
|
+
attr_accessor :compiler
|
36
33
|
|
37
34
|
# Creates a new dependency tracker for the given items and layouts.
|
38
35
|
#
|
39
36
|
# @param [Array<Nanoc3::Item, Nanoc3::Layout>] objects The list of items
|
40
37
|
# and layouts whose dependencies should be managed
|
41
38
|
def initialize(objects)
|
39
|
+
super('tmp/dependencies', 4)
|
40
|
+
|
42
41
|
@objects = objects
|
43
42
|
|
44
|
-
@
|
45
|
-
@graph = Nanoc3::DirectedGraph.new([ nil ] + @objects)
|
43
|
+
@graph = Nanoc3::DirectedGraph.new([ nil ] + @objects)
|
46
44
|
@previous_objects = []
|
45
|
+
@objects_outdated_due_to_dependencies = Set.new
|
47
46
|
end
|
48
47
|
|
49
48
|
# Starts listening for dependency messages (`:visit_started` and
|
@@ -77,6 +76,18 @@ module Nanoc3
|
|
77
76
|
Nanoc3::NotificationCenter.remove(:visit_ended, self)
|
78
77
|
end
|
79
78
|
|
79
|
+
# Checks whether the given object is outdated due to dependencies, i.e.
|
80
|
+
# check whether there are other objects that are outdated that cause this
|
81
|
+
# object to be outdated.
|
82
|
+
#
|
83
|
+
# @param [Nanoc3::Item, Nanoc3::Layout] obj The object to check
|
84
|
+
#
|
85
|
+
# @return [Boolean] true if the given object is outdated due to
|
86
|
+
# dependencies, false if not.
|
87
|
+
def outdated_due_to_dependencies?(obj)
|
88
|
+
@objects_outdated_due_to_dependencies.include?(obj)
|
89
|
+
end
|
90
|
+
|
80
91
|
# Returns the direct dependencies for the given object.
|
81
92
|
#
|
82
93
|
# The direct dependencies of the given object include the items
|
@@ -94,20 +105,6 @@ module Nanoc3
|
|
94
105
|
@graph.direct_predecessors_of(object).compact
|
95
106
|
end
|
96
107
|
|
97
|
-
# Returns all dependencies (direct and indirect) for the given object.
|
98
|
-
#
|
99
|
-
# The dependencies of given object include the objects that, when
|
100
|
-
# outdated, will cause the given object to be marked as outdated.
|
101
|
-
#
|
102
|
-
# @param [Nanoc3::Item, Nanoc3::Layout] object The object for which to
|
103
|
-
# fetch all direct and indirect predecessors
|
104
|
-
#
|
105
|
-
# @return [Array<Nanoc3::Item, Nanoc3::Layout>] The predecessors of the
|
106
|
-
# given object
|
107
|
-
def predecessors_of(object)
|
108
|
-
@graph.predecessors_of(object).compact
|
109
|
-
end
|
110
|
-
|
111
108
|
# Returns the direct inverse dependencies for the given object.
|
112
109
|
#
|
113
110
|
# The direct inverse dependencies of the given object include the objects
|
@@ -125,21 +122,6 @@ module Nanoc3
|
|
125
122
|
@graph.direct_successors_of(object).compact
|
126
123
|
end
|
127
124
|
|
128
|
-
# Returns all inverse dependencies (direct and indirect) for the given
|
129
|
-
# object.
|
130
|
-
#
|
131
|
-
# The inverse dependencies of the given object include the objects that
|
132
|
-
# will be marked as outdated when the given object is outdated.
|
133
|
-
#
|
134
|
-
# @param [Nanoc3::Item, Nanoc3::Layout] object The object for which to
|
135
|
-
# fetch all direct and indirect successors
|
136
|
-
#
|
137
|
-
# @return [Array<Nanoc3::Item, Nanoc3::Layout>] The successors of the
|
138
|
-
# given object
|
139
|
-
def successors_of(object)
|
140
|
-
@graph.successors_of(object).compact
|
141
|
-
end
|
142
|
-
|
143
125
|
# Records a dependency from `src` to `dst` in the dependency graph. When
|
144
126
|
# `dst` is oudated, `src` will also become outdated.
|
145
127
|
#
|
@@ -156,71 +138,21 @@ module Nanoc3
|
|
156
138
|
@graph.add_edge(dst, src) unless src == dst
|
157
139
|
end
|
158
140
|
|
159
|
-
# Stores the dependency graph into the file specified by the {#filename}
|
160
|
-
# attribute.
|
161
|
-
#
|
162
|
-
# @return [void]
|
163
|
-
def store_graph
|
164
|
-
FileUtils.mkdir_p(File.dirname(self.filename))
|
165
|
-
store = PStore.new(self.filename)
|
166
|
-
store.transaction do
|
167
|
-
store[:version] = STORE_VERSION
|
168
|
-
store[:vertices] = @graph.vertices.map { |obj| obj && obj.reference }
|
169
|
-
store[:edges] = @graph.edges
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
# Loads the dependency graph from the file specified by the {#filename}
|
174
|
-
# attribute. This method will overwrite an existing dependency graph.
|
175
|
-
#
|
176
|
-
# @return [void]
|
177
|
-
def load_graph
|
178
|
-
# Create new graph
|
179
|
-
@graph = Nanoc3::DirectedGraph.new([ nil ] + @objects)
|
180
|
-
|
181
|
-
# Get store
|
182
|
-
return if !File.file?(self.filename)
|
183
|
-
store = PStore.new(self.filename)
|
184
|
-
|
185
|
-
# Load dependencies
|
186
|
-
store.transaction do
|
187
|
-
# Verify version
|
188
|
-
return if store[:version] != STORE_VERSION
|
189
|
-
|
190
|
-
# Load vertices
|
191
|
-
@previous_objects = store[:vertices].map do |reference|
|
192
|
-
@objects.find { |obj| reference == obj.reference }
|
193
|
-
end
|
194
|
-
|
195
|
-
# Load edges
|
196
|
-
store[:edges].each do |edge|
|
197
|
-
from_index, to_index = *edge
|
198
|
-
from, to = @previous_objects[from_index], @previous_objects[to_index]
|
199
|
-
@graph.add_edge(from, to)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
141
|
# Traverses the dependency graph and marks all objects that (directly or
|
205
142
|
# indirectly) depend on an outdated object as outdated.
|
206
143
|
#
|
207
144
|
# @return [void]
|
208
145
|
def propagate_outdatedness
|
209
146
|
# Unmark everything
|
210
|
-
@
|
147
|
+
@objects_outdated_due_to_dependencies.clear
|
211
148
|
|
212
149
|
# Mark new objects as outdated
|
213
150
|
added_objects = @objects - @previous_objects
|
214
|
-
added_objects
|
215
|
-
|
216
|
-
# Mark successors of nil as outdated
|
217
|
-
self.successors_of(nil).each do |o|
|
218
|
-
o.outdated_due_to_dependencies = true
|
219
|
-
end
|
151
|
+
@objects_outdated_due_to_dependencies.merge(added_objects)
|
220
152
|
|
221
153
|
# Mark successors of outdated objects as outdated
|
222
154
|
require 'set'
|
223
|
-
unprocessed = @objects.select { |o|
|
155
|
+
unprocessed = [ nil ] + @objects.select { |o| compiler.outdated?(o) }
|
224
156
|
seen = Set.new(unprocessed)
|
225
157
|
until unprocessed.empty?
|
226
158
|
obj = unprocessed.shift
|
@@ -229,7 +161,7 @@ module Nanoc3
|
|
229
161
|
next if seen.include?(successor)
|
230
162
|
seen << successor
|
231
163
|
|
232
|
-
|
164
|
+
@objects_outdated_due_to_dependencies << successor
|
233
165
|
unprocessed << successor
|
234
166
|
end
|
235
167
|
end
|
@@ -240,6 +172,8 @@ module Nanoc3
|
|
240
172
|
# will stick around and new dependencies will appear twice. This function
|
241
173
|
# removes all incoming edges for the given vertex.
|
242
174
|
#
|
175
|
+
# @api private
|
176
|
+
#
|
243
177
|
# @param [Nanoc3::Item, Nanoc3::Layout] object The object for which to
|
244
178
|
# forget all dependencies
|
245
179
|
#
|
@@ -253,6 +187,42 @@ module Nanoc3
|
|
253
187
|
propagate_outdatedness
|
254
188
|
end
|
255
189
|
|
190
|
+
# @deprecated Use {#store} instead
|
191
|
+
def store_graph
|
192
|
+
self.store
|
193
|
+
end
|
194
|
+
|
195
|
+
# @deprecated Use {#load} instead
|
196
|
+
def load_graph
|
197
|
+
self.load
|
198
|
+
end
|
199
|
+
|
200
|
+
protected
|
201
|
+
|
202
|
+
def data
|
203
|
+
{
|
204
|
+
:edges => @graph.edges,
|
205
|
+
:vertices => @graph.vertices.map { |obj| obj && obj.reference }
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
def data=(new_data)
|
210
|
+
# Create new graph
|
211
|
+
@graph = Nanoc3::DirectedGraph.new([ nil ] + @objects)
|
212
|
+
|
213
|
+
# Load vertices
|
214
|
+
@previous_objects = new_data[:vertices].map do |reference|
|
215
|
+
@objects.find { |obj| reference == obj.reference }
|
216
|
+
end
|
217
|
+
|
218
|
+
# Load edges
|
219
|
+
new_data[:edges].each do |edge|
|
220
|
+
from_index, to_index = *edge
|
221
|
+
from, to = @previous_objects[from_index], @previous_objects[to_index]
|
222
|
+
@graph.add_edge(from, to)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
256
226
|
end
|
257
227
|
|
258
228
|
end
|
File without changes
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Nanoc3
|
6
|
+
|
7
|
+
# Represents an item representation, but provides an interface that is
|
8
|
+
# easier to use when writing compilation and routing rules. It is also
|
9
|
+
# responsible for fetching the necessary information from the compiler, such
|
10
|
+
# as assigns.
|
11
|
+
#
|
12
|
+
# The API provided by item representation proxies allows layout identifiers
|
13
|
+
# to be given as literals instead of as references to {Nanoc3::Layout}.
|
14
|
+
class ItemRepProxy
|
15
|
+
|
16
|
+
extend Forwardable
|
17
|
+
|
18
|
+
def_delegators :@item_rep, :item, :name, :binary, :binary?, :compiled_content, :has_snapshot?, :raw_path, :path
|
19
|
+
def_delegator :@item_rep, :snapshot
|
20
|
+
|
21
|
+
# @param [Nanoc3::ItemRep] item_rep The item representation that this
|
22
|
+
# proxy should behave like
|
23
|
+
#
|
24
|
+
# @param [Nanoc3::Compiler] compiler The compiler that will provide the
|
25
|
+
# necessary compilation-related functionality.
|
26
|
+
def initialize(item_rep, compiler)
|
27
|
+
@item_rep = item_rep
|
28
|
+
@compiler = compiler
|
29
|
+
end
|
30
|
+
|
31
|
+
# Runs the item content through the given filter with the given arguments.
|
32
|
+
# This method will replace the content of the `:last` snapshot with the
|
33
|
+
# filtered content of the last snapshot.
|
34
|
+
#
|
35
|
+
# This method is supposed to be called only in a compilation rule block
|
36
|
+
# (see {Nanoc3::CompilerDSL#compile}).
|
37
|
+
#
|
38
|
+
# @see Nanoc3::ItemRep#filter
|
39
|
+
#
|
40
|
+
# @param [Symbol] filter_name The name of the filter to run the item
|
41
|
+
# representations' content through
|
42
|
+
#
|
43
|
+
# @param [Hash] filter_args The filter arguments that should be passed to
|
44
|
+
# the filter's #run method
|
45
|
+
#
|
46
|
+
# @return [void]
|
47
|
+
def filter(name, args={})
|
48
|
+
set_assigns
|
49
|
+
@item_rep.filter(name, args)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Lays out the item using the given layout. This method will replace the
|
53
|
+
# content of the `:last` snapshot with the laid out content of the last
|
54
|
+
# snapshot.
|
55
|
+
#
|
56
|
+
# This method is supposed to be called only in a compilation rule block
|
57
|
+
# (see {Nanoc3::CompilerDSL#compile}).
|
58
|
+
#
|
59
|
+
# @see Nanoc3::ItemRep#layout
|
60
|
+
#
|
61
|
+
# @param [String] layout_identifier The identifier of the layout to use
|
62
|
+
#
|
63
|
+
# @return [void]
|
64
|
+
def layout(layout_identifier)
|
65
|
+
set_assigns
|
66
|
+
|
67
|
+
layout = layout_with_identifier(layout_identifier)
|
68
|
+
filter_name, filter_args = @compiler.filter_for_layout(layout)
|
69
|
+
|
70
|
+
@item_rep.layout(layout, filter_name, filter_args)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def set_assigns
|
76
|
+
@item_rep.assigns = @compiler.assigns_for(@item_rep)
|
77
|
+
end
|
78
|
+
|
79
|
+
def layout_with_identifier(layout_identifier)
|
80
|
+
layout ||= @compiler.site.layouts.find { |l| l.identifier == layout_identifier.cleaned_identifier }
|
81
|
+
raise Nanoc3::Errors::UnknownLayout.new(layout_identifier) if layout.nil?
|
82
|
+
layout
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc3
|
4
|
+
|
5
|
+
# Responsible for determining whether an item or a layout is outdated.
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class OutdatednessChecker
|
9
|
+
|
10
|
+
# @option params [Nanoc3::Site] :site (nil) The site this outdatedness
|
11
|
+
# checker belongs to.
|
12
|
+
#
|
13
|
+
# @option params [Nanoc3::ChecksumStore] :checksum_store (nil) The
|
14
|
+
# checksum store where checksums of items, layouts, … are stored.
|
15
|
+
def initialize(params={})
|
16
|
+
@site = params[:site] if params.has_key?(:site)
|
17
|
+
@checksum_store = params[:checksum_store] if params.has_key?(:checksum_store)
|
18
|
+
|
19
|
+
@outdatedness_reasons = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
# Checks whether the given object is outdated and therefore needs to be
|
23
|
+
# recompiled.
|
24
|
+
#
|
25
|
+
# @param [Nanoc3::Item, Nanoc3::ItemRep, Nanoc3::Layout] obj The object
|
26
|
+
# whose outdatedness should be checked.
|
27
|
+
#
|
28
|
+
# @return [Boolean] true if the object is outdated, false otherwise
|
29
|
+
def outdated?(obj)
|
30
|
+
!outdatedness_reason_for(obj).nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
# Calculates the reason why the given object is outdated.
|
34
|
+
#
|
35
|
+
# @param [Nanoc3::Item, Nanoc3::ItemRep, Nanoc3::Layout] obj The object
|
36
|
+
# whose outdatedness reason should be calculated.
|
37
|
+
#
|
38
|
+
# @return [Nanoc3::OutdatednessReasons::Generic, nil] The reason why the
|
39
|
+
# given object is outdated, or nil if the object is not outdated.
|
40
|
+
def outdatedness_reason_for(obj)
|
41
|
+
case obj.type
|
42
|
+
when :item_rep
|
43
|
+
# Outdated if checksums are missing or different
|
44
|
+
return Nanoc3::OutdatednessReasons::NotEnoughData if !checksum_store.checksums_available?(obj.item)
|
45
|
+
return Nanoc3::OutdatednessReasons::SourceModified if !checksum_store.checksums_identical?(obj.item)
|
46
|
+
|
47
|
+
# Outdated if compiled file doesn't exist (yet)
|
48
|
+
return Nanoc3::OutdatednessReasons::NotWritten if obj.raw_path && !File.file?(obj.raw_path)
|
49
|
+
|
50
|
+
# Outdated if code snippets outdated
|
51
|
+
return Nanoc3::OutdatednessReasons::CodeSnippetsModified if @site.code_snippets.any? do |cs|
|
52
|
+
checksum_store.object_modified?(cs)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Outdated if configuration outdated
|
56
|
+
return Nanoc3::OutdatednessReasons::ConfigurationModified if checksum_store.object_modified?(@site.config)
|
57
|
+
|
58
|
+
# Outdated if rules outdated
|
59
|
+
return Nanoc3::OutdatednessReasons::RulesModified if checksum_store.object_modified?(@site.compiler.rules_with_reference)
|
60
|
+
|
61
|
+
# Not outdated
|
62
|
+
return nil
|
63
|
+
when :item
|
64
|
+
obj.reps.find { |rep| outdatedness_reason_for(rep) }
|
65
|
+
when :layout
|
66
|
+
# Outdated if checksums are missing or different
|
67
|
+
return Nanoc3::OutdatednessReasons::NotEnoughData if !checksum_store.checksums_available?(obj)
|
68
|
+
return Nanoc3::OutdatednessReasons::SourceModified if !checksum_store.checksums_identical?(obj)
|
69
|
+
|
70
|
+
# Not outdated
|
71
|
+
return nil
|
72
|
+
else
|
73
|
+
raise RuntimeError, "do not know how to check outdatedness of #{obj.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# @return [Nanoc3::ChecksumStore] The checksum store
|
80
|
+
def checksum_store
|
81
|
+
@checksum_store
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc3
|
4
|
+
|
5
|
+
# Module that contains all outdatedness reasons.
|
6
|
+
module OutdatednessReasons
|
7
|
+
|
8
|
+
# A generic outdatedness reason. An outdatedness reason is basically a
|
9
|
+
# descriptive message that explains why a given object is outdated.
|
10
|
+
class Generic
|
11
|
+
|
12
|
+
# @return [String] A descriptive message for this outdatedness reason
|
13
|
+
attr_reader :message
|
14
|
+
|
15
|
+
# @param [String] message The descriptive message for this outdatedness
|
16
|
+
# reason
|
17
|
+
def initialize(message)
|
18
|
+
@message = message
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
NotEnoughData = Generic.new(
|
24
|
+
'Not enough data is present to correctly determine whether the item is outdated.')
|
25
|
+
|
26
|
+
NotWritten = Generic.new(
|
27
|
+
'This item representation has not yet been written to the output directory (but it does have a path).')
|
28
|
+
|
29
|
+
SourceModified = Generic.new(
|
30
|
+
'The source file of this item has been modified since the last time the site was compiled.')
|
31
|
+
|
32
|
+
CodeSnippetsModified = Generic.new(
|
33
|
+
'The code snippets have been modified since the last time the site was compiled.')
|
34
|
+
|
35
|
+
ConfigurationModified = Generic.new(
|
36
|
+
'The site configuration has been modified since the last time the site was compiled.')
|
37
|
+
|
38
|
+
RulesModified = Generic.new(
|
39
|
+
'The rules file has been modified since the last time the site was compiled.')
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -55,9 +55,15 @@ module Nanoc3
|
|
55
55
|
# @param [Nanoc3::ItemRep] rep The item representation where this rule
|
56
56
|
# should be applied to
|
57
57
|
#
|
58
|
+
# @option params [Nanoc3::Compiler] :compiler The compiler
|
59
|
+
#
|
60
|
+
# @raise [ArgumentError] if no compiler is passed
|
61
|
+
#
|
58
62
|
# @return [void]
|
59
|
-
def apply_to(rep)
|
60
|
-
|
63
|
+
def apply_to(rep, params={})
|
64
|
+
compiler = params[:compiler] or raise ArgumentError, "Required :compiler option is missing"
|
65
|
+
rep = Nanoc3::ItemRepProxy.new(rep, compiler)
|
66
|
+
Nanoc3::RuleContext.new(:rep => rep, :compiler => compiler).instance_eval &@block
|
61
67
|
end
|
62
68
|
|
63
69
|
end
|
@@ -12,26 +12,29 @@ module Nanoc3
|
|
12
12
|
# * `config` ({Hash}) - The site configuration
|
13
13
|
# * `items` ({Array}<{Nanoc3::Item}>) - A list of all items
|
14
14
|
# * `layouts` ({Array}<{Nanoc3::Layout}>) - A list of all layouts
|
15
|
+
#
|
16
|
+
# @api private
|
15
17
|
class RuleContext < Context
|
16
18
|
|
17
|
-
#
|
19
|
+
# @option params [Nanoc3::ItemRep] :rep The item representation that will
|
20
|
+
# be processed in this rule context
|
21
|
+
#
|
22
|
+
# @option params [Nanoc3::Compiler] :compiler The compiler that is being
|
23
|
+
# used to compile the site
|
18
24
|
#
|
19
|
-
# @
|
20
|
-
#
|
21
|
-
def initialize(
|
22
|
-
|
23
|
-
|
24
|
-
config = site.config
|
25
|
-
items = site.items
|
26
|
-
layouts = site.layouts
|
25
|
+
# @raise [ArgumentError] if the `:rep` or the `:compiler` option is
|
26
|
+
# missing
|
27
|
+
def initialize(params={})
|
28
|
+
rep = params[:rep] or raise ArgumentError, "Required :rep option is missing"
|
29
|
+
compiler = params[:compiler] or raise ArgumentError, "Required :compiler option is missing"
|
27
30
|
|
28
31
|
super({
|
29
32
|
:rep => rep,
|
30
|
-
:item => item,
|
31
|
-
:site => site,
|
32
|
-
:config => config,
|
33
|
-
:items => items,
|
34
|
-
:layouts => layouts
|
33
|
+
:item => rep.item,
|
34
|
+
:site => compiler.site,
|
35
|
+
:config => compiler.site.config,
|
36
|
+
:items => compiler.site.items,
|
37
|
+
:layouts => compiler.site.layouts
|
35
38
|
})
|
36
39
|
end
|
37
40
|
|
@@ -38,6 +38,8 @@ module Nanoc3
|
|
38
38
|
# @return [Array]
|
39
39
|
attr_reader :vertices
|
40
40
|
|
41
|
+
# @group Creating a graph
|
42
|
+
|
41
43
|
# Creates a new directed graph with the given vertices.
|
42
44
|
def initialize(vertices)
|
43
45
|
@vertices = vertices
|
@@ -55,6 +57,8 @@ module Nanoc3
|
|
55
57
|
invalidate_caches
|
56
58
|
end
|
57
59
|
|
60
|
+
# @group Modifying the graph
|
61
|
+
|
58
62
|
# Adds an edge from the first vertex to the second vertex.
|
59
63
|
#
|
60
64
|
# @param from Vertex where the edge should start
|
@@ -149,6 +153,8 @@ module Nanoc3
|
|
149
153
|
@roots.delete(v)
|
150
154
|
end
|
151
155
|
|
156
|
+
# @group Querying the graph
|
157
|
+
|
152
158
|
# Returns the direct predecessors of the given vertex, i.e. the vertices
|
153
159
|
# x where there is an edge from x to the given vertex y.
|
154
160
|
#
|
@@ -210,6 +216,8 @@ module Nanoc3
|
|
210
216
|
@roots
|
211
217
|
end
|
212
218
|
|
219
|
+
# @group Deprecated methods
|
220
|
+
|
213
221
|
# @deprecated Use {#delete_edge} instead
|
214
222
|
def remove_edge(from, to)
|
215
223
|
delete_edge(from, to)
|
data/lib/nanoc3/base/errors.rb
CHANGED
@@ -58,23 +58,6 @@ module Nanoc3
|
|
58
58
|
|
59
59
|
end
|
60
60
|
|
61
|
-
# Error that is raised when data is requested when the data is not yet
|
62
|
-
# available (possibly due to a missing {Nanoc3::Site#load_data}).
|
63
|
-
class DataNotYetAvailable < Generic
|
64
|
-
|
65
|
-
# @param [String] type The name of the data type that is not yet
|
66
|
-
# available. For example: `"site"`, `"items"`.
|
67
|
-
#
|
68
|
-
# @param [Boolean] plural True if the given type is plural, false
|
69
|
-
# otherwise. This only has an effect on the exception message. For
|
70
|
-
# example, if the given type is `"site"`, plural would be `false`; if
|
71
|
-
# the given type is `"items"`, plural would be `true`.
|
72
|
-
def initialize(type, plural)
|
73
|
-
super("#{type} #{plural ? 'are' : 'is'} not available yet. You may be missing a Nanoc3::Site#load_data call.".make_compatible_with_env)
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
61
|
# Error that is raised during site compilation when an item (directly or
|
79
62
|
# indirectly) includes its own item content, leading to endless recursion.
|
80
63
|
class RecursiveCompilation < Generic
|
@@ -181,6 +164,15 @@ module Nanoc3
|
|
181
164
|
class InternalConsistency < Generic
|
182
165
|
end
|
183
166
|
|
167
|
+
# @deprecated No longer necessary, but kept for backwards compatibility.
|
168
|
+
class DataNotYetAvailable < Generic
|
169
|
+
|
170
|
+
def initialize(type, plural)
|
171
|
+
super("#{type} #{plural ? 'are' : 'is'} not available yet. You may be missing a Nanoc3::Site#load_data call.".make_compatible_with_env)
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
184
176
|
end
|
185
177
|
|
186
178
|
end
|