nanoc3 3.1.9 → 3.2.0a1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/LICENSE +1 -1
  2. data/NEWS.md +0 -50
  3. data/README.md +3 -15
  4. data/bin/nanoc3 +2 -0
  5. data/lib/nanoc3/base/checksummer.rb +40 -0
  6. data/lib/nanoc3/base/code_snippet.rb +30 -12
  7. data/lib/nanoc3/base/compiled_content_cache.rb +86 -0
  8. data/lib/nanoc3/base/compiler.rb +134 -95
  9. data/lib/nanoc3/base/compiler_dsl.rb +12 -11
  10. data/lib/nanoc3/base/core_ext/string.rb +2 -2
  11. data/lib/nanoc3/base/data_source.rb +17 -16
  12. data/lib/nanoc3/base/dependency_tracker.rb +102 -121
  13. data/lib/nanoc3/base/directed_graph.rb +65 -3
  14. data/lib/nanoc3/base/errors.rb +20 -16
  15. data/lib/nanoc3/base/item.rb +58 -50
  16. data/lib/nanoc3/base/item_rep.rb +177 -150
  17. data/lib/nanoc3/base/layout.rb +51 -18
  18. data/lib/nanoc3/base/notification_center.rb +8 -8
  19. data/lib/nanoc3/base/plugin_registry.rb +9 -9
  20. data/lib/nanoc3/base/rule.rb +18 -9
  21. data/lib/nanoc3/base/rule_context.rb +5 -5
  22. data/lib/nanoc3/base/site.rb +135 -47
  23. data/lib/nanoc3/base.rb +21 -19
  24. data/lib/nanoc3/cli/base.rb +51 -74
  25. data/lib/nanoc3/cli/commands/autocompile.rb +3 -0
  26. data/lib/nanoc3/cli/commands/compile.rb +35 -74
  27. data/lib/nanoc3/cli/commands/create_site.rb +17 -5
  28. data/lib/nanoc3/cli/commands/debug.rb +11 -4
  29. data/lib/nanoc3/cli/commands/view.rb +0 -1
  30. data/lib/nanoc3/cli/commands/watch.rb +148 -0
  31. data/lib/nanoc3/cli/commands.rb +1 -0
  32. data/lib/nanoc3/cli/logger.rb +15 -21
  33. data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -1
  34. data/lib/nanoc3/data_sources/filesystem.rb +11 -40
  35. data/lib/nanoc3/data_sources/filesystem_unified.rb +22 -22
  36. data/lib/nanoc3/extra/auto_compiler.rb +1 -1
  37. data/lib/nanoc3/extra/chick.rb +8 -8
  38. data/lib/nanoc3/extra/deployers/rsync.rb +2 -3
  39. data/lib/nanoc3/extra/validators/links.rb +32 -51
  40. data/lib/nanoc3/extra/validators/w3c.rb +2 -2
  41. data/lib/nanoc3/extra/vcs.rb +1 -1
  42. data/lib/nanoc3/filters/colorize_syntax.rb +15 -19
  43. data/lib/nanoc3/filters/erb.rb +1 -5
  44. data/lib/nanoc3/filters/erubis.rb +1 -5
  45. data/lib/nanoc3/filters/haml.rb +1 -2
  46. data/lib/nanoc3/filters/less.rb +2 -51
  47. data/lib/nanoc3/filters/mustache.rb +21 -0
  48. data/lib/nanoc3/filters/rdiscount.rb +1 -2
  49. data/lib/nanoc3/filters/relativize_paths.rb +3 -2
  50. data/lib/nanoc3/filters/sass.rb +50 -56
  51. data/lib/nanoc3/filters.rb +2 -0
  52. data/lib/nanoc3/helpers/blogging.rb +22 -29
  53. data/lib/nanoc3/helpers/breadcrumbs.rb +1 -1
  54. data/lib/nanoc3/helpers/capturing.rb +1 -1
  55. data/lib/nanoc3/helpers/filtering.rb +1 -1
  56. data/lib/nanoc3/helpers/link_to.rb +10 -21
  57. data/lib/nanoc3/helpers/rendering.rb +5 -24
  58. data/lib/nanoc3/helpers/tagging.rb +6 -6
  59. data/lib/nanoc3/helpers/text.rb +2 -2
  60. data/lib/nanoc3.rb +1 -1
  61. metadata +35 -93
  62. data/.gemtest +0 -0
  63. data/doc/yardoc_templates/default/layout/html/footer.erb +0 -10
  64. data/nanoc3.gemspec +0 -41
  65. data/tasks/clean.rake +0 -11
  66. data/tasks/doc.rake +0 -14
  67. data/tasks/gem.rake +0 -13
  68. data/tasks/test.rake +0 -38
  69. data/test/base/core_ext/array_spec.rb +0 -23
  70. data/test/base/core_ext/hash_spec.rb +0 -41
  71. data/test/base/core_ext/string_spec.rb +0 -27
  72. data/test/base/test_code_snippet.rb +0 -33
  73. data/test/base/test_compiler.rb +0 -410
  74. data/test/base/test_compiler_dsl.rb +0 -121
  75. data/test/base/test_context.rb +0 -33
  76. data/test/base/test_data_source.rb +0 -48
  77. data/test/base/test_dependency_tracker.rb +0 -510
  78. data/test/base/test_directed_graph.rb +0 -91
  79. data/test/base/test_filter.rb +0 -85
  80. data/test/base/test_item.rb +0 -141
  81. data/test/base/test_item_rep.rb +0 -953
  82. data/test/base/test_layout.rb +0 -44
  83. data/test/base/test_notification_center.rb +0 -36
  84. data/test/base/test_plugin.rb +0 -32
  85. data/test/base/test_rule.rb +0 -21
  86. data/test/base/test_rule_context.rb +0 -63
  87. data/test/base/test_site.rb +0 -366
  88. data/test/cli/commands/test_compile.rb +0 -12
  89. data/test/cli/commands/test_create_item.rb +0 -12
  90. data/test/cli/commands/test_create_layout.rb +0 -28
  91. data/test/cli/commands/test_create_site.rb +0 -24
  92. data/test/cli/commands/test_help.rb +0 -12
  93. data/test/cli/commands/test_info.rb +0 -12
  94. data/test/cli/commands/test_update.rb +0 -12
  95. data/test/cli/test_logger.rb +0 -12
  96. data/test/data_sources/test_filesystem.rb +0 -420
  97. data/test/data_sources/test_filesystem_unified.rb +0 -538
  98. data/test/data_sources/test_filesystem_verbose.rb +0 -359
  99. data/test/extra/core_ext/test_enumerable.rb +0 -32
  100. data/test/extra/core_ext/test_time.rb +0 -17
  101. data/test/extra/deployers/test_rsync.rb +0 -234
  102. data/test/extra/test_auto_compiler.rb +0 -482
  103. data/test/extra/test_file_proxy.rb +0 -21
  104. data/test/extra/test_vcs.rb +0 -24
  105. data/test/extra/validators/test_links.rb +0 -53
  106. data/test/extra/validators/test_w3c.rb +0 -49
  107. data/test/filters/test_bluecloth.rb +0 -20
  108. data/test/filters/test_coderay.rb +0 -46
  109. data/test/filters/test_colorize_syntax.rb +0 -84
  110. data/test/filters/test_erb.rb +0 -72
  111. data/test/filters/test_erubis.rb +0 -72
  112. data/test/filters/test_haml.rb +0 -98
  113. data/test/filters/test_kramdown.rb +0 -20
  114. data/test/filters/test_less.rb +0 -118
  115. data/test/filters/test_markaby.rb +0 -26
  116. data/test/filters/test_maruku.rb +0 -20
  117. data/test/filters/test_rainpress.rb +0 -31
  118. data/test/filters/test_rdiscount.rb +0 -33
  119. data/test/filters/test_rdoc.rb +0 -18
  120. data/test/filters/test_redcloth.rb +0 -20
  121. data/test/filters/test_relativize_paths.rb +0 -231
  122. data/test/filters/test_rubypants.rb +0 -20
  123. data/test/filters/test_sass.rb +0 -235
  124. data/test/gem_loader.rb +0 -11
  125. data/test/helper.rb +0 -99
  126. data/test/helpers/test_blogging.rb +0 -808
  127. data/test/helpers/test_breadcrumbs.rb +0 -83
  128. data/test/helpers/test_capturing.rb +0 -42
  129. data/test/helpers/test_filtering.rb +0 -108
  130. data/test/helpers/test_html_escape.rb +0 -18
  131. data/test/helpers/test_link_to.rb +0 -251
  132. data/test/helpers/test_rendering.rb +0 -109
  133. data/test/helpers/test_tagging.rb +0 -89
  134. data/test/helpers/test_text.rb +0 -26
  135. data/test/helpers/test_xml_sitemap.rb +0 -69
  136. data/test/tasks/test_clean.rb +0 -71
