nanoc 4.0.0b4 → 4.0.0rc1

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +31 -32
  4. data/NEWS.md +7 -0
  5. data/README.md +1 -2
  6. data/Rakefile +2 -11
  7. data/TODO.md +0 -1
  8. data/bin/nanoc +4 -0
  9. data/lib/nanoc/base/checksummer.rb +1 -1
  10. data/lib/nanoc/base/compilation/compiler.rb +7 -13
  11. data/lib/nanoc/base/compilation/dependency_tracker.rb +1 -1
  12. data/lib/nanoc/base/compilation/rule.rb +2 -0
  13. data/lib/nanoc/base/compilation/rules_collection.rb +2 -2
  14. data/lib/nanoc/base/entities/identifier.rb +45 -15
  15. data/lib/nanoc/base/entities/pattern.rb +8 -0
  16. data/lib/nanoc/base/entities/snapshot_def.rb +16 -0
  17. data/lib/nanoc/base/entities.rb +1 -0
  18. data/lib/nanoc/base/plugin_registry.rb +1 -1
  19. data/lib/nanoc/base/{compilation → repos}/checksum_store.rb +0 -0
  20. data/lib/nanoc/base/{compilation → repos}/compiled_content_cache.rb +0 -0
  21. data/lib/nanoc/base/repos/config_loader.rb +67 -0
  22. data/lib/nanoc/base/{compilation → repos}/rule_memory_store.rb +0 -0
  23. data/lib/nanoc/base/repos/site_loader.rb +118 -0
  24. data/lib/nanoc/base/{store.rb → repos/store.rb} +0 -0
  25. data/lib/nanoc/base/repos.rb +7 -0
  26. data/lib/nanoc/base/result_data/item_rep.rb +37 -66
  27. data/lib/nanoc/base/services/executor.rb +15 -9
  28. data/lib/nanoc/base/services/item_rep_writer.rb +1 -1
  29. data/lib/nanoc/base/services/recording_executor.rb +4 -4
  30. data/lib/nanoc/base/source_data/configuration.rb +89 -3
  31. data/lib/nanoc/base/source_data/data_source.rb +2 -15
  32. data/lib/nanoc/base/source_data/site.rb +14 -378
  33. data/lib/nanoc/base/views/{config.rb → config_view.rb} +0 -0
  34. data/lib/nanoc/base/views/{identifiable_collection.rb → identifiable_collection_view.rb} +0 -0
  35. data/lib/nanoc/base/views/{item_collection.rb → item_collection_view.rb} +0 -0
  36. data/lib/nanoc/base/views/{item_rep_collection.rb → item_rep_collection_view.rb} +7 -1
  37. data/lib/nanoc/base/views/{item_rep.rb → item_rep_view.rb} +0 -0
  38. data/lib/nanoc/base/views/{item.rb → item_view.rb} +0 -0
  39. data/lib/nanoc/base/views/{layout_collection.rb → layout_collection_view.rb} +0 -0
  40. data/lib/nanoc/base/views/{layout.rb → layout_view.rb} +0 -0
  41. data/lib/nanoc/base/views/mixins/{document.rb → document_view_mixin.rb} +0 -0
  42. data/lib/nanoc/base/views/mixins/{mutable_document.rb → mutable_document_view_mixin.rb} +0 -0
  43. data/lib/nanoc/base/views/{mutable_config.rb → mutable_config_view.rb} +0 -0
  44. data/lib/nanoc/base/views/{mutable_identifiable_collection.rb → mutable_identifiable_collection_view.rb} +0 -0
  45. data/lib/nanoc/base/views/{mutable_item_collection.rb → mutable_item_collection_view.rb} +0 -0
  46. data/lib/nanoc/base/views/{mutable_item.rb → mutable_item_view.rb} +0 -0
  47. data/lib/nanoc/base/views/{mutable_layout_collection.rb → mutable_layout_collection_view.rb} +0 -0
  48. data/lib/nanoc/base/views/{mutable_layout.rb → mutable_layout_view.rb} +0 -0
  49. data/lib/nanoc/base/views/{site.rb → site_view.rb} +0 -0
  50. data/lib/nanoc/base/views.rb +17 -17
  51. data/lib/nanoc/base.rb +1 -4
  52. data/lib/nanoc/cli/ansi_string_colorizer.rb +1 -1
  53. data/lib/nanoc/cli/cleaning_stream.rb +5 -0
  54. data/lib/nanoc/cli/command_runner.rb +10 -4
  55. data/lib/nanoc/cli/commands/compile.rb +1 -1
  56. data/lib/nanoc/cli/commands/create-site.rb +12 -11
  57. data/lib/nanoc/cli/commands/prune.rb +1 -0
  58. data/lib/nanoc/cli/commands/show-plugins.rb +4 -4
  59. data/lib/nanoc/cli/commands/show-rules.rb +21 -30
  60. data/lib/nanoc/cli/commands/view.rb +1 -1
  61. data/lib/nanoc/cli/error_handler.rb +1 -1
  62. data/lib/nanoc/cli.rb +3 -3
  63. data/lib/nanoc/data_sources/filesystem.rb +4 -4
  64. data/lib/nanoc/extra/checking/runner.rb +3 -2
  65. data/lib/nanoc/extra/deployers/rsync.rb +1 -1
  66. data/lib/nanoc/extra/link_collector.rb +1 -1
  67. data/lib/nanoc/helpers/capturing.rb +1 -1
  68. data/lib/nanoc/helpers/rendering.rb +2 -2
  69. data/lib/nanoc/version.rb +1 -1
  70. data/nanoc.gemspec +3 -4
  71. data/tasks/doc.rake +1 -1
  72. data/tasks/rubocop.rake +4 -8
  73. data/tasks/test.rake +11 -27
  74. data/test/base/test_compiler.rb +21 -16
  75. data/test/base/test_compiler_dsl.rb +8 -8
  76. data/test/base/test_item.rb +1 -1
  77. data/test/base/test_item_rep.rb +16 -14
  78. data/test/base/test_memoization.rb +1 -38
  79. data/test/base/test_outdatedness_checker.rb +38 -6
  80. data/test/base/test_site.rb +19 -121
  81. data/test/cli/commands/test_compile.rb +1 -1
  82. data/test/cli/commands/test_create_site.rb +7 -8
  83. data/test/data_sources/test_filesystem.rb +7 -7
  84. data/test/data_sources/test_filesystem_unified.rb +17 -17
  85. data/test/extra/checking/checks/test_mixed_content.rb +8 -8
  86. data/test/extra/checking/checks/test_stale.rb +3 -4
  87. data/test/extra/deployers/test_fog.rb +1 -1
  88. data/test/extra/deployers/test_rsync.rb +2 -2
  89. data/test/extra/test_filesystem_tools.rb +1 -1
  90. data/test/filters/test_erb.rb +1 -1
  91. data/test/filters/test_handlebars.rb +2 -2
  92. data/test/filters/test_less.rb +2 -2
  93. data/test/filters/test_mustache.rb +2 -2
  94. data/test/filters/test_relativize_paths.rb +1 -1
  95. data/test/filters/test_sass.rb +6 -6
  96. data/test/filters/test_xsl.rb +3 -3
  97. data/test/helper.rb +10 -15
  98. data/test/helpers/test_blogging.rb +16 -16
  99. data/test/helpers/test_capturing.rb +6 -6
  100. data/test/helpers/test_link_to.rb +13 -13
  101. data/test/helpers/test_rendering.rb +33 -0
  102. data/test/helpers/test_tagging.rb +8 -8
  103. metadata +32 -30
  104. data/test/gem_loader.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6a2272e514cd909fa601f4fea595a3827b82ae4
