nanoc 3.3.7 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +133 -0
- data/NEWS.md +15 -0
- data/lib/nanoc.rb +2 -2
- data/lib/nanoc/base/compilation/compiler.rb +1 -1
- data/lib/nanoc/base/compilation/item_rep_proxy.rb +3 -3
- data/lib/nanoc/base/core_ext/string.rb +0 -18
- data/lib/nanoc/base/errors.rb +24 -19
- data/lib/nanoc/base/plugin_registry.rb +1 -1
- data/lib/nanoc/base/result_data/item_rep.rb +1 -2
- data/lib/nanoc/base/source_data/site.rb +1 -1
- data/lib/nanoc/cli.rb +46 -4
- data/lib/nanoc/cli/ansi_string_colorizer.rb +30 -0
- data/lib/nanoc/cli/cleaning_stream.rb +91 -0
- data/lib/nanoc/cli/command_runner.rb +3 -11
- data/lib/nanoc/cli/commands/compile.rb +2 -2
- data/lib/nanoc/cli/commands/{create_item.rb → create-item.rb} +6 -7
- data/lib/nanoc/cli/commands/{create_layout.rb → create-layout.rb} +9 -10
- data/lib/nanoc/cli/commands/{create_site.rb → create-site.rb} +13 -14
- data/lib/nanoc/cli/commands/deploy.rb +4 -12
- data/lib/nanoc/cli/commands/nanoc.rb +4 -2
- data/lib/nanoc/cli/commands/prune.rb +1 -1
- data/lib/nanoc/cli/commands/{debug.rb → show-data.rb} +6 -5
- data/lib/nanoc/cli/commands/{info.rb → show-plugins.rb} +6 -6
- data/lib/nanoc/cli/commands/show-rules.rb +69 -0
- data/lib/nanoc/cli/commands/update.rb +1 -2
- data/lib/nanoc/cli/commands/validate-css.rb +24 -0
- data/lib/nanoc/cli/commands/validate-html.rb +24 -0
- data/lib/nanoc/cli/commands/validate-links.rb +35 -0
- data/lib/nanoc/cli/commands/watch.rb +3 -3
- data/lib/nanoc/cli/error_handler.rb +142 -26
- data/lib/nanoc/cli/logger.rb +4 -21
- data/lib/nanoc/cli/stream_cleaners.rb +14 -0
- data/lib/nanoc/cli/stream_cleaners/abstract.rb +23 -0
- data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +15 -0
- data/lib/nanoc/cli/stream_cleaners/utf8.rb +16 -0
- data/lib/nanoc/extra/deployers/rsync.rb +2 -7
- data/lib/nanoc/extra/pruner.rb +3 -3
- data/lib/nanoc/extra/validators/links.rb +14 -3
- data/lib/nanoc/filters.rb +4 -0
- data/lib/nanoc/filters/handlebars.rb +30 -0
- data/lib/nanoc/filters/mustache.rb +2 -2
- data/lib/nanoc/filters/pandoc.rb +20 -0
- data/lib/nanoc/helpers/filtering.rb +1 -1
- data/lib/nanoc/tasks/validate.rake +10 -68
- data/nanoc.gemspec +0 -16
- data/test/cli/commands/test_create_site.rb +1 -1
- data/test/cli/commands/test_deploy.rb +45 -0
- data/test/cli/test_cli.rb +1 -1
- data/test/extra/validators/test_links.rb +15 -5
- data/test/filters/test_handlebars.rb +42 -0
- data/test/filters/test_mustache.rb +19 -0
- data/test/filters/test_pandoc.rb +18 -0
- 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,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
|
-
|
43
|
-
|
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)
|
data/lib/nanoc/extra/pruner.rb
CHANGED
@@ -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
|
-
#
|
16
|
-
#
|
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 =
|
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
|
-
|
19
|
-
::Mustache.render(content,
|
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]
|
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'
|
5
|
+
desc 'Validate the site’s HTML files'
|
6
6
|
task :html do
|
7
|
-
|
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'
|
10
|
+
desc 'Validate the site’s CSS files'
|
22
11
|
task :css do
|
23
|
-
|
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'
|
17
|
+
desc 'Validate the site’s internal links'
|
40
18
|
task :internal do
|
41
|
-
|
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
|
22
|
+
desc 'Validate the site’s external links'
|
57
23
|
task :external do
|
58
|
-
|
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'
|
29
|
+
desc 'Validate the site’s internal and external links'
|
76
30
|
task :links do
|
77
|
-
|
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(
|
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(
|
102
|
+
assert_match(/Stack trace:/, stderr_addition)
|
103
103
|
assert_match(/commands\/_test.rb/, stderr_addition)
|
104
104
|
end
|
105
105
|
end
|