nanoc 3.5.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +20 -12
  3. data/NEWS.md +23 -0
  4. data/README.md +6 -3
  5. data/doc/yardoc_templates/default/layout/html/footer.erb +16 -7
  6. data/lib/nanoc.rb +1 -1
  7. data/lib/nanoc/base.rb +1 -0
  8. data/lib/nanoc/base/compilation/compiler_dsl.rb +31 -0
  9. data/lib/nanoc/base/compilation/filter.rb +34 -0
  10. data/lib/nanoc/base/result_data/item_rep.rb +3 -3
  11. data/lib/nanoc/base/source_data/code_snippet.rb +1 -1
  12. data/lib/nanoc/base/source_data/data_source.rb +12 -0
  13. data/lib/nanoc/base/source_data/item.rb +1 -1
  14. data/lib/nanoc/base/source_data/item_array.rb +62 -0
  15. data/lib/nanoc/base/source_data/layout.rb +1 -1
  16. data/lib/nanoc/base/source_data/site.rb +24 -3
  17. data/lib/nanoc/cli/cleaning_stream.rb +10 -0
  18. data/lib/nanoc/cli/command_runner.rb +25 -12
  19. data/lib/nanoc/cli/commands/autocompile.rb +5 -3
  20. data/lib/nanoc/cli/commands/check.rb +9 -1
  21. data/lib/nanoc/cli/commands/compile.rb +1 -1
  22. data/lib/nanoc/cli/commands/create-site.rb +5 -5
  23. data/lib/nanoc/cli/commands/prune.rb +1 -1
  24. data/lib/nanoc/cli/commands/shell.rb +37 -0
  25. data/lib/nanoc/cli/commands/show-data.rb +1 -1
  26. data/lib/nanoc/cli/commands/sync.rb +34 -0
  27. data/lib/nanoc/cli/error_handler.rb +11 -2
  28. data/lib/nanoc/extra/checking/checks/stale.rb +10 -2
  29. data/lib/nanoc/extra/pruner.rb +14 -11
  30. data/lib/nanoc/filters/asciidoc.rb +2 -2
  31. data/lib/nanoc/filters/bluecloth.rb +2 -2
  32. data/lib/nanoc/filters/coderay.rb +2 -2
  33. data/lib/nanoc/filters/coffeescript.rb +2 -2
  34. data/lib/nanoc/filters/colorize_syntax.rb +2 -4
  35. data/lib/nanoc/filters/erb.rb +2 -2
  36. data/lib/nanoc/filters/erubis.rb +2 -2
  37. data/lib/nanoc/filters/haml.rb +2 -2
  38. data/lib/nanoc/filters/handlebars.rb +2 -2
  39. data/lib/nanoc/filters/kramdown.rb +2 -2
  40. data/lib/nanoc/filters/less.rb +2 -2
  41. data/lib/nanoc/filters/markaby.rb +2 -2
  42. data/lib/nanoc/filters/maruku.rb +2 -2
  43. data/lib/nanoc/filters/mustache.rb +2 -2
  44. data/lib/nanoc/filters/pandoc.rb +2 -2
  45. data/lib/nanoc/filters/rainpress.rb +2 -2
  46. data/lib/nanoc/filters/rdiscount.rb +2 -2
  47. data/lib/nanoc/filters/rdoc.rb +3 -17
  48. data/lib/nanoc/filters/redcarpet.rb +7 -3
  49. data/lib/nanoc/filters/redcloth.rb +2 -2
  50. data/lib/nanoc/filters/rubypants.rb +2 -2
  51. data/lib/nanoc/filters/sass.rb +2 -3
  52. data/lib/nanoc/filters/slim.rb +2 -2
  53. data/lib/nanoc/filters/typogruby.rb +2 -2
  54. data/lib/nanoc/filters/uglify_js.rb +2 -2
  55. data/lib/nanoc/filters/xsl.rb +2 -1
  56. data/lib/nanoc/filters/yui_compressor.rb +2 -2
  57. data/lib/nanoc/helpers/blogging.rb +1 -1
  58. data/lib/nanoc/helpers/filtering.rb +1 -1
  59. data/lib/nanoc/helpers/rendering.rb +1 -1
  60. data/nanoc.gemspec +2 -2
  61. data/test/base/core_ext/array_spec.rb +4 -12
  62. data/test/base/core_ext/hash_spec.rb +4 -12
  63. data/test/base/test_compiler_dsl.rb +63 -0
  64. data/test/base/test_item.rb +3 -18
  65. data/test/base/test_item_array.rb +336 -0
  66. data/test/base/test_item_rep.rb +2 -12
  67. data/test/base/test_layout.rb +1 -6
  68. data/test/base/test_outdatedness_checker.rb +1 -1
  69. data/test/base/test_site.rb +9 -3
  70. data/test/cli/commands/test_check.rb +22 -0
  71. data/test/cli/commands/test_compile.rb +2 -2
  72. data/test/cli/commands/test_deploy.rb +6 -6
  73. data/test/cli/commands/test_prune.rb +23 -4
  74. data/test/cli/commands/test_sync.rb +31 -0
  75. data/test/cli/test_error_handler.rb +16 -11
  76. data/test/extra/checking/checks/test_stale.rb +24 -1
  77. data/test/extra/test_auto_compiler.rb +4 -4
  78. data/test/filters/test_asciidoc.rb +1 -1
  79. data/test/filters/test_bluecloth.rb +1 -1
  80. data/test/filters/test_coderay.rb +3 -3
  81. data/test/filters/test_coffeescript.rb +1 -1
  82. data/test/filters/test_colorize_syntax.rb +20 -20
  83. data/test/filters/test_erb.rb +10 -10
  84. data/test/filters/test_erubis.rb +6 -6
  85. data/test/filters/test_haml.rb +10 -10
  86. data/test/filters/test_handlebars.rb +3 -3
  87. data/test/filters/test_kramdown.rb +1 -1
  88. data/test/filters/test_less.rb +4 -4
  89. data/test/filters/test_markaby.rb +1 -1
  90. data/test/filters/test_maruku.rb +1 -1
  91. data/test/filters/test_mustache.rb +2 -2
  92. data/test/filters/test_pandoc.rb +1 -1
  93. data/test/filters/test_rainpress.rb +2 -2
  94. data/test/filters/test_rdiscount.rb +2 -2
  95. data/test/filters/test_rdoc.rb +1 -1
  96. data/test/filters/test_redcarpet.rb +21 -6
  97. data/test/filters/test_redcloth.rb +3 -3
  98. data/test/filters/test_relativize_paths.rb +27 -27
  99. data/test/filters/test_rubypants.rb +1 -1
  100. data/test/filters/test_sass.rb +8 -8
  101. data/test/filters/test_slim.rb +4 -4
  102. data/test/filters/test_typogruby.rb +1 -1
  103. data/test/filters/test_uglify_js.rb +2 -2
  104. data/test/filters/test_xsl.rb +2 -2
  105. data/test/filters/test_yui_compressor.rb +3 -3
  106. data/test/helper.rb +6 -1
  107. metadata +12 -6