4
- data.tar.gz: d2817ebcf5353f903262f858b7ce2b7dbcd995e6
3
+ metadata.gz: 43b1a732cd792777b84fed953191470f0147e4ec
4
+ data.tar.gz: d2ac5a5275b3486c88e94dd68e353d8ac19d50e2
5
5
  SHA512:
6
- metadata.gz: bbaeae81947c39944044cb73ac30d7347c5a204ccfe70843f7796e7aa17d5def67be3fc1a77f65abca4f64ce704cf81dff123ced4c08e98f1b7e124841d96d63
7
- data.tar.gz: e58c103c1bbf728768f349d286b1c299524513b20bff9a0621548b861eeba906b9cb4582a01f688ef6b8bc6318aefa7958166b58ba7db4187a8e8d61f9223745
6
+ metadata.gz: b6a63f720e046d3385085ff1b25ea062776389208d1c29936df3647c85dd59a8a65b4b107dad415ddaba25d859d9ec97c41f44d2a49921c6cf8114ee1aba7a97
7
+ data.tar.gz: ccf810ffe22680e674c52b06605ac20ed2851727aca8c149c12ac8988788aee6f174f318b7ab7822ecb00116104fc60169a3f3cc87c1c3616080d61803fd4ed6
data/Gemfile CHANGED
@@ -12,7 +12,6 @@ gem 'compass'
12
12
  gem 'coffee-script'