@@ -15,7 +15,7 @@ module Nanoc3
15
15
  # Sets the identifiers for this plugin.
16
16
  #
17
17
  # @param [Array<Symbol>] identifier A list of identifiers to assign to
18
- # this plugin.
18
+ # this plugin.
19
19
  #
20
20
  # @return [void]
21
21
  def identifiers(*identifiers)
@@ -34,10 +34,10 @@ module Nanoc3
34
34
  # Registers the given class as a plugin with the given identifier.
35
35
  #
36
36
  # @param [Class, String] class_or_name The class to register, or a
37
- # string containing the class name to register.
37
+ # string containing the class name to register.
38
38
  #
39
39
  # @param [Array<Symbol>] identifiers A list of identifiers to assign to
40
- # this plugin.
40
+ # this plugin.
41
41
  #
42
42
  # @return [void]
43
43
  def register(class_or_name, *identifiers)
@@ -79,15 +79,15 @@ module Nanoc3
79
79
  # Registers the given class as a plugin.
80
80
  #
81
81
  # @param [Class] superclass The superclass of the plugin. For example:
82
- # {Nanoc3::Filter}, {Nanoc3::Extra::VCS}.
82
+ # {Nanoc3::Filter}, {Nanoc3::Extra::VCS}.
83
83
  #