@@ -99,6 +99,16 @@ module Nanoc::CLI
99
99
  @stream.exists?
100
100
  end
101
101
 
102
+ # @see IO.winsize
103
+ def winsize
104
+ @stream.winsize
105
+ end
106
+
107
+ # @see IO.winsize=
108
+ def winsize=(arg)
109
+ @stream.winsize=(arg)
110
+ end
111
+
102
112
  protected
103
113
 
104
114
  def clean(s)
@@ -22,7 +22,7 @@ module Nanoc::CLI
22
22
  def site
23
23
  # Load site if possible
24
24
  @site ||= nil
25
- if File.file?('config.yaml') && @site.nil?
25
+ if self.is_in_site_dir? && @site.nil?
26
26
  @site = Nanoc::Site.new('.')
27
27
  end
28
28
 
@@ -36,13 +36,10 @@ module Nanoc::CLI
36
36
  self.new(opts, args, cmd).call
37
37
  end
38
38
 
39
- protected
40
-
41
- # @return [Boolean] true if debug output is enabled, false if not
42
- #
43
- # @see Nanoc::CLI.debug?
44
- def debug?
45
- Nanoc::CLI.debug?
39
+ # @return [Boolean] true if the current working directory is a nanoc site
40
+ # directory, false otherwise
41
+ def is_in_site_dir?
42
+ Nanoc::Site.cwd_is_nanoc_site?
46
43
  end
