nanoc 3.3.7 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
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