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.
- 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,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc::CLI
|
4
|
+
|
5
|
+
# A simple ANSI colorizer for strings. When given a string and a list of
|
6
|
+
# attributes, it returns a colorized string.
|
7
|
+
module ANSIStringColorizer
|
8
|
+
|
9
|
+
# TODO complete mapping
|
10
|
+
MAPPING = {
|
11
|
+
:bold => "\e[1m",
|
12
|
+
:red => "\e[31m",
|
13
|
+
:green => "\e[32m",
|
14
|
+
:yellow => "\e[33m",
|
15
|
+
:blue => "\e[34m"
|
16
|
+
}
|
17
|
+
|
18
|
+
# @param [String] s The string to colorize
|
19
|
+
#
|
20
|
+
# @param [Array] as An array of attributes from `MAPPING` to colorize the
|
21
|
+
# string with
|
22
|
+
#
|
23
|
+
# @return [String] A string colorized using the given attributes
|
24
|
+
def self.c(s, *as)
|
25
|
+
as.map { |a| MAPPING[a] }.join('') + s + "\e[0m"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc::CLI
|
4
|
+
|
5
|
+
# An output stream that passes output through stream cleaners. This can be
|
6
|
+
# used to strip ANSI color sequences, for instance.
|
7
|
+
class CleaningStream
|
8
|
+
|
9
|
+
# @param [IO, StringIO] stream The stream to wrap
|
10
|
+
def initialize(stream)
|
11
|
+
@stream = stream
|
12
|
+
@stream_cleaners = []
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds a stream cleaner for the given class to this cleaning stream. If the
|
16
|
+
# cleaning stream already has the given stream cleaner, nothing happens.
|
17
|
+
#
|
18
|
+
# @param [Nanoc::CLI::StreamCleaners::Abstract] klass The class of the
|
19
|
+
# stream cleaner to add
|
20
|
+
#
|
21
|
+
# @return [void]
|
22
|
+
def add_stream_cleaner(klass)
|
23
|
+
unless @stream_cleaners.map { |c| c.class }.include?(klass)
|
24
|
+
@stream_cleaners << klass.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Removes the stream cleaner for the given class from this cleaning stream.
|
29
|
+
# If the cleaning stream does not have the given stream cleaner, nothing
|
30
|
+
# happens.
|
31
|
+
#
|
32
|
+
# @param [Nanoc::CLI::StreamCleaners::Abstract] klass The class of the
|
33
|
+
# stream cleaner to add
|
34
|
+
#
|
35
|
+
# @return [void]
|
36
|
+
def remove_stream_cleaner(klass)
|
37
|
+
@stream_cleaners.delete_if { |c| c.class == klass }
|
38
|
+
end
|
39
|
+
|
40
|
+
# @group IO proxy methods
|
41
|
+
|
42
|
+
# @see IO#write
|
43
|
+
def write(s)
|
44
|
+
@stream.write(self.clean(s))
|
45
|
+
end
|
46
|
+
|
47
|
+
# @see IO#<<
|
48
|
+
def <<(s)
|
49
|
+
@stream.<<(self.clean(s))
|
50
|
+
end
|
51
|
+
|
52
|
+
# @see IO#tty?
|
53
|
+
def tty?
|
54
|
+
@stream.tty?
|
55
|
+
end
|
56
|
+
|
57
|
+
# @see IO#flush
|
58
|
+
def flush
|
59
|
+
@stream.flush
|
60
|
+
end
|
61
|
+
|
62
|
+
# @see IO#tell
|
63
|
+
def tell
|
64
|
+
@stream.tell
|
65
|
+
end
|
66
|
+
|
67
|
+
# @see IO#print
|
68
|
+
def print(s)
|
69
|
+
@stream.print(self.clean(s))
|
70
|
+
end
|
71
|
+
|
72
|
+
# @see IO#puts
|
73
|
+
def puts(*s)
|
74
|
+
@stream.puts(*s.map { |ss| self.clean(ss) })
|
75
|
+
end
|
76
|
+
|
77
|
+
# @see StringIO#string
|
78
|
+
def string
|
79
|
+
@stream.string
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def clean(s)
|
85
|
+
@stream_cleaners.inject(s) { |m,c| c.clean(m) }
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
@@ -23,12 +23,7 @@ module Nanoc::CLI
|
|
23
23
|
# Load site if possible
|
24
24
|
@site ||= nil
|
25
25
|
if File.file?('config.yaml') && @site.nil?
|
26
|
-
|
27
|
-
@site = Nanoc::Site.new('.')
|
28
|
-
rescue Nanoc::Errors::UnknownDataSource => e
|
29
|
-
$stderr.puts "Unknown data source: #{e}"
|
30
|
-
exit 1
|
31
|
-
end
|
26
|
+
@site = Nanoc::Site.new('.')
|
32
27
|
end
|
33
28
|
|
34
29
|
@site
|
@@ -57,9 +52,7 @@ module Nanoc::CLI
|
|
57
52
|
# @return [void]
|
58
53
|
def require_site
|
59
54
|
if site.nil?
|
60
|
-
|
61
|
-
'valid/complete nanoc site directory; aborting.'
|
62
|
-
exit 1
|
55
|
+
raise ::Nanoc::Errors::GenericTrivial, "The current working directory does not seem to be a nanoc site."
|
63
56
|
end
|
64
57
|
end
|
65
58
|
|
@@ -77,8 +70,7 @@ module Nanoc::CLI
|
|
77
70
|
# Find VCS
|
78
71
|
vcs_class = Nanoc::Extra::VCS.named(vcs_name.to_sym)
|
79
72
|
if vcs_class.nil?
|
80
|
-
|
81
|
-
exit 1
|
73
|
+
raise Nanoc::Errors::GenericTrivial, "A VCS named #{vcs_name} was not found"
|
82
74
|
end
|
83
75
|
|
84
76
|
site.data_sources.each do |data_source|
|
@@ -37,7 +37,7 @@ module Nanoc::CLI::Commands
|
|
37
37
|
# Warn if trying to compile a single item
|
38
38
|
if arguments.size == 1
|
39
39
|
$stderr.puts '-' * 80
|
40
|
-
$stderr.puts 'Note: As of nanoc 3.2, it is no longer possible to compile a single item. When invoking the “compile” command, all items in the site will be compiled.'
|
40
|
+
$stderr.puts 'Note: As of nanoc 3.2, it is no longer possible to compile a single item. When invoking the “compile” command, all items in the site will be compiled.'
|
41
41
|
$stderr.puts '-' * 80
|
42
42
|
end
|
43
43
|
|
@@ -221,7 +221,7 @@ module Nanoc::CLI::Commands
|
|
221
221
|
delay = 1.0
|
222
222
|
step = 0
|
223
223
|
|
224
|
-
text = "Running #{filter_name} filter… "
|
224
|
+
text = "Running #{filter_name} filter… "
|
225
225
|
|
226
226
|
while !Thread.current[:stopped]
|
227
227
|
sleep 0.1
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
usage '
|
3
|
+
usage 'create-item [options] identifier'
|
4
|
+
aliases :create_item, :ci
|
4
5
|
summary 'create an item'
|
5
|
-
aliases :ci
|
6
6
|
description <<-EOS
|
7
7
|
Create a new item in the current site. The first data source in the site
|
8
8
|
configuration will be used.
|
@@ -17,8 +17,7 @@ module Nanoc::CLI::Commands
|
|
17
17
|
def run
|
18
18
|
# Check arguments
|
19
19
|
if arguments.length != 1
|
20
|
-
|
21
|
-
exit 1
|
20
|
+
raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
|
22
21
|
end
|
23
22
|
|
24
23
|
# Extract arguments and options
|
@@ -32,9 +31,9 @@ module Nanoc::CLI::Commands
|
|
32
31
|
|
33
32
|
# Check whether item is unique
|
34
33
|
if !self.site.items.find { |i| i.identifier == identifier }.nil?
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
raise Nanoc::Errors::GenericTrivial,
|
35
|
+
"An item already exists at #{identifier}. Please " +
|
36
|
+
"pick a unique name for the item you are creating."
|
38
37
|
end
|
39
38
|
|
40
39
|
# Setup notifications
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
usage '
|
4
|
-
aliases
|
3
|
+
usage 'create-layout [options] identifier'
|
4
|
+
aliases :create_layout, :cl
|
5
5
|
summary 'create a layout'
|
6
6
|
description <<-EOS
|
7
7
|
Create a new layout in the current site. The first data source in the site
|
@@ -15,8 +15,7 @@ module Nanoc::CLI::Commands
|
|
15
15
|
def run
|
16
16
|
# Check arguments
|
17
17
|
if arguments.length != 1
|
18
|
-
|
19
|
-
exit 1
|
18
|
+
raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
|
20
19
|
end
|
21
20
|
|
22
21
|
# Extract arguments
|
@@ -30,16 +29,16 @@ module Nanoc::CLI::Commands
|
|
30
29
|
|
31
30
|
# Check whether layout is unique
|
32
31
|
if !self.site.layouts.find { |l| l.identifier == identifier }.nil?
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
raise Nanoc::Errors::GenericTrivial,
|
33
|
+
"A layout already exists at #{identifier}. Please " +
|
34
|
+
"pick a unique name for the layout you are creating."
|
36
35
|
end
|
37
36
|
|
38
37
|
# Check whether layout is not at /
|
39
38
|
if identifier == '/'
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
raise Nanoc::Errors::GenericTrivial,
|
40
|
+
"There cannot be a layout with the identifier '/'; " +
|
41
|
+
"please pick a different identifier for this layout."
|
43
42
|
end
|
44
43
|
|
45
44
|
# Setup notifications
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
usage '
|
4
|
-
aliases
|
3
|
+
usage 'create-site [options] path'
|
4
|
+
aliases :create_site, :cs
|
5
5
|
summary 'create a site'
|
6
6
|
description <<-EOS
|
7
7
|
Create a new site at the given path. The site will use the filesystem_unified data source by default, but this can be changed using the --datasource commandline option.
|
@@ -274,7 +274,9 @@ EOS
|
|
274
274
|
<meta charset="utf-8">
|
275
275
|
<title>A Brand New nanoc Site - <%= @item[:title] %></title>
|
276
276
|
<link rel="stylesheet" type="text/css" href="/style.css" media="screen">
|
277
|
-
|
277
|
+
|
278
|
+
<!-- you don't need to keep this, but it's cool for stats! -->
|
279
|
+
<meta name="generator" content="nanoc <%= Nanoc::VERSION %>">
|
278
280
|
</head>
|
279
281
|
<body>
|
280
282
|
<div id="main">
|
@@ -300,8 +302,7 @@ EOS
|
|
300
302
|
def run
|
301
303
|
# Check arguments
|
302
304
|
if arguments.length != 1
|
303
|
-
|
304
|
-
exit 1
|
305
|
+
raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
|
305
306
|
end
|
306
307
|
|
307
308
|
# Extract arguments and options
|
@@ -310,14 +311,12 @@ EOS
|
|
310
311
|
|
311
312
|
# Check whether site exists
|
312
313
|
if File.exist?(path)
|
313
|
-
|
314
|
-
exit 1
|
314
|
+
raise Nanoc::Errors::GenericTrivial, "A site at '#{path}' already exists."
|
315
315
|
end
|
316
316
|
|
317
317
|
# Check whether data source exists
|
318
318
|
if Nanoc::DataSource.named(data_source).nil?
|
319
|
-
|
320
|
-
exit 1
|
319
|
+
raise Nanoc::Errors::GenericTrivial, "Unrecognised data source: #{data_source}"
|
321
320
|
end
|
322
321
|
|
323
322
|
# Setup notifications
|
@@ -345,12 +344,12 @@ EOS
|
|
345
344
|
FileUtils.mkdir_p('output')
|
346
345
|
|
347
346
|
# Create config
|
348
|
-
File.open('config.yaml', 'w') { |io| io.write(DEFAULT_CONFIG
|
347
|
+
File.open('config.yaml', 'w') { |io| io.write(DEFAULT_CONFIG) }
|
349
348
|
Nanoc::NotificationCenter.post(:file_created, 'config.yaml')
|
350
349
|
|
351
350
|
# Create rules
|
352
351
|
File.open('Rules', 'w') do |io|
|
353
|
-
io.write DEFAULT_RULES
|
352
|
+
io.write DEFAULT_RULES
|
354
353
|
end
|
355
354
|
Nanoc::NotificationCenter.post(:file_created, 'Rules')
|
356
355
|
end
|
@@ -376,14 +375,14 @@ EOS
|
|
376
375
|
|
377
376
|
# Create home page
|
378
377
|
data_source.create_item(
|
379
|
-
DEFAULT_ITEM
|
378
|
+
DEFAULT_ITEM,
|
380
379
|
{ :title => "Home" },
|
381
380
|
'/'
|
382
381
|
)
|
383
382
|
|
384
383
|
# Create stylesheet
|
385
384
|
data_source.create_item(
|
386
|
-
DEFAULT_STYLESHEET
|
385
|
+
DEFAULT_STYLESHEET,
|
387
386
|
{},
|
388
387
|
'/stylesheet/',
|
389
388
|
:extension => '.css'
|
@@ -391,7 +390,7 @@ EOS
|
|
391
390
|
|
392
391
|
# Create layout
|
393
392
|
data_source.create_layout(
|
394
|
-
DEFAULT_LAYOUT
|
393
|
+
DEFAULT_LAYOUT,
|
395
394
|
{},
|
396
395
|
'/default/'
|
397
396
|
)
|
@@ -28,8 +28,7 @@ module Nanoc::CLI::Commands
|
|
28
28
|
|
29
29
|
# Get config
|
30
30
|
deploy_configs = site.config.fetch(:deploy) do
|
31
|
-
|
32
|
-
exit 1
|
31
|
+
raise Nanoc::Errors::GenericTrivial, "The site configuration has no deploy configuration."
|
33
32
|
end
|
34
33
|
|
35
34
|
# List
|
@@ -42,14 +41,9 @@ module Nanoc::CLI::Commands
|
|
42
41
|
end
|
43
42
|
|
44
43
|
# Get target
|
45
|
-
target = options.fetch(:target)
|
46
|
-
$stderr.puts "The deploy command requires a --target option."
|
47
|
-
exit 1
|
48
|
-
end
|
49
|
-
target = target.to_sym
|
44
|
+
target = options.fetch(:target, :default).to_sym
|
50
45
|
config = deploy_configs.fetch(target) do
|
51
|
-
|
52
|
-
exit 1
|
46
|
+
raise Nanoc::Errors::GenericTrivial, "The site configuration has no deploy configuration for #{target}."
|
53
47
|
end
|
54
48
|
|
55
49
|
# Get deployer
|
@@ -60,9 +54,7 @@ module Nanoc::CLI::Commands
|
|
60
54
|
end
|
61
55
|
deployer_class = Nanoc::Extra::Deployer.named(name)
|
62
56
|
if deployer_class.nil?
|
63
|
-
|
64
|
-
$stderr.puts "(expected one of #{names.join(', ')})"
|
65
|
-
exit 1
|
57
|
+
raise Nanoc::Errors::GenericTrivial, "The specified deploy target has an unrecognised kind “#{name}” (expected one of #{names.join(', ')})."
|
66
58
|
end
|
67
59
|
|
68
60
|
# Run
|
@@ -4,7 +4,8 @@ usage 'nanoc command [options] [arguments]'
|
|
4
4
|
summary 'nanoc, a static site compiler written in Ruby'
|
5
5
|
|
6
6
|
opt :l, :color, 'enable color' do
|
7
|
-
Nanoc::CLI::
|
7
|
+
$stdout.remove_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
8
|
+
$stderr.remove_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
8
9
|
end
|
9
10
|
|
10
11
|
opt :d, :debug, 'enable debugging' do
|
@@ -17,7 +18,8 @@ opt :h, :help, 'show the help message and quit' do |value, cmd|
|
|
17
18
|
end
|
18
19
|
|
19
20
|
opt :C, :'no-color', 'disable color' do
|
20
|
-
Nanoc::CLI::
|
21
|
+
$stdout.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
22
|
+
$stderr.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
21
23
|
end
|
22
24
|
|
23
25
|
opt :V, :verbose, 'make nanoc output more detailed' do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
usage 'prune'
|
4
|
-
summary '
|
4
|
+
summary 'remove files not managed by nanoc from the output directory'
|
5
5
|
description <<-EOS
|
6
6
|
Find all files in the output directory that do not correspond to an item
|
7
7
|
managed by nanoc and remove them. Since this is a hazardous operation, an
|
@@ -1,15 +1,16 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
usage '
|
4
|
-
|
3
|
+
usage 'show-data'
|
4
|
+
aliases :debug
|
5
|
+
summary 'show data in this site'
|
5
6
|
description <<-EOS
|
6
7
|
Show information about all items, item representations and layouts in the
|
7
|
-
current site.
|
8
|
+
current site, along with dependency information.
|
8
9
|
EOS
|
9
10
|
|
10
11
|
module Nanoc::CLI::Commands
|
11
12
|
|
12
|
-
class
|
13
|
+
class ShowData < ::Nanoc::CLI::CommandRunner
|
13
14
|
|
14
15
|
def run
|
15
16
|
# Make sure we are in a nanoc site directory
|
@@ -114,4 +115,4 @@ module Nanoc::CLI::Commands
|
|
114
115
|
|
115
116
|
end
|
116
117
|
|
117
|
-
runner Nanoc::CLI::Commands::
|
118
|
+
runner Nanoc::CLI::Commands::ShowData
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
summary 'show
|
4
|
-
|
3
|
+
summary 'show all available plugins'
|
4
|
+
aliases :info
|
5
|
+
usage 'show-plugins [options]'
|
5
6
|
description <<-EOS
|
6
7
|
Show a list of available plugins, including filters, data sources and VCSes.
|
7
8
|
If the current directory contains a nanoc web site, the plugins defined in this site will be shown as well.
|
@@ -9,13 +10,12 @@ EOS
|
|
9
10
|
|
10
11
|
module Nanoc::CLI::Commands
|
11
12
|
|
12
|
-
class
|
13
|
+
class ShowPlugins < ::Nanoc::CLI::CommandRunner
|
13
14
|
|
14
15
|
def run
|
15
16
|
# Check arguments
|
16
17
|
if arguments.size != 0
|
17
|
-
|
18
|
-
exit 1
|
18
|
+
raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
|
19
19
|
end
|
20
20
|
|
21
21
|
# Get list of plugins (before and after)
|
@@ -95,4 +95,4 @@ module Nanoc::CLI::Commands
|
|
95
95
|
|
96
96
|
end
|
97
97
|
|
98
|
-
runner Nanoc::CLI::Commands::
|
98
|
+
runner Nanoc::CLI::Commands::ShowPlugins
|