nanoc 3.6.11 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a730bbd1983d87218d076f836977767199ef701
4
- data.tar.gz: 7bb2110b44c0d6d2e9819b00a903d5e7de9f8234
3
+ metadata.gz: e05fb6e57e3ddbb81bd5170426bfcc2ce3430f31
4
+ data.tar.gz: 9c19214f41958e9dd43fdc7f5b1c0db914edde74
5
5
  SHA512:
6
- metadata.gz: bbc3e89e3c6d901a0c7482d8f52db5574d08f6a2e5e9655cc94dcc83085b56dc18825546af3e5c66bb03b219414dab87dc289ac4954edae25a5f53b6ee8b6ae7
7
- data.tar.gz: 2878543090973ca8832c17352d360edcb966d1d701307df6846735a529de0ea65493702d1c7ddb666a55fa9973fae80d58d8ba6b29f2a1c466920d44193bdafd
6
+ metadata.gz: 0bc2ef4f92b9db37fb96ef5359f6b75df606c682db3269910c35044889275f43dd92ae2f13d8d11af4afbcd762a7f73823db7ad633ccacf0cef0c46ab4b88197
7
+ data.tar.gz: f8dac777eb295e619fa854cdad8dcf5dbfb57b671b7561697b16a52234b5c561cf87bea85eba92aa0819e3da7ce29069f2ad8839ab5d0029c756833909e3a92e
data/Gemfile CHANGED
@@ -13,6 +13,7 @@ gem 'builder'
13
13
  gem 'coderay'
14
14
  gem 'compass'
15
15
  gem 'coffee-script'
16
+ gem 'coveralls', :require => false
16
17
  gem 'erubis'
17
18
  gem 'fog', :platforms => ruby_19_plus
18
19
  gem 'haml'
@@ -37,6 +38,7 @@ gem 'rdiscount', :platforms => [:ruby, :mswin]
37
38
  gem 'rdoc'
38
39
  gem 'redcarpet', :platforms => ruby_19_plus_without_jruby + [:mswin]
39
40
  gem 'RedCloth'
41
+ gem 'rouge'
40
42
  gem 'rubocop', :platforms => ruby_19_plus
41
43
  gem 'rubypants'
42
44
  gem 'sass', '~> 3.2.2'
data/Gemfile.lock CHANGED
@@ -1,26 +1,21 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nanoc (3.6.11)
4
+ nanoc (3.7.0)
5
5
  cri (~> 2.3)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  RedCloth (4.2.9)
11
- RedCloth (4.2.9-java)
12
11
  addressable (2.3.6)
13
12
  adsf (1.2.0)
14
13
  rack (>= 1.0.0)
15
- allison (2.0.3)
16
14
  ast (2.0.0)
17
15
  bluecloth (2.2.0)
18
16
  builder (3.2.2)
19
17
  celluloid (0.15.2)
20
18
  timers (~> 1.1.0)
21
- celluloid-io (0.15.0)
22
- celluloid (>= 0.15.0)
23
- nio4r (>= 0.5.0)
24
19
  chunky_png (1.3.1)
25
20
  coderay (1.1.0)
26
21
  coffee-script (2.2.0)
@@ -33,24 +28,26 @@ GEM
33
28
  chunky_png (~> 1.2)
34
29
  fssm (>= 0.2.7)
35
30
  sass (~> 3.2.19)
31
+ coveralls (0.7.0)
32
+ multi_json (~> 1.3)
33
+ rest-client
34
+ simplecov (>= 0.7)
35
+ term-ansicolor
36
+ thor
36
37
  crack (0.4.2)
37
38
  safe_yaml (~> 1.0.0)
38
- cri (2.6.0)
39
+ cri (2.6.1)
39
40
  colored (~> 1.2)
40
- echoe (4.6.5)
41
- allison (>= 2.0.3)
42
- rake (>= 0.9.2)
43
- rdoc (>= 2.5.11)
44
- rubyforge (>= 2.0.4)
41
+ docile (1.1.3)
45
42
  erubis (2.7.0)
46
- excon (0.33.0)
47
- execjs (2.0.2)
43
+ excon (0.36.0)
44
+ execjs (2.2.0)
48
45
  ffi (1.9.3)
49
- ffi (1.9.3-java)
50
- fog (1.22.0)
46
+ fog (1.22.1)
51
47
  fog-brightbox
52
- fog-core (~> 1.21, >= 1.21.1)
48
+ fog-core (~> 1.22)
53
49
  fog-json
50
+ ipaddress (~> 0.5)
54
51
  nokogiri (~> 1.5, >= 1.5.11)
55
52
  fog-brightbox (0.0.2)
56
53
  fog-core
@@ -64,7 +61,7 @@ GEM
64
61
  net-ssh (>= 2.1.3)
65
62
  fog-json (1.0.0)
66
63
  multi_json (~> 1.0)
67
- formatador (0.2.4)
64
+ formatador (0.2.5)
68
65
  fssm (0.2.10)
69
66
  haml (4.0.5)
70
67
  tilt
@@ -72,39 +69,33 @@ GEM
72
69
  handlebars-source (~> 1.3.0)
73
70
  therubyracer (~> 0.12.0)
74
71
  handlebars-source (1.3.0)
72
+ ipaddress (0.8.0)
75
73
  json (1.8.1)
76
- json (1.8.1-java)
77
- json_pure (1.8.1)
78
74
  kramdown (1.3.3)
79
- less (2.5.0)
75
+ less (2.6.0)
80
76
  commonjs (~> 0.2.7)
81
77
  libv8 (3.16.14.3)
82
- listen (2.7.4)
78
+ listen (2.7.7)
83
79
  celluloid (>= 0.15.2)
84
- celluloid-io (>= 0.15.0)
85
80
  rb-fsevent (>= 0.9.3)
86
81
  rb-inotify (>= 0.9)
87
82
  markaby (0.8.0)
88
83
  builder
89
- maruku (0.7.1)
84
+ maruku (0.7.2)
90
85
  metaclass (0.0.4)
91
86
  method_source (0.8.2)
92
- mime-types (2.2)
93
- mini_portile (0.5.3)
87
+ mime-types (2.3)
88
+ mini_portile (0.6.0)
94
89
  minitest (4.7.5)