84
84
  # @param [Class, String] class_or_name The class to register. This can be
85
- # a string, in which case it will be automatically converted to a proper
86
- # class at lookup. For example: `Nanoc3::Filters::ERB`,
87
- # `"Nanoc3::Filters::Haml"`.
85
+ # a string, in which case it will be automatically converted to a proper
86
+ # class at lookup. For example: `Nanoc3::Filters::ERB`,
87
+ # `"Nanoc3::Filters::Haml"`.
88
88
  #
89
89
  # @param [Symbol] identifiers One or more symbols identifying the class.
90
- # For example: `:haml`, :`erb`.
90
+ # For example: `:haml`, :`erb`.
91
91
  #
92
92
  # @return [void]
93
93
  def register(superclass, class_or_name, *identifiers)
@@ -159,7 +159,7 @@ module Nanoc3
159
159
 
160
160
  end
161
161
 
162
- # @deprecated Use {Nanoc3::PluginRegistry.instance} instead
162
+ # @deprecated Use {Nanoc3::PluginRegistry.instace} instead
163
163
  Plugin = PluginRegistry.instance
164
164
 
165
165
  end
@@ -6,29 +6,38 @@ module Nanoc3
6
6
  class Rule
7
7
 
8
8
  # @return [Regexp] The regex that determines which items this rule can be
9
- # applied to. This rule can be applied to items with a identifier matching
10
- # this regex.
9
+ # applied to. This rule can be applied to items with a identifier
10
+ # matching this regex.
11
11
  attr_reader :identifier_regex
12
12
 
13
13
  # @return [Symbol] The name of the representation that will be compiled
14
- # using this rule
14
+ # using this rule
15
15
  attr_reader :rep_name
16
16
 
17
+ # @return [Symbol] The name of the snapshot this rule will apply to.
18
+ # Ignored for compilation rules, but used for routing rules.
19
+ attr_reader :snapshot_name
20
+
17
21
  # Creates a new item compilation rule with the given identifier regex,
18
22
  # compiler and block. The block will be called during compilation with the
19
23
  # item rep as its argument.
20
24
  #