47
44
 
48
45
  # Asserts that the current working directory contains a site
@@ -51,15 +48,31 @@ module Nanoc::CLI
51
48
  #
52
49
  # @return [void]
53
50
  def require_site
54
- print "Loading site data… "
55
51
  if site.nil?
56
- puts "error"
57
52
  raise ::Nanoc::Errors::GenericTrivial, "The current working directory does not seem to be a nanoc site."
58
- else
59
- puts "done"
60
53
  end
61
54
  end
62
55
 
56
+ # Asserts that the current workign directory contains a site (just like
57
+ # {#require_site}) and loads the site into memory.
58
+ #
59
+ # @return [void]
60
+ def load_site
61
+ self.require_site
62
+ print "Loading site data… "
63
+ self.site.load
64
+ puts "done"
65
+ end
66
+
67
+ protected
68
+
69
+ # @return [Boolean] true if debug output is enabled, false if not
70
+ #
71
+ # @see Nanoc::CLI.debug?
72
+ def debug?
73
+ Nanoc::CLI.debug?
74
+ end
75
+
63
76
  # Sets the data source's VCS to the VCS with the given name. Does nothing
64
77
  # when the site's data source does not support VCSes (i.e. does not
65
78
  # implement #vcs=).
@@ -8,12 +8,13 @@ Start the autocompiler web server. Unless overridden with commandline options
8
8
  or configuration entries, the web server will run on port 3000 and listen on all
9
9
  IP addresses. Running the autocompiler requires the `mime/types` and `rack` gems.
10
10
 
11
- To specify the host and/or port options in config.yaml, you can add either (or
12
- both) of the following:
11
+ To specify the host, port, and/or handler options in config.yaml, you can add
12
+ any of the following:
13
13
 
14
14
  autocompile:
15
15
  host: '10.0.2.0' # override the default host
16
16
  port: 4000 # override the default port
17
+ handler: thin # override the default handler
17
18
 
18
19
  EOS
19
20
 
@@ -39,7 +40,8 @@ module Nanoc::CLI::Commands
39
40
  }
40
41
 
41
42
  # Guess which handler we should use
42
- unless handler = Rack::Handler.get(options[:handler])
43
+ handler_option = options[:handler] || autocompile_config[:handler]
44
+ unless handler = Rack::Handler.get(handler_option)
43
45
  begin
44
46
  handler = Rack::Handler::Mongrel
45
47
  rescue LoadError => e
@@ -19,15 +19,23 @@ module Nanoc::CLI::Commands
19
19
  self.require_site
20
20
 
21
21
  runner = Nanoc::Extra::Checking::Runner.new(site)
22
+
22
23
  if options[:list]
23
24
  runner.list_checks
24
- elsif options[:all]
25
+ return
26
+ end
27
+
28
+ success = if options[:all]
25
29
  runner.run_all
26
30
  elsif options[:deploy]
27
31
  runner.run_for_deploy
28
32
  else
29
33
  runner.run_specific(arguments)
30
34
  end
35
+
36
+ unless success
37
+ raise Nanoc::Errors::GenericTrivial, 'One or more checks failed'
38
+ end
31
39
  end
32
40
 