95
- mocha (1.0.0)
90
+ mocha (1.1.0)
96
91
  metaclass (~> 0.0.1)
97
- multi_json (1.10.0)
92
+ multi_json (1.10.1)
98
93
  mustache (0.99.5)
99
94
  net-scp (1.2.1)
100
95
  net-ssh (>= 2.6.5)
101
- net-ssh (2.9.0)
102
- nio4r (1.0.0)
103
- nio4r (1.0.0-java)
104
- nokogiri (1.6.1)
105
- mini_portile (~> 0.5.0)
106
- nokogiri (1.6.1-java)
107
- mini_portile (~> 0.5.0)
96
+ net-ssh (2.9.1)
97
+ nokogiri (1.6.2.1)
98
+ mini_portile (= 0.6.0)
108
99
  pandoc-ruby (0.7.5)
109
100
  parser (2.1.9)
110
101
  ast (>= 1.1, < 3.0)
@@ -115,69 +106,70 @@ GEM
115
106
  coderay (~> 1.0)
116
107
  method_source (~> 0.8)
117
108
  slop (~> 3.4)
118
- pry (0.9.12.6-java)
119
- coderay (~> 1.0)
120
- method_source (~> 0.8)
121
- slop (~> 3.4)
122
- spoon (~> 0.0)
123
109
  pygments.rb (0.5.4)
124
110
  posix-spawn (~> 0.3.6)
125
111
  yajl-ruby (~> 1.1.0)
126
112
  rack (1.5.2)
127
113
  rainbow (2.0.0)
128
114
  rainpress (1.0)
129
- echoe
130
- rake (10.3.1)
115
+ rake (10.3.2)
131
116
  rb-fsevent (0.9.4)
132
- rb-inotify (0.9.4)
117
+ rb-inotify (0.9.5)
133
118
  ffi (>= 0.5.0)
134
119
  rdiscount (2.1.7.1)
135
120
  rdoc (4.1.1)
136
121
  json (~> 1.4)
137
- redcarpet (3.1.1)
122
+ redcarpet (3.1.2)
138
123
  ref (1.0.5)
139
- rubocop (0.21.0)
124
+ rest-client (1.6.7)
125
+ mime-types (>= 1.16)
126
+ rouge (1.4.0)
127
+ rubocop (0.23.0)
140
128
  json (>= 1.7.7, < 2)
141
129
  parser (~> 2.1.9)
142
130
  powerpack (~> 0.0.6)
143
131
  rainbow (>= 1.99.1, < 3.0)
144
132
  ruby-progressbar (~> 1.4)
145
- ruby-progressbar (1.4.2)
146
- rubyforge (2.0.4)
147
- json_pure (>= 1.1.7)
133
+ ruby-progressbar (1.5.1)
148
134
  rubypants (0.2.0)
149
135
  safe_yaml (1.0.3)
150
136
  sass (3.2.19)
137
+ simplecov (0.8.2)
138
+ docile (~> 1.1.0)
139
+ multi_json
140
+ simplecov-html (~> 0.8.0)
141
+ simplecov-html (0.8.0)
151
142
  slim (2.0.2)
152
143
  temple (~> 0.6.6)
153
144
  tilt (>= 1.3.3, < 2.1)
154
145
  slop (3.5.0)
155
- spoon (0.0.4)
156
- ffi
157
146
  temple (0.6.7)
147
+ term-ansicolor (1.3.0)
148
+ tins (~> 1.0)
158
149
  therubyracer (0.12.1)
159
150
  libv8 (~> 3.16.14.0)
160
151
  ref
152
+ thor (0.19.1)
161
153
  tilt (2.0.1)
162
154
  timers (1.1.0)
155
+ tins (1.3.0)
163
156
  typogruby (1.0.16)
164
157
  rubypants
165
158
  uglifier (2.5.0)
166
159
  execjs (>= 0.3.0)
167
160
  json (>= 1.8.0)
168
- vcr (2.9.0)
161
+ vcr (2.9.2)
169
162
  w3c_validators (1.2)
170
163
  json
171
164
  nokogiri
172
- webmock (1.17.4)
173
- addressable (>= 2.2.7)
165
+ webmock (1.18.0)
166
+ addressable (>= 2.3.6)
174
167
  crack (>= 0.3.2)
175
168
  yajl-ruby (1.1.0)
176
169
  yard (0.8.7.4)
177
170
  yuicompressor (1.3.3)
178
171
 
179
172
  PLATFORMS
180
- java
181
173
  ruby
182
174
 
183
175
  DEPENDENCIES
@@ -189,6 +181,7 @@ DEPENDENCIES
189
181
  coderay
190
182
  coffee-script
191
183
  compass
184
+ coveralls
192
185
  erubis
193
186
  fog
194
187
  haml
@@ -213,6 +206,7 @@ DEPENDENCIES
213
206
  rdiscount
214
207
  rdoc
215
208
  redcarpet
209
+ rouge
216
210
  rubocop
217
211
  rubypants
218
212
  sass (~> 3.2.2)
data/NEWS.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # nanoc news
2
2
 