21
25
  # @param [Regexp] identifier_regex A regular expression that will be used
22
- # to determine whether this rule is applicable to certain items.
26
+ # to determine whether this rule is applicable to certain items.
23
27
  #
24
28
  # @param [String, Symbol] rep_name The name of the item representation
25
- # where this rule can be applied to
29
+ # where this rule can be applied to
26
30
  #
27
31
  # @param [Proc] block A block that will be called when matching items are
28
- # compiled
29
- def initialize(identifier_regex, rep_name, block)
32
+ # compiled
33
+ #
34
+ # @option params [Symbol, nil] :snapshot (nil) The name of the snapshot
35
+ # this rule will apply to. Ignored for compilation rules, but used for
36
+ # routing rules.
37
+ def initialize(identifier_regex, rep_name, block, params={})
30
38
  @identifier_regex = identifier_regex
31
39
  @rep_name = rep_name.to_sym
40
+ @snapshot_name = params[:snapshot_name]
32
41
 
33
42
  @block = block
34
43
  end
@@ -36,7 +45,7 @@ module Nanoc3
36
45
  # @param [Nanoc3::Item] item The item to check
37
46
  #
38
47
  # @return [Boolean] true if this rule can be applied to the given item
39
- # rep, false otherwise
48
+ # rep, false otherwise
40
49
  def applicable_to?(item)
41
50
  item.identifier =~ @identifier_regex
42
51
  end
@@ -44,7 +53,7 @@ module Nanoc3
44
53
  # Applies this rule to the given item rep.
45
54
  #
46
55
  # @param [Nanoc3::ItemRep] rep The item representation where this rule
47
- # should be applied to
56
+ # should be applied to
48
57
  #
49
58
  # @return [void]
50
59
  def apply_to(rep)
@@ -14,10 +14,10 @@ module Nanoc3
14
14
  # * `layouts` ({Array}<{Nanoc3::Layout}>) - A list of all layouts
15
15
  class RuleContext < Context
16
16
 
17
- # Creates a new rule context for the given item representation.
17
+ # Creates a new rule context for the given iterm representation.
18
18
  #
19
19
  # @param [Nanoc3::ItemRep] rep The item representation for which to create
20
- # a new rule context.
20
+ # a new rule context.
21
21
  def initialize(rep)
22
22
  item = rep.item
23
23
  site = item.site
@@ -41,10 +41,10 @@ module Nanoc3
41
41
  # @see Nanoc3::ItemRep#filter
42
42
  #
43
43
  # @param [Symbol] filter_name The name of the filter to run the item
44
- # representations' content through
44
+ # representations' content through
45
45
  #
46
46
  # @param [Hash] filter_args The filter arguments that should be passed to
47
- # the filter's #run method
47
+ # the filter's #run method
48
48
  #
49
49
  # @return [void]
50
50
  def filter(filter_name, filter_args={})
@@ -57,7 +57,7 @@ module Nanoc3
57
57
  # @see Nanoc3::ItemRep#layout
58
58
  #
59
59
  # @param [String] layout_identifier The identifier of the layout the item
60
- # should be laid out with
60
+ # should be laid out with
61
61
  #
62
62
  # @return [void]
63
63
  def layout(layout_identifier)
@@ -39,13 +39,16 @@ module Nanoc3
39
39
  # that lacks some options, the default value will be taken from
40
40
  # `DEFAULT_CONFIG`.
41
41
  DEFAULT_CONFIG = {
42
- :text_extensions => %w( css erb haml htm html js less markdown md php rb sass scss txt xhtml xml ),
42
+ :text_extensions => %w( css erb haml htm html js less markdown md php rb sass txt xml ),
43
43
  :output_dir => 'output',
44
44
  :data_sources => [ {} ],
45
45
  :index_filenames => [ 'index.html' ],
46
46
  :enable_output_diff => false
47
47
  }
48
48
 
49
+ # The name of the file where checksums will be stored.
50
+ CHECKSUMS_FILE_NAME = 'tmp/checksums'
51
+
49
52
  # The site configuration. The configuration has the following keys:
50
53
  #
51
54
  # * `text_extensions` ({Array<String>}) - A list of file extensions that