33
41
  protected
@@ -316,7 +316,7 @@ module Nanoc::CLI::Commands
316
316
  end
317
317
 
318
318
  def run
319
- self.require_site
319
+ self.load_site
320
320
  self.check_for_deprecated_usage
321
321
  self.setup_listeners
322
322
 
@@ -285,14 +285,14 @@ EOS
285
285
  <div id="sidebar">
286
286
  <h2>Documentation</h2>
287
287
  <ul>
288
- <li><a href="http://nanoc.stoneship.org/docs/">Documentation</a></li>
289
- <li><a href="http://nanoc.stoneship.org/docs/3-getting-started/">Getting Started</a></li>
288
+ <li><a href="http://nanoc.ws/docs/">Documentation</a></li>
289
+ <li><a href="http://nanoc.ws/docs/tutorial/">Getting Started</a></li>
290
290
  </ul>
291
291
  <h2>Community</h2>
292
292
  <ul>
293
293
  <li><a href="http://groups.google.com/group/nanoc/">Discussion Group</a></li>
294
294
  <li><a href="irc://chat.freenode.net/#nanoc">IRC Channel</a></li>
295
- <li><a href="http://projects.stoneship.org/trac/nanoc/">Wiki</a></li>
295
+ <li><a href="http://github.com/nanoc/nanoc/wiki/">Wiki</a></li>
296
296
  </ul>
297
297
  </div>
298
298
  </body>
@@ -344,8 +344,8 @@ EOS
344
344
  FileUtils.mkdir_p('output')
345
345
 
346
346
  # Create config
347
- File.open('config.yaml', 'w') { |io| io.write(DEFAULT_CONFIG) }
348
- Nanoc::NotificationCenter.post(:file_created, 'config.yaml')
347
+ File.open('nanoc.yaml', 'w') { |io| io.write(DEFAULT_CONFIG) }
348
+ Nanoc::NotificationCenter.post(:file_created, 'nanoc.yaml')
349
349
 
350
350
  # Create rules
351
351
  File.open('Rules', 'w') do |io|
@@ -19,7 +19,7 @@ module Nanoc::CLI::Commands
19
19
  class Prune < ::Nanoc::CLI::CommandRunner
20
20
 
21
21
  def run
22
- require_site
22
+ self.load_site
23
23
 
24
24
  if options.has_key?(:yes)
25
25
  Nanoc::Extra::Pruner.new(self.site, :exclude => self.prune_config_exclude).run
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ usage 'shell'
4
+ summary 'open a shell on the nanoc environment'
5
+ aliases 'console'
6
+ description <<-EOS
7
+ Open an IRB shell on a context that contains @items, @layouts, @config and @site.
8
+ EOS
9
+
10
+ module Nanoc::CLI::Commands
11
+
12
+ class Shell < ::Nanoc::CLI::CommandRunner
13
+
14
+ def run
15
+ require 'pry'
16
+
17
+ self.require_site
18
+
19
+ Nanoc::Context.new(env).pry
20
+ end
21
+
22
+ protected
23
+
24
+ def env
25
+ {
26
+ :site => self.site,
27
+ :items => self.site.items,
28
+ :layouts => self.site.layouts,
29
+ :config => self.site.config
30
+ }
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
37
+ runner Nanoc::CLI::Commands::Shell
@@ -13,7 +13,7 @@ module Nanoc::CLI::Commands
13
13
  class ShowData < ::Nanoc::CLI::CommandRunner
14
14
 
15
15
  def run
16
- self.require_site
16
+ self.load_site
17
17
 
18
18
  # Get data
19
19
  items = self.site.items