3
+ ## 3.7.0 (2014-06-08)
4
+
5
+ New features:
6
+
7
+ * Allowed excluding links from the internal links check (`@config[:checks][:internal_links][:exclude]`) (#242) [Remko Tronçon]
8
+ * Added Rouge syntax coloring filter (#398) [Guilherme Garnier]
9
+ * Backported `after_setup` from nanoc 4 to make it easier to create CLI plugins (#407) [Rémi Barraquand]
10
+ * Make lib dirs configurable using `lib_dirs` config attribute (#424) [Gregory Pakosz]
11
+ * Added support for setting parent config dir using `parent_config_file` config attribute (#419) [Gregory Pakosz]
12
+
13
+ Enhancements:
14
+
15
+ * Added `:with_toc` support to RedCarpet (#222, #232)
16
+ * Added `slim` to the list of text extensions (#316)
17
+ * Made `content/` and `layouts/` dirs configurable (#412) [Gregory Pakosz]
18
+ * Allowed included rules files to have their own preprocess block (#420) [Gregory Pakosz]
19
+
20
+ Fixes:
21
+
22
+ * Fixed bug which caused temporary directories not to be removed (#440, #444)
23
+
3
24
  ## 3.6.11 (2014-05-09)
4
25
 
5
26
  Identical to 3.6.10 but published with corrected release notes.
data/bin/nanoc CHANGED
@@ -4,6 +4,7 @@
4
4
  # Try loading bundler if it's possible
5
5
  begin
6
6
  require 'bundler/setup'
7
+ Bundler.require(:default)
7
8
  rescue LoadError
8
9
  # no problem
9
10
  end
@@ -191,12 +191,13 @@ module Nanoc
191
191
  end
192
192
  memoize :dependency_tracker
193
193
 
194
- # Runs the preprocessor.
194
+ # Runs the preprocessors.
195
195
  #
196
196
  # @api private
197
197
  def preprocess
198
- return if rules_collection.preprocessor.nil?
199
- preprocessor_context.instance_eval(&rules_collection.preprocessor)
198
+ rules_collection.preprocessors.each_value do |preprocessor|
199
+ preprocessor_context.instance_eval(&preprocessor)
200
+ end
200
201
  end
201
202
 
202
203
  # Returns all objects managed by the site (items, layouts, code snippets,
@@ -5,6 +5,11 @@ module Nanoc
5
5
  # Contains methods that will be executed by the site’s `Rules` file.
6
6
  class CompilerDSL
7
7
 
8
+ # The current rules filename.
9
+ #
10
+ # @return [String] The current rules filename.
11
+ attr_accessor :rules_filename
12
+
8
13
  # Creates a new compiler DSL for the given collection of rules.
9
14
  #
10
15
  # @api private
@@ -25,12 +30,11 @@ module Nanoc
25
30
  #
26
31
  # @return [void]
27
32
  def preprocess(&block)
28
- if @rules_collection.preprocessor
33
+ if @rules_collection.preprocessors[rules_filename]
29
34
  warn 'WARNING: A preprocess block is already defined. Defining ' \
30
35
  'another preprocess block overrides the previously one.'
31
36
  end
32
-
33
- @rules_collection.preprocessor = block
37
+ @rules_collection.preprocessors[rules_filename] = block
34
38
  end
35
39
 
36
40
  # Creates a compilation rule for all items whose identifier match the
@@ -246,7 +250,7 @@ module Nanoc
246
250
  filename = [ "#{name}", "#{name}.rb", "./#{name}", "./#{name}.rb" ].find { |f| File.file?(f) }
247
251
  raise Nanoc::Errors::NoRulesFileFound.new if filename.nil?
248
252
 
249
- instance_eval(File.read(filename), filename)
253
+ @rules_collection.parse(filename)
250
254
  end
251
255
 
252
256
  private
@@ -28,17 +28,21 @@ module Nanoc
28
28
  # @return [Hash] The layout-to-filter mapping rules
29
29
  attr_reader :layout_filter_mapping
30
30
 
31
- # @return [Proc] The code block that will be executed after all data is
32
- # loaded but before the site is compiled
33
- attr_accessor :preprocessor
31
+ # The hash containing preprocessor code blocks that will be executed after
32
+ # all data is loaded but before the site is compiled.
33
+ #
34
+ # @return [Hash] The hash containing the preprocessor code blocks that will
35
+ # be executed after all data is loaded but before the site is compiled
36
+ attr_accessor :preprocessors
34
37
 
35
38
  # @param [Nanoc::Compiler] compiler The site’s compiler
36
39
  def initialize(compiler)
37
40
  @compiler = compiler
38
41
 
39
- @item_compilation_rules = []
40
- @item_routing_rules = []
41
- @layout_filter_mapping = OrderedHash.new
42
+ @item_compilation_rules = []
43
+ @item_routing_rules = []
44
+ @layout_filter_mapping = OrderedHash.new
45
+ @preprocessors = OrderedHash.new
42
46
  end
43
47
 
44
48
  # Add the given rule to the list of item compilation rules.
@@ -76,20 +80,29 @@ module Nanoc
76
80
  rules_filename = rules_filenames.find { |f| File.file?(f) }
77
81
  raise Nanoc::Errors::NoRulesFileFound.new if rules_filename.nil?
78
82
 
83
+ parse(rules_filename)
84
+ end
85
+
86
+ def parse(rules_filename)
87
+ rules_filename = File.absolute_path(rules_filename)
88
+
79
89
  # Get rule data
80
90
  @data = File.read(rules_filename)
81
91
 
82
- # Load DSL
83
- dsl.instance_eval(@data, "./#{rules_filename}")
92
+ old_rules_filename = dsl.rules_filename
93
+ dsl.rules_filename = rules_filename
94
+ dsl.instance_eval(@data, rules_filename)
95
+ dsl.rules_filename = old_rules_filename
84
96
  end
85
97
 
86
98
  # Unloads this site’s rules.
87
99
  #
88
100
  # @return [void]
89
101
  def unload
90
- @item_compilation_rules = []
91
- @item_routing_rules = []
92
- @layout_filter_mapping = OrderedHash.new
102
+ @item_compilation_rules = []
103
+ @item_routing_rules = []
104
+ @layout_filter_mapping = OrderedHash.new
105
+ @preprocessors = OrderedHash.new
93
106
  end
94
107
 
95
108
  # Finds the first matching compilation rule for the given item
@@ -58,7 +58,7 @@ module Nanoc
58
58
  @site = site
59
59
  @items_root = items_root
60
60
  @layouts_root = layouts_root
61
- @config = config
61
+ @config = config || {}
62
62
 
63
63
  @references = 0
64
64
  end
@@ -32,7 +32,8 @@ module Nanoc
32
32
  # that lacks some options, the default value will be taken from
33
33
  # `DEFAULT_CONFIG`.
34
34
  DEFAULT_CONFIG = {
35
- :text_extensions => %w( css erb haml htm html js less markdown md php rb sass scss txt xhtml xml coffee hb handlebars mustache ms ).sort,
35
+ :text_extensions => %w( css erb haml htm html js less markdown md php rb sass scss txt xhtml xml coffee hb handlebars mustache ms slim ).sort,
36
+ :lib_dirs => %w( lib ),
36
37
  :output_dir => 'output',
37
38
  :data_sources => [ {} ],
38
39
  :index_filenames => [ 'index.html' ],
@@ -305,11 +306,15 @@ module Nanoc
305
306
  @code_snippets_loaded = true
306
307
 
307
308
  # Get code snippets
308
- @code_snippets = Dir['lib/**/*.rb'].sort.map do |filename|
309
- Nanoc::CodeSnippet.new(
310
- File.read(filename),
311
- filename
312
- )
309
+ @code_snippets = []
310
+ config[:lib_dirs].each do |lib|
311
+ code_snippets = Dir["#{lib}/**/*.rb"].sort.map do |filename|
312
+ Nanoc::CodeSnippet.new(
313
+ File.read(filename),
314
+ filename
315
+ )
316
+ end
317
+ @code_snippets.concat(code_snippets)
313
318
  end
314
319
 
315
320
  # Execute code snippets
@@ -350,6 +355,29 @@ module Nanoc
350
355
  end
351
356
  end
352
357
 
358
+ # Loads a configuration file.
359
+ def load_config(config_path)
360
+ YAML.load_file(config_path).symbolize_keys_recursively
361
+ end
362
+
363
+ def apply_parent_config(config, config_paths = [])
364
+ parent_config_file = config[:parent_config_file]
365
+ if parent_config_file
366
+ config.delete(:parent_config_file)
367
+ config_path = File.absolute_path(parent_config_file, File.dirname(config_paths.last))
368
+ if !File.file?(config_path)
369
+ raise Nanoc::Errors::GenericTrivial, "Could not find parent configuration file '#{parent_config_file}'"
370
+ end
371
+ if config_paths.include?(config_path)
372
+ raise Nanoc::Errors::GenericTrivial, "Cycle detected. Could not use parent configuration file '#{parent_config_file}'"
373
+ end
374
+ parent_config = load_config(config_path)
375
+ apply_parent_config(parent_config, config_paths + [config_path]).merge(config)
376
+ else
377
+ config
378
+ end
379
+ end
380
+
353
381
  def ensure_identifier_uniqueness(objects, type)
354
382
  seen = Set.new
355
383
  objects.each do |obj|
@@ -375,22 +403,24 @@ module Nanoc
375
403
  if filename.nil?
376
404
  raise Nanoc::Errors::GenericTrivial, 'Could not find nanoc.yaml or config.yaml in the current working directory'
377
405
  end
378
- File.join(dir_or_config_hash, filename)
406
+ File.absolute_path(filename, dir_or_config_hash)
379
407
  end
380
- @config = DEFAULT_CONFIG.merge(YAML.load_file(config_path).symbolize_keys_recursively)
381
- @config[:data_sources].map! { |ds| ds.symbolize_keys_recursively }
408
+
409
+ @config = apply_parent_config(load_config(config_path), [config_path])
382
410
  else
383
411
  # Use passed config hash
384
- @config = DEFAULT_CONFIG.merge(dir_or_config_hash)
412
+ @config = apply_parent_config(dir_or_config_hash.symbolize_keys_recursively)
385
413
  end
386
414
 
415
+ # Merge config with default config
416
+ @config = DEFAULT_CONFIG.merge(@config)
417
+
387
418
  # Merge data sources with default data source config
388
419
  @config[:data_sources] = @config[:data_sources].map { |ds| DEFAULT_DATA_SOURCE_CONFIG.merge(ds) }
389
420
 
390
421
  # Convert to proper configuration
391
422
  @config = Nanoc::Configuration.new(@config)
392
423
  end
393
-
394
424
  end
395
425
 
396
426
  end
@@ -46,6 +46,10 @@ module Nanoc
46
46
  end
47
47
 
48
48
  @counts.delete(prefix)
49
+
50
+ if @counts.empty? && File.directory?(@root_dir)
51
+ FileUtils.remove_entry_secure(@root_dir)
52
+ end
49
53
  end
50
54
 
51
55
  end
data/lib/nanoc/cli.rb CHANGED
@@ -74,6 +74,14 @@ module Nanoc::CLI
74
74
  root_command.add_command(cmd)
75
75
  end
76
76
 
77
+ # Schedules the given block to be executed after the CLI has been set up.
78
+ #
79
+ # @return [void]
80
+ def self.after_setup(&block)
81
+ # TODO decide what should happen if the CLI is already set up
82
+ self.add_after_setup_proc(block)
83
+ end
84
+
77
85
  protected
78
86
 
79
87
  # Makes the commandline interface ready for use.
@@ -83,6 +91,7 @@ protected
83
91
  setup_cleaning_streams
84
92
  setup_commands
85
93
  load_custom_commands
94
+ after_setup_procs.each { |b| b.call }
86
95
  end
87
96
 
88
97
  # Sets up the root command and base subcommands.
@@ -207,4 +216,13 @@ protected
207
216
  true
208
217
  end
209
218
 
219
+ def self.after_setup_procs
220
+ @after_setup_procs || []
221
+ end
222
+
223
+ def self.add_after_setup_proc(proc)
224
+ @after_setup_procs ||= []
225
+ @after_setup_procs << proc
226
+ end
227
+
210
228
  end
@@ -85,8 +85,20 @@ data_sources:
85
85
  # it will become “/about.html/” instead.
86
86
  allow_periods_in_identifiers: false
87
87
 
88
- # The default encoding for all files in `content/` and `layouts/`.
88
+ # The encoding to use for input files. If your input files are not in
89
+ # UTF-8 (which they should be!), change this.
89
90
  encoding: utf-8
91
+
92
+ # Configuration for the “check” command, which run unit tests on the site.
93
+ checks:
94
+ # Configuration for the “internal_links” checker, which checks whether all
95
+ # internal links are valid.
96
+ internal_links:
97
+ # A list of patterns, specified as regular expressions, to exclude from the check.
98
+ # If an internal link matches this pattern, the validity check will be skipped.
99
+ # E.g.:
100
+ # exclude: ['^/server_status']
101
+ exclude: []
90
102
  EOS
91
103
 
92
104
  DEFAULT_RULES = <<EOS unless defined? DEFAULT_RULES
@@ -23,10 +23,18 @@ module Nanoc::DataSources
23
23
  def down
24
24
  end
25
25
 
26
+ def content_dir_name
27
+ config.fetch(:content_dir, 'content')
28
+ end
29
+
30
+ def layouts_dir_name
31
+ config.fetch(:layouts_dir, 'layouts')
32
+ end
33
+
26
34
  # See {Nanoc::DataSource#setup}.
27
35
  def setup
28
36
  # Create directories
29
- %w( content layouts ).each do |dir|
37
+ [ content_dir_name, layouts_dir_name ].each do |dir|
30
38
  FileUtils.mkdir_p(dir)
31
39
  vcs.add(dir)
32
40
  end
@@ -34,22 +42,22 @@ module Nanoc::DataSources
34
42
 
35
43
  # See {Nanoc::DataSource#items}.
36
44
  def items
37
- load_objects('content', 'item', Nanoc::Item)
45
+ load_objects(content_dir_name, 'item', Nanoc::Item)
38
46
  end
39
47
 
40
48
  # See {Nanoc::DataSource#layouts}.
41
49
  def layouts
42
- load_objects('layouts', 'layout', Nanoc::Layout)
50
+ load_objects(layouts_dir_name, 'layout', Nanoc::Layout)
43
51
  end
44
52
 
45
53
  # See {Nanoc::DataSource#create_item}.
46
54
  def create_item(content, attributes, identifier, params = {})
47
- create_object('content', content, attributes, identifier, params)
55
+ create_object(content_dir_name, content, attributes, identifier, params)
48
56
  end
49
57
 
50
58
  # See {Nanoc::DataSource#create_layout}.
51
59
  def create_layout(content, attributes, identifier, params = {})
52
- create_object('layouts', content, attributes, identifier, params)
60
+ create_object(layouts_dir_name, content, attributes, identifier, params)
53
61
  end
54
62
 
55
63
  protected
@@ -5,8 +5,15 @@ module Nanoc::DataSources
5
5
  # The filesystem_unified data source stores its items and layouts in nested
6
6
  # directories. Items and layouts are represented by one or two files; if it
7
7
  # is represented using one file, the metadata can be contained in this file.
8
- # The root directory for items is the `content` directory; for layouts, this
9
- # is the `layouts` directory.
8
+ #
9
+ # The default root directory for items is the `content` directory; for
10
+ # layouts, this is the `layouts` directory. This can be overridden
11
+ # in the data source configuration:
12
+ #
13
+ # data_sources:
14
+ # - type: filesystem_unified
15
+ # content_dir: items
16
+ # layouts_dir: layouts
10
17
  #
11
18
  # The metadata for items and layouts can be stored in a separate file with
12
19
  # the same base name but with the `.yaml` extension. If such a file is
@@ -17,9 +17,9 @@ module Nanoc::DataSources
17
17
  # The default data source directory is `static/`, but this can be overridden
18
18
  # in the data source configuration:
19
19
  #
20
- # data_sources:
21
- # - type: static
22
- # prefix: assets
20
+ # data_sources:
21
+ # - type: static
22
+ # prefix: assets
23
23
  #
24
24
  # Unless the `hide_items` configuration attribute is false, items from static
25
25
  # data sources will have the :is_hidden attribute set by default, which will
@@ -9,6 +9,9 @@ module Nanoc::Extra::Checking::Checks
9
9
 
10
10
  # Starts the validator. The results will be printed to stdout.
11
11
  #
12
+ # Internal links that match a regexp pattern in `@config[:checks][:internal_links][:exclude]` will
13
+ # be skipped.
14
+ #
12
15
  # @return [void]
13
16
  def run
14
17
  # TODO de-duplicate this (duplicated in external links check)
@@ -32,6 +35,9 @@ module Nanoc::Extra::Checking::Checks
32
35
  # FIXME this is ugly and won’t always be correct
33
36
  return true if href == '.'
34
37
 
38
+ # Skip hrefs that are specified in the exclude configuration
39
+ return true if self.excluded?(href)
40
+
35
41
  # Remove target
36
42
  path = href.sub(/#.*$/, '')
37
43
  return true if path.empty?
@@ -60,6 +66,11 @@ module Nanoc::Extra::Checking::Checks
60
66
  false
61
67
  end
62
68
 
69
+ def excluded?(href)
70
+ excludes = @site.config.fetch(:checks, {}).fetch(:internal_links, {}).fetch(:exclude, [])
71
+ excludes.any? { |pattern| Regexp.new(pattern).match(href) }
72
+ end
73
+
63
74
  end
64
75
 
65
76
  end
@@ -23,7 +23,15 @@ module Nanoc::Extra::Deployers
23
23
 
24
24
  # Default rsync options
25
25
  DEFAULT_OPTIONS = [
26
- '-glpPrtvz',
26
+ '--group',
27
+ '--links',
28
+ '--perms',
29
+ '--partial',
30
+ '--progress',
31
+ '--recursive',
32
+ '--times',
33
+ '--verbose',
34
+ '--compress',
27
35
  '--exclude=".hg"',
28
36
  '--exclude=".svn"',
29
37
  '--exclude=".git"'
@@ -34,6 +34,7 @@ module Nanoc::Filters
34
34
  # * `:pygmentsrb` for [pygments.rb](https://github.com/tmm1/pygments.rb),
35
35
  # a Ruby interface for [Pygments](http://pygments.org/)
36
36
  # * `:simon_highlight` for [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html)
37
+ # * `:rouge` for [Rouge](https://github.com/jayferd/rouge/)
37
38
  #
38
39
  # Additional colorizer implementations are welcome!
39
40
  #
@@ -315,9 +316,50 @@ module Nanoc::Filters
315
316
  element.swap div_outer
316
317
  end
317
318
 
319
+ # Runs the content through [Rouge](https://github.com/jayferd/rouge/.
320
+ #
321
+ # @api private
322
+ #
323
+ # @param [String] code The code to colorize
324
+ #
325
+ # @param [String] language The language the code is written in
326
+ #
327
+ # @return [String] The colorized output
328
+ def rouge(code, language, params = {})
329
+ require 'rouge'
330
+
331
+ formatter_options = {
332
+ :css_class => params.fetch(:css_class, 'highlight'),
333
+ }
334
+ formatter = Rouge::Formatters::HTML.new(formatter_options)
335
+ lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText
336
+ formatter.format(lexer.lex(code))
337
+ end
338
+
339
+ # Removes the double wrapping.
340
+ #
341
+ # Before:
342
+ #
343
+ # <pre><code class="language-ruby"><pre><code class="highlight">
344
+ #
345
+ # After:
346
+ #
347
+ # <pre><code class="language-ruby highlight">
348
+ def rouge_postprocess(language, element)
349
+ return if element.name != 'pre'
350
+
351
+ code1 = element.xpath('code').first
352
+ return if code1.nil?
353
+ code2 = code1.xpath('pre/code').first
354
+ return if code2.nil?
355
+
356
+ code1.inner_html = code2.inner_html
357
+ code1['class'] = [ code1['class'], code2['class'] ].compact.join(' ')
358
+ end
359
+
318
360
  protected
319
361
 
320
- KNOWN_COLORIZERS = [ :coderay, :dummy, :pygmentize, :pygmentsrb, :simon_highlight ]
362
+ KNOWN_COLORIZERS = [ :coderay, :dummy, :pygmentize, :pygmentsrb, :simon_highlight, :rouge ]
321
363
 
322
364
  # Removes the first blank lines and any whitespace at the end.
323
365
  def strip(s)
@@ -38,26 +38,47 @@ module Nanoc::Filters
38
38
  # @option params [Hash] :renderer_options ({}) A list of options to pass
39
39
  # on to the Redcarpet renderer
40
40
  #
41
+ # @option params [Boolean] :with_toc (false) A boolean to request a table
42
+ # of contents
43
+
41
44
  # @return [String] The filtered content
42
45
  def run(content, params = {})
43
46
  if ::Redcarpet::VERSION > '2'
44
- options = params[:options] || {}
45
- renderer_class = params[:renderer] || ::Redcarpet::Render::HTML
46
- renderer_options = params[:renderer_options] || {}
47
+ options = params.fetch(:options, {})
48
+ renderer_class = params.fetch(:renderer, ::Redcarpet::Render::HTML)
49
+ renderer_options = params.fetch(:renderer_options, {})
50
+ with_toc = params.fetch(:with_toc, false)
47
51
 
48
52
  if options.is_a?(Array)
49
53
  warn 'WARNING: You are passing an array of options to the :redcarpet filter, but Redcarpet 2.x expects a hash instead. This will likely fail.'
50
54
  end
51
55
 
56
+ # Setup TOC
57
+ if with_toc
58
+ unless renderer_class <= ::Redcarpet::Render::HTML
59
+ raise "Unexpected renderer: #{renderer_class}"
60
+ end
61
+
62
+ # `with_toc` implies `with_toc_data` for the HTML renderer
63
+ renderer_options[:with_toc_data] = true
64
+ end
65
+
66
+ # Create renderer
52
67
  if renderer_class == ::Redcarpet::Render::HTML_TOC
53
68
  renderer = renderer_class.new
54
69
  else
55
70
  renderer = renderer_class.new(renderer_options)
56
71
  end
57
- ::Redcarpet::Markdown.new(renderer, options).render(content)
58
- else
59
- options = params[:options] || []
60
- ::Redcarpet.new(content, *options).to_html
72
+
73
+ # Render
74
+ if with_toc
75
+ renderer_toc = ::Redcarpet::Render::HTML_TOC.new
76
+ toc = ::Redcarpet::Markdown.new(renderer_toc, options).render(content)
77
+ body = ::Redcarpet::Markdown.new(renderer, options).render(content)
78
+ toc + body
79
+ else
80
+ ::Redcarpet::Markdown.new(renderer, options).render(content)
81
+ end
61
82
  end
62
83
  end
63
84
 
@@ -28,7 +28,12 @@ module Nanoc::Helpers
28
28
  #
29
29
  # @return [Array] An array containing all articles
30
30
  def articles
31
- @items.select { |item| item[:kind] == 'article' }
31
+ blk = lambda { @items.select { |item| item[:kind] == 'article' } }
32
+ if @items.frozen?
33
+ @article_items ||= blk.call
34
+ else
35
+ blk.call
36
+ end
32
37
  end
33
38
 
34
39
  # Returns a sorted list of articles, i.e. items where the `kind`
@@ -37,9 +42,15 @@ module Nanoc::Helpers
37
42
  #
38
43
  # @return [Array] A sorted array containing all articles
39
44
  def sorted_articles
40
- articles.sort_by do |a|
41
- attribute_to_time(a[:created_at])
42
- end.reverse
45
+ blk = lambda do
46
+ articles.sort_by { |a| attribute_to_time(a[:created_at]) }.reverse
47
+ end
48
+
49
+ if @items.frozen?
50
+ @sorted_article_items ||= blk.call
51
+ else
52
+ blk.call
53
+ end
43
54
  end
44
55
 
45
56
  class AtomFeedBuilder
data/lib/nanoc/version.rb CHANGED
@@ -3,6 +3,6 @@
3
3
  module Nanoc
4
4
 
5
5
  # The current nanoc version.
6
- VERSION = '3.6.11'
6
+ VERSION = '3.7.0'
7
7
 
8
8
  end
data/nanoc.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  $LOAD_PATH.unshift(File.expand_path('../lib/', __FILE__))
4
- require 'nanoc'
4
+ require 'nanoc/version'
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'nanoc'
data/tasks/rubocop.rake CHANGED
@@ -1,9 +1,9 @@
1
1
  begin
2
2
  require 'rubocop/rake_task'
3
3
 
4
- Rubocop::RakeTask.new(:rubocop) do |task|
4
+ RuboCop::RakeTask.new(:rubocop) do |task|
5
5
  task.patterns = ['lib/**/*.rb']
6
6
  end
7
7
  rescue LoadError
8
- warn "Could not load Rubocop. Rubocop rake tasks will be unavailable."
8
+ warn "Could not load RuboCop. RuboCop rake tasks will be unavailable."
9
9
  end
@@ -53,6 +53,14 @@ describe Nanoc::TempFilenameFactory do
53
53
  File.file?(path_a).wont_equal(true)
54
54
  end
55
55
 
56
+ it 'should eventually delete the root directory' do
57
+ subject.create(prefix)
58
+ File.directory?(subject.root_dir).must_equal(true)
59
+
60
+ subject.cleanup(prefix)
61
+ File.directory?(subject.root_dir).wont_equal(true)
62
+ end
63
+
56
64
  end
57
65
 
58
66
  describe 'other instance' do
@@ -33,6 +33,40 @@ class Nanoc::CompilerDSLTest < Nanoc::TestCase
33
33
  assert_match(/WARNING: A preprocess block is already defined./, io[:stderr])
34
34
  end
35
35
 
36
+ def test_per_rules_file_preprocessor
37
+ # Create site
38
+ Nanoc::CLI.run %w( create_site per-rules-file-preprocessor )
39
+ FileUtils.cd('per-rules-file-preprocessor') do
40
+ # Create rep
41
+ item = Nanoc::Item.new('foo', { :extension => 'bar' }, '/foo/')
42
+
43
+ # Create a bonus rules file
44
+ File.open('more_rules.rb', 'w') { |io| io.write "preprocess { @items['/foo/'][:preprocessed] = true }" }
45
+
46
+ # Create other necessary stuff
47
+ site = Nanoc::Site.new('.')
48
+ site.items << item
49
+ dsl = site.compiler.rules_collection.dsl
50
+ io = capturing_stdio do
51
+ dsl.preprocess {}
52
+ end
53
+ assert_empty io[:stdout]
54
+ assert_empty io[:stderr]
55
+
56
+ # Include rules
57
+ dsl.include_rules 'more_rules'
58
+
59
+ # Check that the two preprocess blocks have been added
60
+ assert_equal 2, site.compiler.rules_collection.preprocessors.size
61
+ refute_nil site.compiler.rules_collection.preprocessors.first
62
+ refute_nil site.compiler.rules_collection.preprocessors.last
63
+
64
+ # Apply preprocess blocks
65
+ site.compiler.preprocess
66
+ assert item[:preprocessed]
67
+ end
68
+ end
69
+
36
70
  def test_include_rules
37
71
  # Create site
38
72
  Nanoc::CLI.run %w( create_site with_bonus_rules )
@@ -33,14 +33,89 @@ class Nanoc::SiteTest < Nanoc::TestCase
33
33
  assert_equal({}, site.config[:data_sources][0][:config])
34
34
  end
35
35
 
36
+ def test_initialize_with_existing_parent_config_file
37
+ File.open('nanoc.yaml', 'w') do |io|
38
+ io.write <<-EOF
39
+ output_dir: public_html
40
+ parent_config_file: foo/foo.yaml
41
+ EOF
42
+ end
43
+ FileUtils.mkdir_p('foo')
44
+ FileUtils.cd('foo') do
45
+ File.open('foo.yaml', 'w') do |io|
46
+ io.write <<-EOF
47
+ parent_config_file: ../bar/bar.yaml
48
+ EOF
49
+ end
50
+ end
51
+ FileUtils.mkdir_p('bar')
52
+ FileUtils.cd('bar') do
53
+ File.open('bar.yaml', 'w') do |io|
54
+ io.write <<-EOF
55
+ enable_output_diff: true
56
+ foo: bar
57
+ output_dir: output
58
+ EOF
59
+ end
60
+ end
61
+
62
+ site = Nanoc::Site.new('.')
63
+ assert_nil site.config[:parent_config_file]
64
+ assert site.config[:enable_output_diff]
65
+ assert_equal 'bar', site.config[:foo]
66
+ assert_equal 'public_html', site.config[:output_dir]
67
+ end
68
+
69
+ def test_initialize_with_missing_parent_config_file
70
+ File.open('nanoc.yaml', 'w') do |io|
71
+ io.write <<-EOF
72
+ parent_config_file: foo/foo.yaml
73
+ EOF
74
+ end
75
+
76
+ error = assert_raises(Nanoc::Errors::GenericTrivial) do
77
+ site = Nanoc::Site.new('.')
78
+ end
79
+ assert_equal(
80
+ "Could not find parent configuration file 'foo/foo.yaml'",
81
+ error.message
82
+ )
83
+ end
84
+
85
+ def test_initialize_with_parent_config_file_cycle
86
+ File.open('nanoc.yaml', 'w') do |io|
87
+ io.write <<-EOF
88
+ parent_config_file: foo/foo.yaml
89
+ EOF
90
+ end
91
+ FileUtils.mkdir_p('foo')
92
+ FileUtils.cd('foo') do
93
+ File.open('foo.yaml', 'w') do |io|
94
+ io.write <<-EOF
95
+ parent_config_file: ../nanoc.yaml
96
+ EOF
97
+ end
98
+ end
99
+
100
+ error = assert_raises(Nanoc::Errors::GenericTrivial) do
101
+ site = Nanoc::Site.new('.')
102
+ end
103
+ assert_equal(
104
+ "Cycle detected. Could not use parent configuration file '../nanoc.yaml'",
105
+ error.message
106
+ )
107
+ end
108
+
36
109
  def test_load_rules_with_existing_rules_file
37
110
  # Mock DSL
38
111
  dsl = mock
112
+ dsl.stubs(:rules_filename)
113
+ dsl.stubs(:rules_filename=)
39
114
  dsl.expects(:compile).with('*')
40
115
 
41
116
  # Create site
42
117
  site = Nanoc::Site.new({})
43
- site.compiler.rules_collection.expects(:dsl).returns(dsl)
118
+ site.compiler.rules_collection.stubs(:dsl).returns(dsl)
44
119
 
45
120
  # Create rules file
46
121
  File.open('Rules', 'w') do |io|
@@ -19,6 +19,37 @@ class Nanoc::CLI::Commands::CreateSiteTest < Nanoc::TestCase
19
19
  end
20
20
  end
21
21
 
22
+ def test_default_encoding
23
+ if !defined?(Encoding)
24
+ skip 'No Encoding class'
25
+ return
26
+ end
27
+
28
+ original_encoding = Encoding.default_external
29
+ Encoding.default_external = 'ISO-8859-1' # ew!
30
+
31
+ Nanoc::CLI.run %w( create_site foo )
32
+
33
+ FileUtils.cd('foo') do
34
+
35
+ # Try with encoding = default encoding = utf-8
36
+ File.open('content/index.html', 'w') { |io| io.write("Hello <\xD6>!\n") }
37
+ site = Nanoc::Site.new('.')
38
+ exception = assert_raises(RuntimeError) do
39
+ site.compile
40
+ end
41
+ assert_equal "Could not read content/index.html because the file is not valid UTF-8.", exception.message
42
+
43
+ # Try with encoding = specific
44
+ File.open('nanoc.yaml', 'w') { |io| io.write("meh: true\n") }
45
+ site = Nanoc::Site.new('.')
46
+ site.compile
47
+ end
48
+ FileUtils
49
+ ensure
50
+ Encoding.default_external = original_encoding
51
+ end
52
+
22
53
  def test_new_site_has_correct_stylesheets
23
54
  Nanoc::CLI.run %w( create_site foo )
24
55
  FileUtils.cd('foo') do
data/test/cli/test_cli.rb CHANGED
@@ -102,6 +102,15 @@ EOS
102
102
  end
103
103
  end
104
104
 
105
+ def test_after_setup
106
+ $after_setup_success = false
107
+ Nanoc::CLI.after_setup do
108
+ $after_setup_success = true
109
+ end
110
+ Nanoc::CLI.setup
111
+ assert $after_setup_success
112
+ end
113
+
105
114
  def test_enable_utf8_only_on_tty
106
115
  new_env_diff = {
107
116
  'LC_ALL' => 'en_US.ISO-8859-1',
@@ -53,6 +53,19 @@ class Nanoc::Extra::Checking::Checks::InternalLinksTest < Nanoc::TestCase
53
53
  end
54
54
  end
55
55
 
56
+ def test_exclude
57
+ with_site do |site|
58
+ # Create check
59
+ check = Nanoc::Extra::Checking::Checks::InternalLinks.new(site)
60
+ site.config.update({ :checks => { :internal_links => { :exclude => ['^/excluded\d+'] } } })
61
+
62
+ # Test
63
+ assert check.send(:valid?, '/excluded1', 'output/origin')
64
+ assert check.send(:valid?, '/excluded2', 'output/origin')
65
+ assert !check.send(:valid?, '/excluded_not', 'output/origin')
66
+ end
67
+ end
68
+
56
69
  def test_unescape_url
57
70
  with_site do |site|
58
71
  FileUtils.mkdir_p('output/stuff')
@@ -64,4 +77,5 @@ class Nanoc::Extra::Checking::Checks::InternalLinksTest < Nanoc::TestCase
64
77
  refute check.send(:valid?, 'stuff/wrong%20foo', 'output/origin')
65
78
  end
66
79
  end
80
+
67
81
  end
@@ -385,4 +385,58 @@ EOS
385
385
  end
386
386
  end
387
387
 
388
+ def test_rouge
389
+ if_have 'rouge', 'nokogiri' do
390
+ # Create filter
391
+ filter = ::Nanoc::Filters::ColorizeSyntax.new
392
+
393
+ # Get input and expected output
394
+ input = <<EOS
395
+ before
396
+ <pre><code class="language-ruby">
397
+ def foo
398
+ end
399
+ </code></pre>
400
+ after
401
+ EOS
402
+ expected_output = <<EOS
403
+ before
404
+ <pre><code class=\"language-ruby highlight\"> <span class=\"k\">def</span> <span class=\"nf\">foo</span>
405
+ <span class=\"k\">end</span></code></pre>
406
+ after
407
+ EOS
408
+
409
+ # Run filter
410
+ actual_output = filter.setup_and_run(input, :default_colorizer => :rouge)
411
+ assert_equal(expected_output, actual_output)
412
+ end
413
+ end
414
+
415
+ def test_rouge_with_css_class
416
+ if_have 'rouge', 'nokogiri' do
417
+ # Create filter
418
+ filter = ::Nanoc::Filters::ColorizeSyntax.new
419
+
420
+ # Get input and expected output
421
+ input = <<EOS
422
+ before
423
+ <pre><code class="language-ruby">
424
+ def foo
425
+ end
426
+ </code></pre>
427
+ after
428
+ EOS
429
+ expected_output = <<EOS
430
+ before
431
+ <pre><code class=\"language-ruby my-class\"> <span class=\"k\">def</span> <span class=\"nf\">foo</span>
432
+ <span class=\"k\">end</span></code></pre>
433
+ after
434
+ EOS
435
+
436
+ # Run filter
437
+ actual_output = filter.setup_and_run(input, :default_colorizer => :rouge, :rouge => { :css_class => 'my-class' })
438
+ assert_equal(expected_output, actual_output)
439
+ end
440
+ end
441
+
388
442
  end
@@ -79,7 +79,31 @@ class Nanoc::Filters::RedcarpetTest < Nanoc::TestCase
79
79
 
80
80
  # Run filter
81
81
  input = "# Heading 1\n## Heading 2\n"
82
- filter.run(input, :renderer => Redcarpet::Render::HTML_TOC)
82
+ output_actual = filter.run(input, :renderer => Redcarpet::Render::HTML_TOC)
83
+
84
+ # Test
85
+ output_expected = %r{<ul>\n<li>\n<a href=\"#heading-1\">Heading 1</a>\n<ul>\n<li>\n<a href=\"#heading-2\">Heading 2</a>\n</li>\n</ul>\n</li>\n</ul>}
86
+ assert_match(output_expected, output_actual)
87
+ end
88
+ end
89
+
90
+ def test_toc_if_requested
91
+ if_have 'redcarpet' do
92
+ # Create filter
93
+ filter = ::Nanoc::Filters::Redcarpet.new
94
+
95
+ # Run filter
96
+ input = "A Title\n======"
97
+ if ::Redcarpet::VERSION > '2'
98
+ output_expected = %r{<ul>\n<li>\n<a href="#a-title">A Title</a>\n</li>\n</ul>\n<h1 id="a-title">A Title</h1>\n}
99
+ output_actual = filter.setup_and_run(input, :with_toc => true)
100
+ else
101
+ output_expected = %r{<h1>A Title</h1>\n}
102
+ output_actual = filter.setup_and_run(input)
103
+ end
104
+
105
+ # Test
106
+ assert_match(output_expected, output_actual)
83
107
  end
84
108
  end
85
109
 
data/test/helper.rb CHANGED
@@ -10,6 +10,10 @@ require 'minitest/mock'
10
10
  require 'mocha/setup'
11
11
  require 'vcr'
12
12
 
13
+ # Setup coverage
14
+ require 'coveralls'
15
+ Coveralls.wear!
16
+
13
17
  # Load nanoc
14
18
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
15
19
  require 'nanoc'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.11
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-09 00:00:00.000000000 Z
11
+ date: 2014-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cri