@@ -89,23 +92,33 @@ module Nanoc3
89
92
  # @return [Hash] The site configuration
90
93
  attr_reader :config
91
94
 
92
- # @return [Time] The timestamp when the site configuration was last
93
- # modified
94
- attr_reader :config_mtime
95
+ # @return [String] The checksum of the site configuration that was in
96
+ # effect during the previous site compilation
97
+ attr_accessor :old_config_checksum
98
+
99
+ # @return [String] The current, up-to-date checksum of the site
100
+ # configuration
101
+ attr_reader :new_config_checksum
102
+
103
+ # @return [String] The checksum of the rules file that was in effect
104
+ # during the previous site compilation
105
+ attr_accessor :old_rules_checksum
95
106
 
96
- # @return [Time] The timestamp when the rules were last modified
97
- attr_reader :rules_mtime
107
+ # @return [String] The current, up-to-date checksum of the rules file
108
+ attr_reader :new_rules_checksum
98
109
 
99
110
  # @return [Proc] The code block that will be executed after all data is
100
- # loaded but before the site is compiled
111
+ # loaded but before the site is compiled
101
112
  attr_accessor :preprocessor
102
113
 
103
114
  # Creates a site object for the site specified by the given
104
115
  # `dir_or_config_hash` argument.
105
116
  #
106
117
  # @param [Hash, String] dir_or_config_hash If a string, contains the path
107
- # to the site directory; if a hash, contains the site configuration.
118
+ # to the site directory; if a hash, contains the site configuration.
108
119
  def initialize(dir_or_config_hash)
120
+ @new_checksums = {}
121
+
109
122
  build_config(dir_or_config_hash)
110
123
 
111
124
  @code_snippets_loaded = false
@@ -125,10 +138,10 @@ module Nanoc3
125
138
  # none exists yet.
126
139
  #
127
140
  # @return [Array<Nanoc3::DataSource>] The list of data sources for this
128
- # site
141
+ # site
129
142
  #
130
143
  # @raise [Nanoc3::Errors::UnknownDataSource] if the site configuration
131
- # specifies an unknown data source
144
+ # specifies an unknown data source
132
145
  def data_sources
133
146
  @data_sources ||= begin
134
147
  @config[:data_sources].map do |data_source_hash|
@@ -162,7 +175,7 @@ module Nanoc3
162
175
  # the `force` parameter is true.
163
176
  #
164
177
  # @param [Boolean] force If true, will force load the site data even if it
165
- # has been loaded before, to circumvent caching issues
178
+ # has been loaded before, to circumvent caching issues
166
179
  #
167
180
  # @return [void]
168
181
  def load_data(force=false)
@@ -192,10 +205,10 @@ module Nanoc3
192
205
  # Returns this site’s code snippets.
193
206
  #
194
207
  # @return [Array<Nanoc3::CodeSnippet>] The list of code snippets in this
195
- # site
208
+ # site
196
209
  #
197
210
  # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
198
- # been loaded yet (call {#load_data} to load the site data)
211
+ # been loaded yet (call {#load_data} to load the site data)
199
212
  def code_snippets
200
213
  raise Nanoc3::Errors::DataNotYetAvailable.new('Code snippets', false) unless @code_snippets_loaded
201
214
  @code_snippets
@@ -206,7 +219,7 @@ module Nanoc3
206
219
  # @return [Array<Nanoc3::Item>] The list of items in this site
207
220
  #
208
221
  # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
209
- # been loaded yet (call {#load_data} to load the site data)
222
+ # been loaded yet (call {#load_data} to load the site data)
210
223
  def items
211
224
  raise Nanoc3::Errors::DataNotYetAvailable.new('Items', true) unless @items_loaded
212
225
  @items
@@ -217,12 +230,36 @@ module Nanoc3
217
230
  # @return [Array<Nanoc3::Layouts>] The list of layout in this site
218
231
  #
219
232
  # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
220
- # been loaded yet (call {#load_data} to load the site data)
233
+ # been loaded yet (call {#load_data} to load the site data)
221
234
  def layouts
222
235
  raise Nanoc3::Errors::DataNotYetAvailable.new('Layouts', true) unless @layouts_loaded