@@ -0,0 +1,34 @@
1
+ usage 'sync'
2
+ summary 'sync data sources'
3
+ description <<-EOS
4
+ Sync data source data. This command is useful for updating local item caches
5
+ for data sources which rely on slow external APIs.
6
+ EOS
7
+
8
+ module Nanoc::CLI::Commands
9
+
10
+ class Sync < ::Nanoc::CLI::CommandRunner
11
+
12
+ def run
13
+ # Check arguments
14
+ if arguments.size != 0
15
+ raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
16
+ end
17
+
18
+ # Make sure we are in a nanoc site directory
19
+ self.require_site
20
+
21
+ # Update all syncable data sources
22
+ self.site.data_sources.each do |data_source|
23
+ unless data_source.method(:sync).owner == Nanoc::DataSource
24
+ puts "Syncing #{data_source.config[:type]} data source: #{data_source.items_root}"
25
+ data_source.sync
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ runner Nanoc::CLI::Commands::Sync
@@ -208,6 +208,7 @@ module Nanoc::CLI
208
208
  'maruku' => 'maruku',
209
209
  'mime/types' => 'mime-types',
210
210
  'nokogiri' => 'nokogiri',
211
+ 'pry' => 'pry',
211
212
  'rack' => 'rack',
212
213
  'rack/cache' => 'rack-cache',
213
214
  'rainpress' => 'rainpress',
@@ -236,7 +237,11 @@ module Nanoc::CLI
236
237
 
237
238
  # Build message
238
239
  if gem_name
239
- "Try installing the '#{gem_name}' gem (`gem install #{gem_name}`) and then re-running the command."
240
+ if self.using_bundler?
241
+ "Make sure the gem is added to Gemfile and run `bundle up`."
242
+ else
243
+ "Install the '#{gem_name}' gem using `gem install #{gem_name}`."
244
+ end
240
245
  end
241
246
  when RuntimeError
242
247
  if error.message =~ /^can't modify frozen/
@@ -249,6 +254,10 @@ module Nanoc::CLI
249
254
  end
250
255
  end
251
256
 
257
+ def using_bundler?
258
+ defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
259
+ end
260
+
252
261
  def write_section_header(stream, title, params={})
253
262
  stream.puts
254
263
  if params[:verbose]
@@ -298,7 +307,7 @@ module Nanoc::CLI
298
307
  def write_issue_link(stream, params={})
299
308
  stream.puts
300
309
  stream.puts "If you believe this is a bug in nanoc, please do report it at"
301
- stream.puts "-> https://github.com/ddfreyne/nanoc/issues/new <-"
310
+ stream.puts "-> https://github.com/nanoc/nanoc/issues/new <-"
302
311
  stream.puts
303
312
  stream.puts "A detailed crash log has been written to ./crash.log."
304
313
  end
@@ -6,8 +6,11 @@ module Nanoc::Extra::Checking::Checks
6
6
 
7
7
  def run
8
8
  require 'set'
9
+
9
10
  item_rep_paths = Set.new(@site.items.collect { |i| i.reps }.flatten.collect { |r| r.raw_path })
11
+
10
12
  self.output_filenames.each do |f|
13
+ next if self.pruner.filename_excluded?(f)
11
14
  if !item_rep_paths.include?(f)