13
13
  gem 'coveralls', require: false
14
14
  gem 'erubis'
15
- gem 'fakefs'
16
15
  gem 'fog'
17
16
  gem 'haml'
18
17
  gem 'handlebars', platforms: :ruby
@@ -42,9 +41,10 @@ gem 'redcarpet', platforms: [:ruby, :mswin]
42
41
  gem 'RedCloth'
43
42
  gem 'rouge'
44
43
  gem 'rspec'
45
- gem 'rubocop'
44
+ gem 'rubocop', '~> 0.31.0'
46
45
  gem 'rubypants'
47
46
  gem 'sass', '~> 3.2.2'
47
+ gem 'simplecov', require: false
48
48
  gem 'slim'
49
49
  gem 'typogruby'
50
50
  gem 'uglifier'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nanoc (4.0.0b4)
4
+ nanoc (4.0.0rc1)
5
5
  cri (~> 2.3)
6
6
 
7
7
  GEM
@@ -48,15 +48,14 @@ GEM
48
48
  erubis (2.7.0)
49
49
  excon (0.45.3)
50
50
  execjs (2.5.2)
51
- fakefs (0.6.7)
52
51
  ffi (1.9.8)
53
52
  fission (0.5.0)
54
53
  CFPropertyList (~> 2.2)
55
- fog (1.30.0)
54
+ fog (1.31.0)
56
55
  fog-atmos
57
56
  fog-aws (~> 0.0)
58
57
  fog-brightbox (~> 0.4)
59
- fog-core (~> 1.27, >= 1.27.4)
58
+ fog-core (~> 1.30)
60
59
  fog-ecloud
61
60
  fog-google (>= 0.0.2)
62
61
  fog-json
@@ -78,7 +77,7 @@ GEM
78
77
  fog-atmos (0.1.0)
79
78
  fog-core
80
79
  fog-xml
81
- fog-aws (0.4.0)
80
+ fog-aws (0.5.0)
82
81
  fog-core (~> 1.27)
83
82
  fog-json (~> 1.0)
84
83
  fog-xml (~> 0.1)
@@ -87,30 +86,30 @@ GEM
87
86
  fog-core (~> 1.22)
88
87
  fog-json
89
88
  inflecto (~> 0.0.2)
90
- fog-core (1.30.0)
89
+ fog-core (1.31.1)
91
90
  builder
92
91
  excon (~> 0.45)
93
92
  formatador (~> 0.2)
94
93
  mime-types
95
94
  net-scp (~> 1.1)
96
95
  net-ssh (>= 2.1.3)
97
- fog-ecloud (0.1.1)
96
+ fog-ecloud (0.1.3)
98
97
  fog-core
99
98
  fog-xml
100
99
  fog-google (0.0.5)
101
100
  fog-core
102
101
  fog-json
103
102
  fog-xml
104
- fog-json (1.0.1)
103
+ fog-json (1.0.2)
105
104
  fog-core (~> 1.0)
106
- multi_json (~> 1.0)
105
+ multi_json (~> 1.10)
107
106
  fog-local (0.2.1)
108
107
  fog-core (~> 1.27)
109
108
  fog-powerdns (0.1.1)
110
109
  fog-core (~> 1.27)
111
110
  fog-json (~> 1.0)
112
111
  fog-xml (~> 0.1)
113
- fog-profitbricks (0.0.2)
112
+ fog-profitbricks (0.0.3)
114
113
  fog-core
115
114
  fog-xml
116
115
  nokogiri