223
236
  @layouts
224
237
  end
225
238
 
239
+ # Stores the checksums into the checksums file.
240
+ #
241
+ # @return [void]
242
+ def store_checksums
243
+ # Store
244
+ FileUtils.mkdir_p(File.dirname(CHECKSUMS_FILE_NAME))
245
+ store = PStore.new(CHECKSUMS_FILE_NAME)
246
+ store.transaction do
247
+ store[:checksums] = @new_checksums || {}
248
+ end
249
+ end
250
+
251
+ # @return [Boolean] true if the site configuration was modified since the
252
+ # site was last compiled, false otherwise
253
+ def config_outdated?
254
+ !self.old_config_checksum || !self.new_config_checksum || self.old_config_checksum != self.new_config_checksum
255
+ end
256
+
257
+ # @return [Boolean] true if the rules were modified since the site was
258
+ # last compiled, false otherwise
259
+ def rules_outdated?
260
+ !self.old_rules_checksum || !self.new_rules_checksum || self.old_rules_checksum != self.new_rules_checksum
261
+ end
262
+
226
263
  private
227
264
 
228
265
  # Returns the Nanoc3::CompilerDSL that should be used for this site.
@@ -240,10 +277,16 @@ module Nanoc3
240
277
  Nanoc3::CodeSnippet.new(
241
278
  File.read(filename),
242
279
  filename,
243
- File.stat(filename).mtime
280
+ :checksum => Nanoc3::Checksummer.checksum_for(filename)
244
281
  )
245
282
  end
246
283
 
284
+ # Set checksums
285
+ @code_snippets.each do |cs|
286
+ cs.old_checksum = old_checksum_for(:code_snippet, cs.filename)
287
+ @new_checksums[ [ :code_snippet, cs.filename ] ] = cs.new_checksum
288
+ end
289
+
247
290
  # Execute code snippets
248
291
  @code_snippets.each { |cs| cs.load }
249
292
 
@@ -257,8 +300,10 @@ module Nanoc3
257
300
  raise Nanoc3::Errors::NoRulesFileFound.new if rules_filename.nil?
258
301
 
259
302
  # Get rule data
260
- @rules = File.read(rules_filename)
261
- @rules_mtime = File.stat(rules_filename).mtime
303
+ @rules = File.read(rules_filename)
304
+ @new_rules_checksum = Nanoc3::Checksummer.checksum_for(rules_filename)
305
+ @old_rules_checksum = old_checksum_for(:misc, 'Rules')
306
+ @new_checksums[ [ :misc, 'Rules' ] ] = @new_rules_checksum
262
307
 
263
308
  # Load DSL
264
309
  dsl.instance_eval(@rules, "./#{rules_filename}")
@@ -274,6 +319,12 @@ module Nanoc3
274
319
  @items.concat(items_in_ds)
275
320
  end
276
321
 
322
+ # Set checksums
323
+ @items.each do |i|
324
+ i.old_checksum = old_checksum_for(:item, i.identifier)
325
+ @new_checksums[ [ :item, i.identifier ] ] = i.new_checksum
326
+ end
327
+
277
328
  @items_loaded = true
278
329
  end
279
330
 
@@ -286,6 +337,12 @@ module Nanoc3
286
337
  @layouts.concat(layouts_in_ds)
287
338
  end
288
339
 
340
+ # Set checksums
341
+ @layouts.each do |l|
342
+ l.old_checksum = old_checksum_for(:layout, l.identifier)
343
+ @new_checksums[ [ :layout, l.identifier ] ] = l.new_checksum
344
+ end
345
+
289
346
  @layouts_loaded = true
290
347
  end
291
348
 
@@ -337,52 +394,51 @@ module Nanoc3
337
394
  def route_reps
338
395
  reps = @items.map { |i| i.reps }.flatten
339
396
  reps.each do |rep|
