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,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
usage 'show-rules [thing]'
|
4
|
+
aliases :explain
|
5
|
+
summary 'describe the rules for each item'
|
6
|
+
description <<-EOS
|
7
|
+
Prints the rules used for all items and layouts in the current site. An argument can be given, which can be either an item identifier (e.g. /foo/), the path to the source file (e.g. content/foo.html) or the path to the output file (e.g. output/foo.html).
|
8
|
+
EOS
|
9
|
+
|
10
|
+
module Nanoc::CLI::Commands
|
11
|
+
|
12
|
+
class ShowRules < ::Nanoc::CLI::CommandRunner
|
13
|
+
|
14
|
+
def run
|
15
|
+
self.require_site
|
16
|
+
|
17
|
+
@c = Nanoc::CLI::ANSIStringColorizer
|
18
|
+
@calc = self.site.compiler.rule_memory_calculator
|
19
|
+
|
20
|
+
# TODO explain /foo/
|
21
|
+
# TODO explain content/foo.html
|
22
|
+
# TODO explain output/foo/index.html
|
23
|
+
|
24
|
+
self.site.items.each { |i| self.explain_item(i) }
|
25
|
+
self.site.layouts.each { |l| self.explain_layout(l) }
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def explain_item(item)
|
31
|
+
puts "#{@c.c('Item ' + item.identifier, :bold, :yellow)}:"
|
32
|
+
puts " (from #{item[:filename]})" if item[:filename]
|
33
|
+
item.reps.each do |rep|
|
34
|
+
puts " Rep #{rep.name}:"
|
35
|
+
if @calc[rep].empty? && rep.raw_path.nil?
|
36
|
+
puts " (nothing)"
|
37
|
+
else
|
38
|
+
@calc[rep].each do |mem|
|
39
|
+
puts ' %s %s' % [
|
40
|
+
@c.c(format('%-10s', mem[0].to_s), :blue),
|
41
|
+
mem[1..-1].map { |m| m.inspect }.join(', ')
|
42
|
+
]
|
43
|
+
end
|
44
|
+
if rep.raw_path
|
45
|
+
puts ' %s %s' % [
|
46
|
+
@c.c(format('%-10s', 'write to'), :blue),
|
47
|
+
rep.raw_path
|
48
|
+
]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
puts
|
53
|
+
end
|
54
|
+
|
55
|
+
def explain_layout(layout)
|
56
|
+
puts "#{@c.c('Layout ' + layout.identifier, :bold, :yellow)}:"
|
57
|
+
puts " (from #{layout[:filename]})" if layout[:filename]
|
58
|
+
puts " %s %s" % [
|
59
|
+
@c.c(format('%-10s', 'filter'), :blue),
|
60
|
+
@calc[layout].map { |m| m.inspect }.join(', ')
|
61
|
+
]
|
62
|
+
puts
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
runner Nanoc::CLI::Commands::ShowRules
|
@@ -22,8 +22,7 @@ module Nanoc::CLI::Commands
|
|
22
22
|
def run
|
23
23
|
# Check arguments
|
24
24
|
if arguments.size != 0
|
25
|
-
|
26
|
-
exit 1
|
25
|
+
raise Nanoc::Errors::GenericTrivial, "usage: #{command.usage}"
|
27
26
|
end
|
28
27
|
|
29
28
|
# Make sure we are in a nanoc site directory
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
usage 'validate-css [options]'
|
4
|
+
aliases :validate_css, :vcss
|
5
|
+
summary 'validate the site’s CSS'
|
6
|
+
description <<-EOS
|
7
|
+
Validates the site’s CSS files.
|
8
|
+
EOS
|
9
|
+
|
10
|
+
module Nanoc::CLI::Commands
|
11
|
+
|
12
|
+
class ValidateCSS < ::Nanoc::CLI::CommandRunner
|
13
|
+
|
14
|
+
def run
|
15
|
+
require_site
|
16
|
+
validator = ::Nanoc::Extra::Validators::W3C.new(site.config[:output_dir], [ :css ])
|
17
|
+
validator.run
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
runner Nanoc::CLI::Commands::ValidateCSS
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
usage 'validate-html [options]'
|
4
|
+
aliases :validate_html, :vhtml
|
5
|
+
summary 'validate the site’s HTML'
|
6
|
+
description <<-EOS
|
7
|
+
Validates the site’s HTML files.
|
8
|
+
EOS
|
9
|
+
|
10
|
+
module Nanoc::CLI::Commands
|
11
|
+
|
12
|
+
class ValidateHTML < ::Nanoc::CLI::CommandRunner
|
13
|
+
|
14
|
+
def run
|
15
|
+
require_site
|
16
|
+
validator = ::Nanoc::Extra::Validators::W3C.new(site.config[:output_dir], [ :html ])
|
17
|
+
validator.run
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
runner Nanoc::CLI::Commands::ValidateHTML
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
usage 'validate-links [options]'
|
4
|
+
aliases :validate_links, :vlink
|
5
|
+
summary 'validate links in site'
|
6
|
+
description <<-EOS
|
7
|
+
Validates the site’s links. By default, both internal and external links will be checked.
|
8
|
+
EOS
|
9
|
+
|
10
|
+
flag :i, :internal, 'validate internal links only'
|
11
|
+
flag :e, :external, 'validate external links only'
|
12
|
+
|
13
|
+
module Nanoc::CLI::Commands
|
14
|
+
|
15
|
+
class ValidateLinks < ::Nanoc::CLI::CommandRunner
|
16
|
+
|
17
|
+
def run
|
18
|
+
require_site
|
19
|
+
|
20
|
+
dir = site.config[:output_dir]
|
21
|
+
index_filenames = site.config[:index_filenames]
|
22
|
+
|
23
|
+
validator = ::Nanoc::Extra::Validators::Links.new(
|
24
|
+
dir,
|
25
|
+
index_filenames,
|
26
|
+
:internal => (options[:external] ? false : true),
|
27
|
+
:external => (options[:internal] ? false : true))
|
28
|
+
validator.run
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
runner Nanoc::CLI::Commands::ValidateLinks
|
@@ -30,9 +30,9 @@ module Nanoc::CLI::Commands
|
|
30
30
|
|
31
31
|
# Notify
|
32
32
|
if filename
|
33
|
-
print "Change detected to #{filename}; recompiling… "
|
33
|
+
print "Change detected to #{filename}; recompiling… "
|
34
34
|
else
|
35
|
-
print "Watcher started; compiling the entire site… "
|
35
|
+
print "Watcher started; compiling the entire site… "
|
36
36
|
end
|
37
37
|
|
38
38
|
# Recompile
|
@@ -71,7 +71,7 @@ module Nanoc::CLI::Commands
|
|
71
71
|
files_to_watch.delete_if { |f| !File.file?(f) }
|
72
72
|
|
73
73
|
# Watch
|
74
|
-
puts "Watching for changes…"
|
74
|
+
puts "Watching for changes…"
|
75
75
|
watcher = lambda do |*args|
|
76
76
|
update(&rebuilder)
|
77
77
|
delete(&rebuilder)
|
@@ -61,6 +61,9 @@ module Nanoc::CLI
|
|
61
61
|
|
62
62
|
# Run
|
63
63
|
yield
|
64
|
+
rescue Nanoc::Errors::GenericTrivial => e
|
65
|
+
$stderr.puts "Error: #{e.message}"
|
66
|
+
exit(1)
|
64
67
|
rescue Interrupt => e
|
65
68
|
exit(1)
|
66
69
|
rescue StandardError, ScriptError => e
|
@@ -85,50 +88,149 @@ module Nanoc::CLI
|
|
85
88
|
#
|
86
89
|
# @return [void]
|
87
90
|
def print_error(error)
|
91
|
+
write_compact_error(error, $stderr)
|
92
|
+
File.open('crash.log', 'w') { |io| write_verbose_error(error, io) }
|
93
|
+
end
|
94
|
+
|
95
|
+
# Writes a compact representation of the error, suitable for a terminal, on
|
96
|
+
# the given stream (probably stderr).
|
97
|
+
#
|
98
|
+
# @param [Error] error The error that should be described
|
99
|
+
#
|
100
|
+
# @param [IO] stream The stream to write the description too
|
101
|
+
#
|
102
|
+
# @api private
|
103
|
+
#
|
104
|
+
# @return [void]
|
105
|
+
def write_compact_error(error, stream)
|
88
106
|
# Header
|
89
|
-
|
90
|
-
|
107
|
+
stream.puts
|
108
|
+
stream.puts "Captain! We’ve been hit!"
|
91
109
|
|
92
110
|
# Exception and resolution (if any)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
111
|
+
stream.puts
|
112
|
+
stream.puts format_title('Message:')
|
113
|
+
stream.puts
|
114
|
+
stream.puts "#{error.class}: #{error.message}"
|
97
115
|
resolution = self.resolution_for(error)
|
98
|
-
|
116
|
+
stream.puts "#{resolution}" if resolution
|
99
117
|
|
100
118
|
# Compilation stack
|
101
|
-
|
102
|
-
|
103
|
-
|
119
|
+
stream.puts
|
120
|
+
stream.puts format_title('Compilation stack:')
|
121
|
+
stream.puts
|
104
122
|
if self.stack.empty?
|
105
|
-
|
123
|
+
stream.puts " (empty)"
|
106
124
|
else
|
107
125
|
self.stack.reverse.each do |obj|
|
108
126
|
if obj.is_a?(Nanoc::ItemRep)
|
109
|
-
|
127
|
+
stream.puts " - [item] #{obj.item.identifier} (rep #{obj.name})"
|
110
128
|
else # layout
|
111
|
-
|
129
|
+
stream.puts " - [layout] #{obj.identifier}"
|
112
130
|
end
|
113
131
|
end
|
114
132
|
end
|
115
133
|
|
116
134
|
# Backtrace
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
135
|
+
stream.puts
|
136
|
+
stream.puts format_title('Stack trace:')
|
137
|
+
stream.puts
|
138
|
+
count = 10
|
139
|
+
error.backtrace[0...count].each_with_index do |item, index|
|
140
|
+
stream.puts " #{index}. #{item}"
|
141
|
+
end
|
142
|
+
if error.backtrace.size > count
|
143
|
+
puts " ... #{error.backtrace.size - count} more lines omitted. See full crash log for details."
|
144
|
+
end
|
127
145
|
|
128
146
|
# Issue link
|
129
|
-
|
130
|
-
|
131
|
-
|
147
|
+
stream.puts
|
148
|
+
stream.puts "If you believe this is a bug in nanoc, please do report it at"
|
149
|
+
stream.puts "-> https://github.com/ddfreyne/nanoc/issues/new <-"
|
150
|
+
stream.puts
|
151
|
+
stream.puts "A detailed crash log has been written to ./crash.log."
|
152
|
+
end
|
153
|
+
|
154
|
+
# Writes a verbose representation of the error on the given stream.
|
155
|
+
#
|
156
|
+
# @param [Error] error The error that should be described
|
157
|
+
#
|
158
|
+
# @param [IO] stream The stream to write the description too
|
159
|
+
#
|
160
|
+
# @api private
|
161
|
+
#
|
162
|
+
# @return [void]
|
163
|
+
def write_verbose_error(error, stream)
|
164
|
+
# Date and time
|
165
|
+
stream.puts "Crashlog created at #{Time.now}"
|
166
|
+
stream.puts
|
167
|
+
|
168
|
+
# Exception and resolution (if any)
|
169
|
+
stream.puts '=== MESSAGE:'
|
170
|
+
stream.puts
|
171
|
+
stream.puts "#{error.class}: #{error.message}"
|
172
|
+
resolution = self.resolution_for(error)
|
173
|
+
stream.puts "#{resolution}" if resolution
|
174
|
+
stream.puts
|
175
|
+
|
176
|
+
# Compilation stack
|
177
|
+
stream.puts '=== COMPILATION STACK:'
|
178
|
+
stream.puts
|
179
|
+
if self.stack.empty?
|
180
|
+
stream.puts " (empty)"
|
181
|
+
else
|
182
|
+
self.stack.reverse.each do |obj|
|
183
|
+
if obj.is_a?(Nanoc::ItemRep)
|
184
|
+
stream.puts " - [item] #{obj.item.identifier} (rep #{obj.name})"
|
185
|
+
else # layout
|
186
|
+
stream.puts " - [layout] #{obj.identifier}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
stream.puts
|
191
|
+
|
192
|
+
# Backtrace
|
193
|
+
stream.puts '=== BACKTRACE:'
|
194
|
+
stream.puts
|
195
|
+
stream.puts error.backtrace.to_enum(:each_with_index).map { |item, index| " #{index}. #{item}" }.join("\n")
|
196
|
+
stream.puts
|
197
|
+
|
198
|
+
# Version information
|
199
|
+
stream.puts '=== VERSION INFORMATION:'
|
200
|
+
stream.puts
|
201
|
+
stream.puts Nanoc.version_information
|
202
|
+
stream.puts
|
203
|
+
|
204
|
+
# Installed gems
|
205
|
+
stream.puts '=== INSTALLED GEMS:'
|
206
|
+
stream.puts
|
207
|
+
self.gems_and_versions.each do |g|
|
208
|
+
stream.puts " #{g.first} #{g.last.join(', ')}"
|
209
|
+
end
|
210
|
+
stream.puts
|
211
|
+
|
212
|
+
# Environment
|
213
|
+
stream.puts '=== ENVIRONMENT:'
|
214
|
+
stream.puts
|
215
|
+
ENV.sort.each do |e|
|
216
|
+
stream.puts "#{e.first} => #{e.last.inspect}"
|
217
|
+
end
|
218
|
+
stream.puts
|
219
|
+
|
220
|
+
# Gemfile
|
221
|
+
if File.exist?('Gemfile.lock')
|
222
|
+
stream.puts '=== GEMFILE.LOCK:'
|
223
|
+
stream.puts
|
224
|
+
stream.puts File.read('Gemfile.lock')
|
225
|
+
stream.puts
|
226
|
+
end
|
227
|
+
|
228
|
+
# Load paths
|
229
|
+
stream.puts '=== $LOAD_PATH:'
|
230
|
+
stream.puts
|
231
|
+
$LOAD_PATH.each_with_index do |i, index|
|
232
|
+
stream.puts " #{index}. #{i}"
|
233
|
+
end
|
132
234
|
end
|
133
235
|
|
134
236
|
protected
|
@@ -155,6 +257,15 @@ module Nanoc::CLI
|
|
155
257
|
(compiler && compiler.stack) || []
|
156
258
|
end
|
157
259
|
|
260
|
+
def gems_and_versions
|
261
|
+
gems = {}
|
262
|
+
Gem::Specification.find_all.sort_by { |s| [ s.name, s.version ] }.each do |spec|
|
263
|
+
gems[spec.name] ||= []
|
264
|
+
gems[spec.name] << spec.version.to_s
|
265
|
+
end
|
266
|
+
gems
|
267
|
+
end
|
268
|
+
|
158
269
|
# A hash that contains the name of the gem for a given required file. If a
|
159
270
|
# `#require` fails, the gem name is looked up in this hash.
|
160
271
|
GEM_NAMES = {
|
@@ -168,6 +279,7 @@ module Nanoc::CLI
|
|
168
279
|
'fog' => 'fog',
|
169
280
|
'fssm' => 'fssm',
|
170
281
|
'haml' => 'haml',
|
282
|
+
'handlebars' => 'hbs',
|
171
283
|
'json' => 'json',
|
172
284
|
'kramdown' => 'kramdown',
|
173
285
|
'less' => 'less',
|
@@ -216,6 +328,10 @@ module Nanoc::CLI
|
|
216
328
|
end
|
217
329
|
end
|
218
330
|
|
331
|
+
def format_title(s)
|
332
|
+
"\e[1m\e[31m" + s + "\e[0m"
|
333
|
+
end
|
334
|
+
|
219
335
|
end
|
220
336
|
|
221
337
|
end
|
data/lib/nanoc/cli/logger.rb
CHANGED
@@ -27,27 +27,10 @@ module Nanoc::CLI
|
|
27
27
|
# @return [Symbol] The log level
|
28
28
|
attr_accessor :level
|
29
29
|
|
30
|
-
# @return [Boolean] True if color should be used, false otherwise
|
31
|
-
attr_writer :color
|
32
|
-
|
33
30
|
def initialize
|
34
31
|
@level = :high
|
35
32
|
end
|
36
33
|
|
37
|
-
# @return [Boolean] true if colors are enabled, false otherwise
|
38
|
-
def color?
|
39
|
-
if @color.nil?
|
40
|
-
@color = true
|
41
|
-
begin
|
42
|
-
require 'Win32/Console/ANSI' if RUBY_PLATFORM =~ /mswin|mingw/
|
43
|
-
rescue LoadError
|
44
|
-
@color = false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
@color
|
49
|
-
end
|
50
|
-
|
51
34
|
# Logs a file-related action.
|
52
35
|
#
|
53
36
|
# @param [:high, :low] level The importance of this action
|
@@ -57,15 +40,15 @@ module Nanoc::CLI
|
|
57
40
|
# @param [String] name The name of the file the action was performed on
|
58
41
|
#
|
59
42
|
# @return [void]
|
60
|
-
def file(level, action,
|
43
|
+
def file(level, action, name, duration=nil)
|
61
44
|
log(
|
62
45
|
level,
|
63
46
|
'%s%12s%s %s%s' % [
|
64
|
-
|
47
|
+
ACTION_COLORS[action.to_sym],
|
65
48
|
action,
|
66
|
-
|
49
|
+
"\e[0m",
|
67
50
|
duration.nil? ? '' : "[%2.2fs] " % [ duration ],
|
68
|
-
|
51
|
+
name
|
69
52
|
]
|
70
53
|
)
|
71
54
|
end
|