@@ -159,12 +158,12 @@ GEM
159
158
  domain_name (~> 0.5)
160
159
  inflecto (0.0.2)
161
160
  ipaddress (0.8.0)
162
- json (1.8.2)
161
+ json (1.8.3)
163
162
  kramdown (1.7.0)
164
163
  less (2.6.0)
165
164
  commonjs (~> 0.2.7)
166
165
  libv8 (3.16.14.7)
167
- listen (2.10.0)
166
+ listen (2.10.1)
168
167
  celluloid (~> 0.16.0)
169
168
  rb-fsevent (>= 0.9.3)
170
169
  rb-inotify (>= 0.9)
@@ -178,7 +177,7 @@ GEM
178
177
  minitest (5.7.0)
179
178
  mocha (1.1.0)
180
179
  metaclass (~> 0.0.1)
181
- multi_json (1.11.0)
180
+ multi_json (1.11.1)
182
181
  mustache (1.0.1)
183
182
  net-scp (1.2.1)
184
183
  net-ssh (>= 2.6.5)
@@ -198,7 +197,7 @@ GEM
198
197
  pygments.rb (0.6.3)
199
198
  posix-spawn (~> 0.3.6)
200
199
  yajl-ruby (~> 1.2.0)
201
- rack (1.6.1)
200
+ rack (1.6.4)
202
201
  rainbow (2.0.0)
203
202
  rainpress (1.0)
204
203
  rake (10.4.2)
@@ -207,26 +206,26 @@ GEM
207
206
  ffi (>= 0.5.0)
208
207
  rdiscount (2.1.8)
209
208
  rdoc (4.2.0)
210
- redcarpet (3.2.3)
209
+ redcarpet (3.3.1)
211
210
  ref (1.0.5)
212
211
  rest-client (1.8.0)
213
212
  http-cookie (>= 1.0.2, < 2.0)
214
213
  mime-types (>= 1.16, < 3.0)
215
214
  netrc (~> 0.7)
216
215
  rouge (1.9.0)
217
- rspec (3.2.0)
218
- rspec-core (~> 3.2.0)
219
- rspec-expectations (~> 3.2.0)
220
- rspec-mocks (~> 3.2.0)
221
- rspec-core (3.2.3)
222
- rspec-support (~> 3.2.0)
223
- rspec-expectations (3.2.1)
216
+ rspec (3.3.0)
217
+ rspec-core (~> 3.3.0)
218
+ rspec-expectations (~> 3.3.0)
219
+ rspec-mocks (~> 3.3.0)
220
+ rspec-core (3.3.1)
221
+ rspec-support (~> 3.3.0)
222
+ rspec-expectations (3.3.0)
224
223
  diff-lcs (>= 1.2.0, < 2.0)
225
- rspec-support (~> 3.2.0)
226
- rspec-mocks (3.2.1)
224
+ rspec-support (~> 3.3.0)
225
+ rspec-mocks (3.3.1)
227
226
  diff-lcs (>= 1.2.0, < 2.0)
228
- rspec-support (~> 3.2.0)
229
- rspec-support (3.2.2)
227
+ rspec-support (~> 3.3.0)
228
+ rspec-support (3.3.0)
230
229
  rubocop (0.31.0)
231
230
  astrolabe (~> 1.3)
232
231
  parser (>= 2.2.2.1, < 3.0)
@@ -242,12 +241,12 @@ GEM
242
241
  json (~> 1.8)
243
242
  simplecov-html (~> 0.10.0)
244
243
  simplecov-html (0.10.0)
245
- slim (3.0.3)
244
+ slim (3.0.6)
246
245
  temple (~> 0.7.3)
247
246
  tilt (>= 1.3.3, < 2.1)
248
247
  slop (3.6.0)
249
- temple (0.7.5)
250
- term-ansicolor (1.3.0)
248
+ temple (0.7.6)
249
+ term-ansicolor (1.3.1)
251
250
  tins (~> 1.0)
252
251
  therubyracer (0.12.2)
253
252
  libv8 (~> 3.16.14.0)
@@ -290,7 +289,6 @@ DEPENDENCIES
290
289
  compass
291
290
  coveralls
292
291
  erubis
293
- fakefs
294
292
  fog