12
15
  self.add_issue(
13
16
  "file without matching item",
@@ -16,8 +19,13 @@ module Nanoc::Extra::Checking::Checks
16
19
  end
17
20
  end
18
21
 
19
- end
22
+ protected
20
23
 
21
- end
24
+ def pruner
25
+ exclude_config = @site.config.fetch(:prune, {}).fetch(:exclude, [])
26
+ @pruner ||= Nanoc::Extra::Pruner.new(@site, :exclude => exclude_config)
27
+ end
22
28
 
29
+ end
23
30
 
31
+ end
@@ -6,7 +6,7 @@ module Nanoc::Extra
6
6
  # that are not managed by nanoc.
7
7
  class Pruner
8
8
 
9
- # @return [Nanoc::Site] The site this pruner belongs to
9
+ # @return [Nanoc::Site] The site this pruner belongs to
10
10
  attr_reader :site
11
11
 
12
12
  # @param [Nanoc::Site] site The site for which a pruner is created
@@ -34,12 +34,12 @@ module Nanoc::Extra
34
34
  end.flatten.compact.select { |f| File.file?(f) }
35
35
 
36
36
  # Get present files and dirs
37
- present_files_and_dirs = Set.new
37
+ present_files = []
38
+ present_dirs = []
38
39
  Find.find(self.site.config[:output_dir] + '/') do |f|
39
- present_files_and_dirs << f
40
+ present_files << f if File.file?(f)
41
+ present_dirs << f if File.directory?(f)
40
42
  end
41
- present_files = present_files_and_dirs.select { |f| File.file?(f) }
42
- present_dirs = present_files_and_dirs.select { |f| File.directory?(f) }
43
43
 
44
44
  # Remove stray files
45
45
  stray_files = (present_files - compiled_files)
@@ -49,20 +49,23 @@ module Nanoc::Extra
49
49
  end
50
50
 
51
51
  # Remove empty directories
52
- present_dirs.each do |dir|
52
+ present_dirs.reverse_each do |dir|
53
53
  next if Dir.foreach(dir) { |n| break true if n !~ /\A\.\.?\z/ }
54
54
  next if filename_excluded?(dir)
55
55
  self.delete_dir(dir)
56
56
  end
57
57
  end
58
58
 
59
- protected
60
-
61
- def filename_excluded?(f)
62
- pathname = Pathname.new(f)
63
- @exclude.any? { |e| pathname.include_component?(e) }
59
+ # @param [String] filename The filename to check
60
+ #
61
+ # @return [Boolean] true if the given file is excluded, false otherwise
62
+ def filename_excluded?(filename)
63
+ pathname = Pathname.new(filename)
64
+ @exclude.any? { |e| pathname.include_component?(e) }
64
65
  end
65
66
 
67
+ protected
68
+
66
69
  def delete_file(file)
67
70
  if @dry_run
68
71
  puts file
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'systemu'
4
-
5
3
  module Nanoc::Filters
6
4
 
7
5
  # @since 3.2.0
8
6
  class AsciiDoc < Nanoc::Filter
9
7
 
8
+ requires 'systemu'
9
+
10
10
  # Runs the content through [AsciiDoc](http://www.methods.co.nz/asciidoc/).
11
11
  # This method takes no options.
12
12
  #
@@ -1,10 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'bluecloth'
4
-
5
3
  module Nanoc::Filters
6
4
  class BlueCloth < Nanoc::Filter
7
5
 
6
+ requires 'bluecloth'
7
+
8
8
  # Runs the content through [BlueCloth](http://deveiate.org/projects/BlueCloth).
9
9
  # This method takes no options.
10
10
  #
@@ -1,10 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'coderay'
4
-
5
3
  module Nanoc::Filters
6
4
  class CodeRay < Nanoc::Filter
7
5
 
6
+ requires 'coderay'
7
+
8
8
  # @deprecated Use the `:colorize_syntax` filter instead.
9
9
  def run(content, params={})
10
10
  # Warn
@@ -1,10 +1,10 @@
1
- require 'coffee-script'
2
-
3
1
  module Nanoc::Filters
4
2
 
5
3
  # @since 3.3.0
6
4
  class CoffeeScript < Nanoc::Filter
7
5
 
6
+ require 'coffee-script'
7
+
8
8
  # Runs the content through [CoffeeScript](http://coffeescript.org/).
9
9
  # This method takes no options.
10
10
  #
@@ -1,12 +1,10 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'nokogiri'
4
- require 'stringio'
5
- require 'open3'
6
-
7
3
  module Nanoc::Filters
8
4
  class ColorizeSyntax < Nanoc::Filter
9
5
 
6
+ requires 'nokogiri', 'stringio', 'open3'
7
+
10
8
  # The default colorizer to use for a language if the colorizer for that
11
9
  # language is not overridden.
12
10
  DEFAULT_COLORIZER = :coderay