340
- # Find matching rule
341
- rule = self.compiler.routing_rule_for(rep)
342
- raise Nanoc3::Errors::NoMatchingRoutingRuleFound.new(rep) if rule.nil?
343
-
344
- # Get basic path by applying matching rule
345
- basic_path = rule.apply_to(rep)
346
- next if basic_path.nil?
347
- if basic_path !~ %r{^/}
348
- raise RuntimeError, "The path returned for the #{rep.inspect} item representation, “#{basic_path}”, does not start with a slash. Please ensure that all routing rules return a path that starts with a slash.".make_compatible_with_env
349
- end
350
-
351
- # Get raw path by prepending output directory
352
- rep.raw_path = self.config[:output_dir] + basic_path
353
-
354
- # Get normal path by stripping index filename
355
- rep.path = basic_path
356
- self.config[:index_filenames].each do |index_filename|
357
- if rep.path[-index_filename.length..-1] == index_filename
358
- # Strip and stop
359
- rep.path = rep.path[0..-index_filename.length-1]
360
- break
397
+ # Find matching rules
398
+ rules = self.compiler.routing_rules_for(rep)
399
+ raise Nanoc3::Errors::NoMatchingRoutingRuleFound.new(rep) if rules[:last].nil?
400
+
401
+ rules.each_pair do |snapshot, rule|
402
+ # Get basic path by applying matching rule
403
+ basic_path = rule.apply_to(rep)
404
+ next if basic_path.nil?
405
+
406
+ # Get raw path by prepending output directory
407
+ rep.raw_paths[snapshot] = self.config[:output_dir] + basic_path
408
+
409
+ # Get normal path by stripping index filename
410
+ rep.paths[snapshot] = basic_path
411
+ self.config[:index_filenames].each do |index_filename|
412
+ if rep.paths[snapshot][-index_filename.length..-1] == index_filename
413
+ # Strip and stop
414
+ rep.paths[snapshot] = rep.paths[snapshot][0..-index_filename.length-1]
415
+ break
416
+ end
361
417
  end
362
418
  end
363
419
  end
364
420
  end
365
421
 
366
422
  # Builds the configuration hash based on the given argument. Also see
367
- # #initialize for details.
423
+ # {#initialize} for details.
368
424
  def build_config(dir_or_config_hash)
369
425
  if dir_or_config_hash.is_a? String
370
- # Check whether it is supported
371
- if dir_or_config_hash != '.'
372
- warn 'WARNING: Calling Nanoc3::Site.new with a directory that is not the current working directory is not supported. It is recommended to change the directory before calling Nanoc3::Site.new. For example, instead of Nanoc3::Site.new(\'abc\'), use Dir.chdir(\'abc\') { Nanoc3::Site.new(\'.\') }.'
373
- end
374
-
375
426
  # Read config from config.yaml in given dir
376
427
  config_path = File.join(dir_or_config_hash, 'config.yaml')
377
428
  @config = DEFAULT_CONFIG.merge(YAML.load_file(config_path).symbolize_keys)
378
429
  @config[:data_sources].map! { |ds| ds.symbolize_keys }
379
- @config_mtime = File.stat(config_path).mtime
430
+
431
+ @new_config_checksum = Nanoc3::Checksummer.checksum_for('config.yaml')
432
+ @new_checksums[ [ :misc, 'config.yaml' ] ] = @new_config_checksum
380
433
  else
381
434
  # Use passed config hash
382
435
  @config = DEFAULT_CONFIG.merge(dir_or_config_hash)
383
- @config_mtime = nil
436
+ @new_config_checksum = nil
384
437
  end
385
438
 
439
+ # Build checksum
440
+ @old_config_checksum = old_checksum_for(:misc, 'config.yaml')
441
+
386
442
  # Merge data sources with default data source config
387
443
  @config[:data_sources].map! { |ds| DEFAULT_DATA_SOURCE_CONFIG.merge(ds) }
388
444
  end
@@ -397,6 +453,38 @@ module Nanoc3
397
453
  })
398
454
  end
399
455
 