295
293
  haml
296
294
  handlebars
@@ -316,9 +314,10 @@ DEPENDENCIES
316
314
  redcarpet
317
315
  rouge
318
316
  rspec
319
- rubocop
317
+ rubocop (~> 0.31.0)
320
318
  rubypants
321
319
  sass (~> 3.2.2)
320
+ simplecov
322
321
  slim
323
322
  typogruby
324
323
  uglifier
@@ -329,4 +328,4 @@ DEPENDENCIES
329
328
  yuicompressor
330
329
 
331
330
  BUNDLED WITH
332
- 1.10.3
331
+ 1.10.4
data/NEWS.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # nanoc news
2
2
 
3
+ ## 4.0.0rc1 (2015-06-21)
4
+
5
+ Fixes:
6
+
7
+ * Fixed double-wrapping of `@layout` in rendering helper (#631)
8
+ * Fixed `show-rules` command (#633)
9
+
3
10
  ## 4.0.0b4 (2015-06-10)
4
11
 
5
12
  Fixes:
data/README.md CHANGED
@@ -2,13 +2,12 @@
2
2
  [![Build status](http://img.shields.io/travis/nanoc/nanoc.svg)](https://travis-ci.org/nanoc/nanoc)
3
3
  [![Code Climate](http://img.shields.io/codeclimate/github/nanoc/nanoc.svg)](https://codeclimate.com/github/nanoc/nanoc)
4
4
  [![Code Coverage](http://img.shields.io/coveralls/nanoc/nanoc.svg)](https://coveralls.io/r/nanoc/nanoc)
5
- [![Documentation Coverage](http://inch-ci.org/github/nanoc/nanoc.svg)](http://inch-ci.org/github/nanoc/nanoc/)
6
5
 
7
6
  ![nanoc logo](https://avatars1.githubusercontent.com/u/3260163?s=140)
8
7
 
9
8
  # nanoc
10
9
 
11
- nanoc is a flexible static site generator written in Ruby. See the [nanoc web site](http://nanoc.ws) for more information.
10
+ nanoc is a flexible static-site generator written in Ruby. See the [nanoc web site](http://nanoc.ws) for more information.
12
11
 
13
12
  **Please take a moment and [donate](http://pledgie.com/campaigns/9282) to nanoc. A lot of time has gone into developing nanoc, and I would like to keep it going. Your support will ensure that nanoc will continue to improve.**
14
13
 
data/Rakefile CHANGED
@@ -1,12 +1,3 @@
1
- # Set up env
2
- $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/lib'))
3
- require './test/gem_loader.rb'
1
+ Rake.add_rakelib 'tasks'
4
2
 
5
- # Load nanoc
6
- require 'nanoc'
7
-
8
- # Load tasks
9
- Dir.glob('tasks/**/*.rake').each { |r| Rake.application.add_import r }
10
-
11
- # Set default task
12
- task default: :test
3
+ task default: [:test, :rubocop]
data/TODO.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  ## Ideas
4
4
 
5
- * snapshots [name, array] is weird
6
5
  * binary snapshots could be possible
7
6
  * binary layotus could be possible
8
7
 
data/bin/nanoc CHANGED
@@ -2,4 +2,8 @@
2
2
  require 'nanoc'
3
3
  require 'nanoc/cli'
4
4
 
5
+ if File.file?('Gemfile') && !defined?(Bundler)
6
+ warn 'A Gemfile was detected, but Bundler is not loaded. This is probably not what you want. To run nanoc with Bundler, use `bundle exec nanoc`.'
7
+ end
8
+
5
9
  Nanoc::CLI.run(ARGV)
@@ -66,7 +66,7 @@ module Nanoc::Int
66
66
  update(el, digest, visited + [obj])
67
67
  digest.update(',')
68
68
  end
69
- when ::Hash
69
+ when ::Hash, ::Nanoc::Int::Configuration
70
70
  obj.each do |key, value|
71
71
  update(key, digest, visited + [obj])
72
72
  digest.update('=')
@@ -110,13 +110,10 @@ module Nanoc::Int
110
110
  return if @loaded || @loading
111
111
  @loading = true
112
112
 
113
- # Load site if necessary
114
- site.load
115
-
116
113
  # Preprocess
117
114
  rules_collection.load
118
115
  preprocess
119
- site.setup_child_parent_links
116
+ Nanoc::Int::SiteLoader.new.setup_child_parent_links(site.items)
120
117
  build_reps
121
118
  route_reps
122
119
 
@@ -143,11 +140,8 @@ module Nanoc::Int
143
140
  @stack = []
144
141
 
145
142
  items.each { |item| item.reps.clear }
146
- site.teardown_child_parent_links
147
143
  rules_collection.unload
148
144
 
149
- site.unload
150
-
151
145
  @loaded = false
152
146
  @unloading = false
153
147
  end
@@ -260,9 +254,9 @@ module Nanoc::Int
260
254
  # @api private
261
255
  def assigns_for(rep)
262
256
  if rep.binary?
263
- content_or_filename_assigns = { filename: rep.content_snapshots[:last].filename }
257
+ content_or_filename_assigns = { filename: rep.snapshot_contents[:last].filename }
264
258
  else
265
- content_or_filename_assigns = { content: rep.content_snapshots[:last].string }
259
+ content_or_filename_assigns = { content: rep.snapshot_contents[:last].string }
266
260
  end
267
261
 
268
262
  # TODO: Do not expose @site (necessary for captures store though…)
@@ -320,7 +314,7 @@ module Nanoc::Int
320
314
 
321
315
  # Assign snapshots
322
316
  reps.each do |rep|
323
- rep.snapshots = rules_collection.snapshots_for(rep)
317
+ rep.snapshot_defs = rules_collection.snapshots_defs_for(rep)
324
318
  end
325
319
 
326
320
  # Attempt to compile all active reps
@@ -373,7 +367,7 @@ module Nanoc::Int
373
367
  if !rep.item.forced_outdated? && !outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
374
368
  # Reuse content
375
369
  Nanoc::Int::NotificationCenter.post(:cached_content_used, rep)
376
- rep.content_snapshots = compiled_content_cache[rep]
370
+ rep.snapshot_contents = compiled_content_cache[rep]
377
371
  else
378
372
  # Recalculate content
379
373
  executor.snapshot(rep, :raw)
@@ -384,7 +378,7 @@ module Nanoc::Int
384
378
  end
385
379
 
386
380
  rep.compiled = true
387
- compiled_content_cache[rep] = rep.content_snapshots
381
+ compiled_content_cache[rep] = rep.snapshot_contents
388
382
 
389
383
  Nanoc::Int::NotificationCenter.post(:processing_ended, rep)
390
384
  Nanoc::Int::NotificationCenter.post(:compilation_ended, rep)
@@ -451,7 +445,7 @@ module Nanoc::Int
451
445
  checksum_store,
452
446
  compiled_content_cache,
453
447
  dependency_tracker,
454
- rule_memory_store
448
+ rule_memory_store,
455
449
  ]
456
450
  end
457
451
  end
@@ -159,7 +159,7 @@ module Nanoc::Int
159
159
  def data
160
160
  {
161
161
  edges: @graph.edges,
162
- vertices: @graph.vertices.map { |obj| obj && obj.reference }
162
+ vertices: @graph.vertices.map { |obj| obj && obj.reference },
163
163
  }
164
164
  end
165
165
 
@@ -13,6 +13,8 @@ module Nanoc::Int
13
13
  # @since 3.2.0
14
14
  attr_reader :snapshot_name
15
15
 
16
+ attr_reader :pattern
17
+
16
18
  # Creates a new item compilation rule with the given identifier regex,
17
19
  # compiler and block. The block will be called during compilation with the
18
20
  # item rep as its argument.
@@ -217,9 +217,9 @@ module Nanoc::Int
217
217
  # @return [Array] A list of snapshots, represented as arrays where the
218
218
  # first element is the snapshot name (a Symbol) and the last element is
219
219
  # a Boolean indicating whether the snapshot is final or not
220
- def snapshots_for(rep)
220
+ def snapshots_defs_for(rep)
221
221
  new_rule_memory_for_rep(rep).select { |e| e[0] == :snapshot }.map do |e|
222
- [e[1], e[2].fetch(:final) { true }]
222
+ Nanoc::Int::SnapshotDef.new(e[1], e[2].fetch(:final, true))
223
223
  end
224
224
  end
225
225
 
@@ -2,6 +2,41 @@ module Nanoc
2
2
  class Identifier
3
3
  include Comparable
4
4
 
5
+ # @api private
6
+ class InvalidIdentifierError < ::Nanoc::Error
7
+ def initialize(string)
8
+ super("Invalid identifier (does not start with a slash): #{string.inspect}")
9
+ end
10
+ end
11
+
12
+ # @api private
13
+ class InvalidTypeError < ::Nanoc::Error
14
+ def initialize(type)
15
+ super("Invalid type for identifier: #{type.inspect} (can be :full or :legacy)")
16
+ end
17
+ end
18
+
19
+ # @api private
20
+ class InvalidPrefixError < ::Nanoc::Error
21
+ def initialize(string)
22
+ super("Invalid prefix (does not start with a slash): #{string.inspect}")
23
+ end
24
+ end
25
+
26
+ # @api private
27
+ class UnsupportedLegacyOperationError < ::Nanoc::Error
28
+ def initialize
29
+ super('Cannot use this method on legacy identifiers')
30
+ end
31
+ end
32
+
33
+ # @api private
34
+ class NonCoercibleObjectError < ::Nanoc::Error
35
+ def initialize(obj)
36
+ super("#{obj.inspect} cannot be converted into a Nanoc::Identifier")
37
+ end
38
+ end
39
+
5
40
  def self.from(obj)
6
41
  case obj
7
42
  when Nanoc::Identifier
@@ -9,7 +44,7 @@ module Nanoc
9
44
  when String
10
45
  Nanoc::Identifier.new(obj)
11
46
  else
12
- raise ArgumentError, "Do not know how to convert #{obj} into a Nanoc::Identifier"
47
+ raise NonCoercibleObjectError.new(obj)
13
48
  end
14
49
  end
15
50
 
@@ -21,13 +56,11 @@ module Nanoc
21
56
  @string = "/#{string}/".gsub(/^\/+|\/+$/, '/').freeze
22
57
  when :full
23
58
  if string !~ /\A\//
24
- raise Nanoc::Int::Errors::Generic,
25
- "Invalid identifier (does not start with a slash): #{string.inspect}"
59
+ raise InvalidIdentifierError.new(string)
26
60
  end
27
61
  @string = string.dup.freeze
28
62
  else
29
- raise Nanoc::Int::Errors::Generic,
30
- "Invalid :type param for identifier: #{@type.inspect}"
63
+ raise InvalidTypeError.new(@type)
31
64
  end
32
65
  end
33
66
 
@@ -40,8 +73,8 @@ module Nanoc
40
73
  self.class.hash ^ to_s.hash
41
74
  end
42
75
 
43
- def =~(pat)
44
- Nanoc::Int::Pattern.from(pat).match?(to_s) ? 0 : nil
76
+ def =~(other)
77
+ Nanoc::Int::Pattern.from(other).match?(to_s) ? 0 : nil
45
78
  end
46
79
 
47
80
  def <=>(other)
@@ -60,15 +93,14 @@ module Nanoc
60
93
  end
61
94
 
62
95
  # @return [String]
63
- def +(string)
64
- to_s + string
96
+ def +(other)
97
+ to_s + other
65
98
  end
66
99
 
67
100
  # @return [Nanoc::Identifier]
68
101
  def prefix(string)
69
102
  if string !~ /\A\//
70
- raise Nanoc::Int::Errors::Generic,
71
- "Invalid prefix (does not start with a slash): #{@string.inspect}"
103
+ raise InvalidPrefixError.new(@string)
72
104
  end
73
105
  Nanoc::Identifier.new(string.sub(/\/+\z/, '') + @string, type: @type)
74
106
  end
@@ -76,8 +108,7 @@ module Nanoc
76
108
  # @return [String]
77
109
  def with_ext(ext)
78
110
  unless full?
79
- raise Nanoc::Int::Errors::Generic,
80
- 'Cannot use #with_ext on identifier that does not include the file extension'
111
+ raise UnsupportedLegacyOperationError
81
112
  end
82
113
 
83
114
  # Strip extension, if any
@@ -109,8 +140,7 @@ module Nanoc
109
140
  # @return [String] The extension, without a leading dot.
110
141
  def ext
111
142
  unless full?
112
- raise Nanoc::Int::Errors::Generic,
113
- 'Cannot use #ext on identifier that does not include the file extension'
143
+ raise UnsupportedLegacyOperationError
114
144
  end
115
145
 
116
146
  s = File.extname(@string)
@@ -41,6 +41,10 @@ module Nanoc::Int
41
41
  def captures(_identifier)
42
42
  nil
43
43
  end
44
+
45
+ def to_s
46
+ @string
47
+ end
44
48
  end
45
49
 
46
50
  # @api private
@@ -57,5 +61,9 @@ module Nanoc::Int
57
61
  matches = @regexp.match(identifier.to_s)
58
62
  matches && matches.captures
59
63
  end
64
+
65
+ def to_s
66
+ @regexp.to_s
67
+ end
60
68
  end
61
69
  end
@@ -0,0 +1,16 @@
1
+ module Nanoc
2
+ module Int
3
+ class SnapshotDef
4
+ attr_reader :name
5
+
6
+ def initialize(name, is_final)
7
+ @name = name
8
+ @is_final = is_final
9
+ end
10
+
11
+ def final?
12
+ @is_final
13
+ end
14
+ end
15
+ end
16
+ end
@@ -3,3 +3,4 @@ require_relative 'entities/document'
3
3
  require_relative 'entities/identifier'
4
4
  require_relative 'entities/layout'
5
5
  require_relative 'entities/pattern'
6
+ require_relative 'entities/snapshot_def'
@@ -183,7 +183,7 @@ module Nanoc::Int
183
183
  plugins << {
184
184
  class: klass,
185
185
  superclass: superclass,
186
- identifiers: [identifier]
186
+ identifiers: [identifier],
187
187
  }
188
188
  end
189
189
  end
@@ -0,0 +1,67 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class ConfigLoader
4
+ class NoConfigFileFoundError < ::Nanoc::Error
5
+ def initialize
6
+ super('No configuration file found')
7
+ end
8
+ end
9
+
10
+ class NoParentConfigFileFoundError < ::Nanoc::Error
11
+ def initialize(filename)
12
+ super("There is no parent configuration file at #{filename}")
13
+ end
14
+ end
15
+
16
+ class CyclicalConfigFileError < ::Nanoc::Error
17
+ def initialize(filename)
18
+ super("The parent configuration file at #{filename} includes one of its descendants")
19
+ end
20
+ end
21
+
22
+ # @return [Boolean]
23
+ def self.cwd_is_nanoc_site?
24
+ !config_filename_for_cwd.nil?
25
+ end
26
+
27
+ # @return [String]
28
+ def self.config_filename_for_cwd
29
+ filenames = %w( nanoc.yaml config.yaml )
30
+ candidate = filenames.find { |f| File.file?(f) }
31
+ candidate && File.expand_path(candidate)
32
+ end
33
+
34
+ def new_from_cwd
35
+ # Determine path
36
+ filename = self.class.config_filename_for_cwd
37
+ raise NoConfigFileFoundError if filename.nil?
38
+
39
+ # Read
40
+ apply_parent_config(
41
+ Nanoc::Int::Configuration.new(YAML.load_file(filename)),
42
+ [filename]).with_defaults
43
+ end
44
+
45
+ # @api private
46
+ def apply_parent_config(config, processed_paths = [])
47
+ parent_path = config[:parent_config_file]
48
+ return config if parent_path.nil?
49
+
50
+ # Get absolute path
51
+ parent_path = File.absolute_path(parent_path, File.dirname(processed_paths.last))
52
+ unless File.file?(parent_path)
53
+ raise NoParentConfigFileFoundError.new(parent_path)
54
+ end
55
+
56
+ # Check recursion
57
+ if processed_paths.include?(parent_path)
58
+ raise CyclicalConfigFileError.new(parent_path)
59
+ end
60
+
61
+ # Load
62
+ parent_config = Nanoc::Int::Configuration.new(YAML.load_file(parent_path))
63
+ full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path])
64
+ full_parent_config.merge(config.without(:parent_config_file))
65
+ end
66
+ end
67
+ end