nanoc 3.3.7 → 3.4.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.
Files changed (53) hide show
  1. data/Gemfile.lock +133 -0
  2. data/NEWS.md +15 -0
  3. data/lib/nanoc.rb +2 -2
  4. data/lib/nanoc/base/compilation/compiler.rb +1 -1
  5. data/lib/nanoc/base/compilation/item_rep_proxy.rb +3 -3
  6. data/lib/nanoc/base/core_ext/string.rb +0 -18
  7. data/lib/nanoc/base/errors.rb +24 -19
  8. data/lib/nanoc/base/plugin_registry.rb +1 -1
  9. data/lib/nanoc/base/result_data/item_rep.rb +1 -2
  10. data/lib/nanoc/base/source_data/site.rb +1 -1
  11. data/lib/nanoc/cli.rb +46 -4
  12. data/lib/nanoc/cli/ansi_string_colorizer.rb +30 -0
  13. data/lib/nanoc/cli/cleaning_stream.rb +91 -0
  14. data/lib/nanoc/cli/command_runner.rb +3 -11
  15. data/lib/nanoc/cli/commands/compile.rb +2 -2
  16. data/lib/nanoc/cli/commands/{create_item.rb → create-item.rb} +6 -7
  17. data/lib/nanoc/cli/commands/{create_layout.rb → create-layout.rb} +9 -10
  18. data/lib/nanoc/cli/commands/{create_site.rb → create-site.rb} +13 -14
  19. data/lib/nanoc/cli/commands/deploy.rb +4 -12
  20. data/lib/nanoc/cli/commands/nanoc.rb +4 -2
  21. data/lib/nanoc/cli/commands/prune.rb +1 -1
  22. data/lib/nanoc/cli/commands/{debug.rb → show-data.rb} +6 -5
  23. data/lib/nanoc/cli/commands/{info.rb → show-plugins.rb} +6 -6
  24. data/lib/nanoc/cli/commands/show-rules.rb +69 -0
  25. data/lib/nanoc/cli/commands/update.rb +1 -2
  26. data/lib/nanoc/cli/commands/validate-css.rb +24 -0
  27. data/lib/nanoc/cli/commands/validate-html.rb +24 -0
  28. data/lib/nanoc/cli/commands/validate-links.rb +35 -0
  29. data/lib/nanoc/cli/commands/watch.rb +3 -3
  30. data/lib/nanoc/cli/error_handler.rb +142 -26
  31. data/lib/nanoc/cli/logger.rb +4 -21
  32. data/lib/nanoc/cli/stream_cleaners.rb +14 -0
  33. data/lib/nanoc/cli/stream_cleaners/abstract.rb +23 -0
  34. data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +15 -0
  35. data/lib/nanoc/cli/stream_cleaners/utf8.rb +16 -0
  36. data/lib/nanoc/extra/deployers/rsync.rb +2 -7
  37. data/lib/nanoc/extra/pruner.rb +3 -3
  38. data/lib/nanoc/extra/validators/links.rb +14 -3
  39. data/lib/nanoc/filters.rb +4 -0
  40. data/lib/nanoc/filters/handlebars.rb +30 -0
  41. data/lib/nanoc/filters/mustache.rb +2 -2
  42. data/lib/nanoc/filters/pandoc.rb +20 -0
  43. data/lib/nanoc/helpers/filtering.rb +1 -1
  44. data/lib/nanoc/tasks/validate.rake +10 -68
  45. data/nanoc.gemspec +0 -16
  46. data/test/cli/commands/test_create_site.rb +1 -1
  47. data/test/cli/commands/test_deploy.rb +45 -0
  48. data/test/cli/test_cli.rb +1 -1
  49. data/test/extra/validators/test_links.rb +15 -5
  50. data/test/filters/test_handlebars.rb +42 -0
  51. data/test/filters/test_mustache.rb +19 -0
  52. data/test/filters/test_pandoc.rb +18 -0
  53. metadata +23 -33
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::CLI
4
+
5
+ module StreamCleaners
6
+
7
+ autoload 'Abstract', 'nanoc/cli/stream_cleaners/abstract'
8
+ autoload 'ANSIColors', 'nanoc/cli/stream_cleaners/ansi_colors'
9
+ autoload 'UTF8', 'nanoc/cli/stream_cleaners/utf8'
10
+
11
+ end
12
+
13
+ end
14
+
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::CLI::StreamCleaners
4
+
5
+ # Superclass for all stream cleaners. Stream cleaners have a single method,
6
+ # {#clean}, that takes a string and returns a cleaned string. Stream cleaners
7
+ # can have state, so they can act as a FSM.
8
+ #
9
+ # @abstract Subclasses must implement {#clean}
10
+ class Abstract
11
+
12
+ # Returns a cleaned version of the given string.
13
+ #
14
+ # @param [String] s The string to clean
15
+ #
16
+ # @return [String] The cleaned string
17
+ def clean(s)
18
+ raise NotImplementedError, "Subclasses of Nanoc::CLI::StreamCleaners::Abstract must implement #clean"
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::CLI::StreamCleaners
4
+
5
+ # Removes ANSI color escape sequences.
6
+ class ANSIColors < Abstract
7
+
8
+ # @see Nanoc::CLI::StreamCleaners::Abstract#clean
9
+ def clean(s)
10
+ s.gsub(/\e\[.+?m/, '')
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc::CLI::StreamCleaners
4
+
5
+ # Simplifies output by replacing UTF-8 characters with their ASCII decompositions.
6
+ class UTF8 < Abstract
7
+
8
+ # @see Nanoc::CLI::StreamCleaners::Abstract#clean
9
+ def clean(s)
10
+ # FIXME this decomposition is not generally usable
11
+ s.gsub(/“|”/, '"').gsub(/‘|’/, '\'').gsub('…', '...').gsub('©', '(c)')
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -39,8 +39,8 @@ module Nanoc::Extra::Deployers
39
39
  options = self.config[:options] || DEFAULT_OPTIONS
40
40
 
41
41
  # Validate
42
- error 'No dst found in deployment configuration' if dst.nil?
43
- error 'dst requires no trailing slash' if dst[-1,1] == '/'
42
+ raise 'No dst found in deployment configuration' if dst.nil?
43
+ raise 'dst requires no trailing slash' if dst[-1,1] == '/'
44
44
 
45
45
  # Run
46
46
  if dry_run
@@ -53,11 +53,6 @@ module Nanoc::Extra::Deployers
53
53
 
54
54
  private
55
55
 
56
- # Prints the given message on stderr and exits.
57
- def error(msg)
58
- raise RuntimeError.new(msg)
59
- end
60
-
61
56
  # Runs the given shell command. It will raise an error if execution fails
62
57
  # (results in a nonzero exit code).
63
58
  def run_shell_cmd(args)
@@ -9,11 +9,11 @@ module Nanoc::Extra
9
9
  # @return [Nanoc::Site] The site this pruner belongs to
10
10
  attr_reader :site
11
11
 
12
- # @param [Nanoc::Site] The site for which a pruner is created
12
+ # @param [Nanoc::Site] site The site for which a pruner is created
13
13
  #
14
14
  # @option params [Boolean] :dry_run (false) true if the files to be deleted
15
- # should only be printed instead of actually deleted, false if the files
16
- # should actually be deleted.
15
+ # should only be printed instead of actually deleted, false if the files
16
+ # should actually be deleted.
17
17
  def initialize(site, params={})
18
18
  @site = site
19
19
  @dry_run = params.fetch(:dry_run) { false }
@@ -168,7 +168,7 @@ module Nanoc::Extra::Validators
168
168
 
169
169
  # Get status
170
170
  status = fetch_http_status_for(uri)
171
- is_valid = !!(status && status >= 200 && status <= 299)
171
+ is_valid = !status.nil? && status == 200
172
172
 
173
173
  # Notify
174
174
  @delegate && @delegate.send(:external_href_validated, href, is_valid)
@@ -222,8 +222,19 @@ module Nanoc::Extra::Validators
222
222
  end
223
223
 
224
224
  if res.code =~ /^3..$/
225
- url = URI.parse(res['location'])
226
225
  return nil if i == 5
226
+
227
+ # Find proper location
228
+ location = res['Location']
229
+ if location !~ /^https?:\/\//
230
+ base_url = url.dup
231
+ base_url.path = (location =~ /^\// ? '' : '/')
232
+ base_url.query = nil
233
+ base_url.fragment = nil
234
+ location = base_url.to_s + location
235
+ end
236
+
237
+ url = URI.parse(location)
227
238
  else
228
239
  return res.code.to_i
229
240
  end
@@ -238,7 +249,7 @@ module Nanoc::Extra::Validators
238
249
 
239
250
  path = (url.path.nil? || url.path.empty? ? '/' : url.path)
240
251
  req = Net::HTTP::Head.new(path)
241
- http=Net::HTTP.new(url.host, url.port)
252
+ http = Net::HTTP.new(url.host, url.port)
242
253
  if url.instance_of? URI::HTTPS
243
254
  http.use_ssl = true
244
255
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
data/lib/nanoc/filters.rb CHANGED
@@ -10,11 +10,13 @@ module Nanoc::Filters
10
10
  autoload 'ERB', 'nanoc/filters/erb'
11
11
  autoload 'Erubis', 'nanoc/filters/erubis'
12
12
  autoload 'Haml', 'nanoc/filters/haml'
13
+ autoload 'Handlebars', 'nanoc/filters/handlebars'
13
14
  autoload 'Kramdown', 'nanoc/filters/kramdown'
14
15
  autoload 'Less', 'nanoc/filters/less'
15
16
  autoload 'Markaby', 'nanoc/filters/markaby'
16
17
  autoload 'Maruku', 'nanoc/filters/maruku'
17
18
  autoload 'Mustache', 'nanoc/filters/mustache'
19
+ autoload 'Pandoc', 'nanoc/filters/pandoc'
18
20
  autoload 'Rainpress', 'nanoc/filters/rainpress'
19
21
  autoload 'RDiscount', 'nanoc/filters/rdiscount'
20
22
  autoload 'RDoc', 'nanoc/filters/rdoc'
@@ -37,11 +39,13 @@ module Nanoc::Filters
37
39
  Nanoc::Filter.register '::Nanoc::Filters::ERB', :erb
38
40
  Nanoc::Filter.register '::Nanoc::Filters::Erubis', :erubis
39
41
  Nanoc::Filter.register '::Nanoc::Filters::Haml', :haml
42
+ Nanoc::Filter.register '::Nanoc::Filters::Handlebars', :handlebars
40
43
  Nanoc::Filter.register '::Nanoc::Filters::Kramdown', :kramdown
41
44
  Nanoc::Filter.register '::Nanoc::Filters::Less', :less
42
45
  Nanoc::Filter.register '::Nanoc::Filters::Markaby', :markaby
43
46
  Nanoc::Filter.register '::Nanoc::Filters::Maruku', :maruku
44
47
  Nanoc::Filter.register '::Nanoc::Filters::Mustache', :mustache
48
+ Nanoc::Filter.register '::Nanoc::Filters::Pandoc', :pandoc
45
49
  Nanoc::Filter.register '::Nanoc::Filters::Rainpress', :rainpress
46
50
  Nanoc::Filter.register '::Nanoc::Filters::RDiscount', :rdiscount
47
51
  Nanoc::Filter.register '::Nanoc::Filters::RDoc', :rdoc
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'handlebars'
4
+
5
+ module Nanoc::Filters
6
+
7
+ # @since 3.4.0
8
+ class Handlebars < Nanoc::Filter
9
+
10
+ # Runs the content through
11
+ # [Handlebars](http://handlebarsjs.com/) using
12
+ # [Handlebars.rb](https://github.com/cowboyd/handlebars.rb).
13
+ # This method takes no options.
14
+ #
15
+ # @param [String] content The content to filter
16
+ #
17
+ # @return [String] The filtered content
18
+ def run(content, params={})
19
+ context = item.attributes.dup
20
+ context[:item] = assigns[:item].attributes
21
+ context[:layout] = assigns[:layout].attributes
22
+ context[:config] = assigns[:config]
23
+ context[:yield] = assigns[:content]
24
+
25
+ ::Handlebars.compile(content).call(context)
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -15,8 +15,8 @@ module Nanoc::Filters
15
15
  #
16
16
  # @return [String] The filtered content
17
17
  def run(content, params={})
18
- # Get result
19
- ::Mustache.render(content, item.attributes)
18
+ context = item.attributes.merge({ :yield => assigns[:content] })
19
+ ::Mustache.render(content, context)
20
20
  end
21
21
 
22
22
  end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pandoc-ruby'
4
+
5
+ module Nanoc::Filters
6
+ class Pandoc < Nanoc::Filter
7
+
8
+ # Runs the content through [Pandoc](http://johnmacfarlane.net/pandoc/)
9
+ # using [PandocRuby](https://github.com/alphabetum/pandoc-ruby). Options
10
+ # are passed on to PandocRuby.
11
+ #
12
+ # @param [String] content The content to filter
13
+ #
14
+ # @return [String] The filtered content
15
+ def run(content, params={})
16
+ PandocRuby.convert(content, params)
17
+ end
18
+
19
+ end
20
+ end
@@ -25,7 +25,7 @@ module Nanoc::Helpers
25
25
  # @param [Symbol] filter_name The name of the filter to run on the
26
26
  # contents of the block
27
27
  #
28
- # @param [Hash] argument Arguments to pass to the filter
28
+ # @param [Hash] arguments Arguments to pass to the filter
29
29
  #
30
30
  # @return [void]
31
31
  def filter(filter_name, arguments={}, &block)
@@ -2,91 +2,33 @@
2
2
 
3
3
  namespace :validate do
4
4
 
5
- desc 'Validate the site’s HTML files'.make_compatible_with_env
5
+ desc 'Validate the site’s HTML files'
6
6
  task :html do
7
- # Get output directory
8
- site = Nanoc::Site.new('.')
9
- if site.nil?
10
- $stderr.puts 'The current working directory does not seem to be a ' +
11
- 'valid/complete nanoc site directory; aborting.'
12
- exit 1
13
- end
14
- dir = site.config[:output_dir]
15
-
16
- # Validate
17
- validator = ::Nanoc::Extra::Validators::W3C.new(dir, [ :html ])
18
- validator.run
7
+ Nanoc::CLI.run %w( validate_html )
19
8
  end
20
9
 
21
- desc 'Validate the site’s CSS files'.make_compatible_with_env
10
+ desc 'Validate the site’s CSS files'
22
11
  task :css do
23
- # Get output directory
24
- site = Nanoc::Site.new('.')
25
- if site.nil?
26
- $stderr.puts 'The current working directory does not seem to be a ' +
27
- 'valid/complete nanoc site directory; aborting.'
28
- exit 1
29
- end
30
- dir = site.config[:output_dir]
31
-
32
- # Validate
33
- validator = ::Nanoc::Extra::Validators::W3C.new(dir, [ :css ])
34
- validator.run
12
+ Nanoc::CLI.run %w( validate_css )
35
13
  end
36
14
 
37
15
  namespace :links do
38
16
 
39
- desc 'Validate the site’s internal links'.make_compatible_with_env
17
+ desc 'Validate the site’s internal links'
40
18
  task :internal do
41
- # Get output directory
42
- site = Nanoc::Site.new('.')
43
- if site.nil?
44
- $stderr.puts 'The current working directory does not seem to be a ' +
45
- 'valid/complete nanoc site directory; aborting.'
46
- exit 1
47
- end
48
- dir = site.config[:output_dir]
49
- index_filenames = site.config[:index_filenames]
50
-
51
- # Validate
52
- validator = ::Nanoc::Extra::Validators::Links.new(dir, index_filenames, :internal => true)
53
- validator.run
19
+ Nanoc::CLI.run %w( validate_links --internal )
54
20
  end
55
21
 
56
- desc 'Validate the site’s internal links'.make_compatible_with_env
22
+ desc 'Validate the site’s external links'
57
23
  task :external do
58
- # Get output directory
59
- site = Nanoc::Site.new('.')
60
- if site.nil?
61
- $stderr.puts 'The current working directory does not seem to be a ' +
62
- 'valid/complete nanoc site directory; aborting.'
63
- exit 1
64
- end
65
- dir = site.config[:output_dir]
66
- index_filenames = site.config[:index_filenames]
67
-
68
- # Validate
69
- validator = ::Nanoc::Extra::Validators::Links.new(dir, index_filenames, :external => true)
70
- validator.run
24
+ Nanoc::CLI.run %w( validate_links --external )
71
25
  end
72
26
 
73
27
  end
74
28
 
75
- desc 'Validate the site’s internal and external links'.make_compatible_with_env
29
+ desc 'Validate the site’s internal and external links'
76
30
  task :links do
77
- # Get output directory
78
- site = Nanoc::Site.new('.')
79
- if site.nil?
80
- $stderr.puts 'The current working directory does not seem to be a ' +
81
- 'valid/complete nanoc site directory; aborting.'
82
- exit 1
83
- end
84
- dir = site.config[:output_dir]
85
- index_filenames = site.config[:index_filenames]
86
-
87
- # Validate
88
- validator = ::Nanoc::Extra::Validators::Links.new(dir, index_filenames, :internal => true, :external => true)
89
- validator.run
31
+ Nanoc::CLI.run %w( validate_links )
90
32
  end
91
33
 
92
34
  end
data/nanoc.gemspec CHANGED
@@ -30,20 +30,4 @@ Gem::Specification.new do |s|
30
30
  s.add_development_dependency('rake')
31
31
  s.add_development_dependency('rdiscount')
32
32
  s.add_development_dependency('yard')
33
-
34
- s.post_install_message = %q{------------------------------------------------------------------------------
35
- Thanks for installing nanoc 3.3! Here are some resources to help you get
36
- started:
37
-
38
- * The web site at <http://nanoc.stoneship.org/>
39
- * The tutorial at <http://nanoc.stoneship.org/docs/3-getting-started/>
40
- * The manual at <http://nanoc.stoneship.org/docs/4-basic-concepts/>
41
-
42
- If you have questions, issues or simply want to share ideas, join the
43
- discussion at <http://groups.google.com/group/nanoc> or stop by in the IRC
44
- channel on irc.freenode.net, channel #nanoc. See you there!
45
-
46
- Enjoy!
47
- ------------------------------------------------------------------------------
48
- }
49
33
  end
@@ -6,7 +6,7 @@ class Nanoc::CLI::Commands::CreateSiteTest < MiniTest::Unit::TestCase
6
6
 
7
7
  def test_create_site_with_existing_name
8
8
  Nanoc::CLI.run %w( create_site foo )
9
- assert_raises(SystemExit) do
9
+ assert_raises(::Nanoc::Errors::GenericTrivial) do
10
10
  Nanoc::CLI.run %w( create_site foo )
11
11
  end
12
12
  end
@@ -95,4 +95,49 @@ class Nanoc::CLI::Commands::DeployTest < MiniTest::Unit::TestCase
95
95
  end
96
96
  end
97
97
 
98
+ def test_deploy_without_target_without_default
99
+ if_have 'systemu' do
100
+ with_site do |site|
101
+ File.open('config.yaml', 'w') do |io|
102
+ io.write "deploy:\n"
103
+ io.write " public:\n"
104
+ io.write " dst: mydestination"
105
+ end
106
+
107
+ FileUtils.mkdir_p('output')
108
+ File.open('output/blah.html', 'w') { |io| io.write 'moo' }
109
+
110
+ ios = capturing_stdio do
111
+ assert_raises SystemExit do
112
+ Nanoc::CLI.run %w( deploy )
113
+ end
114
+ end
115
+
116
+ assert ios[:stderr].include?('The site configuration has no deploy configuration for default.')
117
+ end
118
+ end
119
+ end
120
+
121
+ def test_deploy_without_target_without_default
122
+ if_have 'systemu' do
123
+ with_site do |site|
124
+ File.open('config.yaml', 'w') do |io|
125
+ io.write "deploy:\n"
126
+ io.write " default:\n"
127
+ io.write " dst: mydestination"
128
+ end
129
+
130
+ FileUtils.mkdir_p('output')
131
+ File.open('output/blah.html', 'w') { |io| io.write 'moo' }
132
+
133
+ ios = capturing_stdio do
134
+ Nanoc::CLI.run %w( deploy )
135
+ end
136
+
137
+ assert File.directory?('mydestination')
138
+ assert File.file?('mydestination/blah.html')
139
+ end
140
+ end
141
+ end
142
+
98
143
  end
data/test/cli/test_cli.rb CHANGED
@@ -99,7 +99,7 @@ EOS
99
99
 
100
100
  # Check error output
101
101
  stderr_addition = $stderr.string[position_before, position_after]
102
- assert_match(/=== BACKTRACE:/, stderr_addition)
102
+ assert_match(/Stack trace:/, stderr_addition)
103
103
  assert_match(/commands\/_test.rb/, stderr_addition)
104
104
  end
105
105
  end