456
+ # Returns the checksums, loads the checksums from the cached checksums
457
+ # file first if necessary. The checksums returned is a hash in th following
458
+ # format:
459
+ #
460
+ # {
461
+ # [ :layout, '/identifier/' ] => checksum,
462
+ # [ :item, '/identifier/' ] => checksum,
463
+ # [ :code_snippet, 'lib/filename.rb' ] => checksum,
464
+ # }
465
+ def checksums
466
+ return @checksums if @checksums_loaded
467
+
468
+ if !File.file?(CHECKSUMS_FILE_NAME)
469
+ @checksums = {}
470
+ else
471
+ require 'pstore'
472
+ store = PStore.new(CHECKSUMS_FILE_NAME)
473
+ store.transaction do
474
+ @checksums = store[:checksums] || {}
475
+ end
476
+ end
477
+
478
+ @checksums_loaded = true
479
+ @checksums
480
+ end
481
+
482
+ # Returns the old checksum for the given object.
483
+ def old_checksum_for(type, identifier)
484
+ key = [ type, identifier ]
485
+ checksums[key]
486
+ end
487
+
400
488
  end
401
489
 
402
490
  end
data/lib/nanoc3/base.rb CHANGED
@@ -5,27 +5,29 @@ module Nanoc3
5
5
  require 'nanoc3/base/core_ext'
6
6
  require 'nanoc3/base/ordered_hash'
7
7
 
8
- autoload 'CodeSnippet', 'nanoc3/base/code_snippet'
9
- autoload 'Compiler', 'nanoc3/base/compiler'
10
- autoload 'CompilerDSL', 'nanoc3/base/compiler_dsl'
11
- autoload 'Config', 'nanoc3/base/config'
12
- autoload 'Context', 'nanoc3/base/context'
13
- autoload 'DataSource', 'nanoc3/base/data_source'
14
- autoload 'DependencyTracker', 'nanoc3/base/dependency_tracker'
15
- autoload 'DirectedGraph', 'nanoc3/base/directed_graph'
16
- autoload 'Errors', 'nanoc3/base/errors'
17
- autoload 'Filter', 'nanoc3/base/filter'
18
- autoload 'Item', 'nanoc3/base/item'
19
- autoload 'ItemRep', 'nanoc3/base/item_rep'
20
- autoload 'Layout', 'nanoc3/base/layout'
21
- autoload 'NotificationCenter', 'nanoc3/base/notification_center'
22
- autoload 'PluginRegistry', 'nanoc3/base/plugin_registry'
23
- autoload 'Rule', 'nanoc3/base/rule'
24
- autoload 'RuleContext', 'nanoc3/base/rule_context'
25
- autoload 'Site', 'nanoc3/base/site'
8
+ autoload 'Checksummer', 'nanoc3/base/checksummer'
9
+ autoload 'CodeSnippet', 'nanoc3/base/code_snippet'
10
+ autoload 'CompiledContentCache', 'nanoc3/base/compiled_content_cache'
11
+ autoload 'Compiler', 'nanoc3/base/compiler'
12
+ autoload 'CompilerDSL', 'nanoc3/base/compiler_dsl'
13
+ autoload 'Config', 'nanoc3/base/config'
14
+ autoload 'Context', 'nanoc3/base/context'
15
+ autoload 'DataSource', 'nanoc3/base/data_source'
16
+ autoload 'DependencyTracker', 'nanoc3/base/dependency_tracker'
17
+ autoload 'DirectedGraph', 'nanoc3/base/directed_graph'
18
+ autoload 'Errors', 'nanoc3/base/errors'
19
+ autoload 'Filter', 'nanoc3/base/filter'
20
+ autoload 'Item', 'nanoc3/base/item'
21
+ autoload 'ItemRep', 'nanoc3/base/item_rep'
22
+ autoload 'Layout', 'nanoc3/base/layout'
23
+ autoload 'NotificationCenter', 'nanoc3/base/notification_center'
24
+ autoload 'PluginRegistry', 'nanoc3/base/plugin_registry'
25
+ autoload 'Rule', 'nanoc3/base/rule'
26
+ autoload 'RuleContext', 'nanoc3/base/rule_context'
27
+ autoload 'Site', 'nanoc3/base/site'
26
28
 
27
29
  # Deprecated; use PluginRepository instead
28
30
  # TODO [in nanoc 4.0] remove me
29
- autoload 'Plugin', 'nanoc3/base/plugin_registry'
31
+ autoload 'Plugin', 'nanoc3/base/plugin_registry'
30
32
 
31
33
  end