nanoc 3.7.5 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +2 -2
- data/Gemfile +1 -1
- data/NEWS.md +24 -3
- data/README.md +1 -1
- data/bin/nanoc +1 -1
- data/lib/nanoc/base/compilation/dependency_tracker.rb +1 -1
- data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +1 -1
- data/lib/nanoc/base/compilation/rule.rb +15 -1
- data/lib/nanoc/base/result_data/item_rep.rb +27 -10
- data/lib/nanoc/base/source_data/item_array.rb +2 -0
- data/lib/nanoc/base/source_data/site.rb +1 -0
- data/lib/nanoc/cli.rb +16 -7
- data/lib/nanoc/cli/commands/autocompile.rb +1 -1
- data/lib/nanoc/cli/commands/create-site.rb +2 -2
- data/lib/nanoc/cli/commands/show-rules.rb +3 -6
- data/lib/nanoc/cli/commands/watch.rb +3 -3
- data/lib/nanoc/cli/error_handler.rb +1 -1
- data/lib/nanoc/cli/logger.rb +3 -5
- data/lib/nanoc/data_sources/filesystem.rb +2 -2
- data/lib/nanoc/extra/auto_compiler.rb +1 -1
- data/lib/nanoc/extra/checking/checks.rb +2 -0
- data/lib/nanoc/extra/checking/checks/mixed_content.rb +31 -0
- data/lib/nanoc/extra/deployers/fog.rb +24 -0
- data/lib/nanoc/extra/link_collector.rb +42 -9
- data/lib/nanoc/extra/pruner.rb +1 -1
- data/lib/nanoc/filters/colorize_syntax.rb +4 -4
- data/lib/nanoc/filters/pandoc.rb +23 -4
- data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +4 -2
- data/lib/nanoc/helpers/blogging.rb +17 -6
- data/lib/nanoc/helpers/tagging.rb +1 -1
- data/lib/nanoc/helpers/text.rb +1 -1
- data/lib/nanoc/version.rb +1 -1
- data/tasks/test.rake +1 -1
- data/test/base/test_item_array.rb +8 -0
- data/test/base/test_item_rep.rb +51 -0
- data/test/base/test_item_rep_recorder_proxy.rb +19 -0
- data/test/base/test_rule.rb +10 -0
- data/test/cli/commands/test_create_site.rb +13 -0
- data/test/cli/test_cli.rb +30 -0
- data/test/extra/checking/checks/test_mixed_content.rb +188 -0
- data/test/extra/deployers/test_fog.rb +32 -0
- data/test/filters/test_pandoc.rb +17 -3
- data/test/filters/test_sass.rb +11 -0
- data/test/helper.rb +3 -3
- data/test/helpers/test_blogging.rb +30 -0
- metadata +6 -3
@@ -8,6 +8,10 @@ module Nanoc::Extra::Deployers
|
|
8
8
|
# deploy:
|
9
9
|
# public:
|
10
10
|
# kind: fog
|
11
|
+
# bucket: nanoc-site
|
12
|
+
# cdn_id: XXXXXX
|
13
|
+
# preprod:
|
14
|
+
# kind: fog
|
11
15
|
# provider: local
|
12
16
|
# local_root: ~/myCloud
|
13
17
|
# bucket: nanoc-site
|
@@ -25,6 +29,7 @@ module Nanoc::Extra::Deployers
|
|
25
29
|
src = File.expand_path(source_path)
|
26
30
|
bucket = config.delete(:bucket) || config.delete(:bucket_name)
|
27
31
|
path = config.delete(:path)
|
32
|
+
cdn_id = config.delete(:cdn_id)
|
28
33
|
|
29
34
|
config.delete(:kind)
|
30
35
|
|
@@ -33,6 +38,7 @@ module Nanoc::Extra::Deployers
|
|
33
38
|
|
34
39
|
# Mock if necessary
|
35
40
|
if self.dry_run?
|
41
|
+
puts 'Dry run - simulation'
|
36
42
|
::Fog.mock!
|
37
43
|
end
|
38
44
|
|
@@ -51,6 +57,7 @@ module Nanoc::Extra::Deployers
|
|
51
57
|
|
52
58
|
# Create bucket if necessary
|
53
59
|
if should_create_bucket
|
60
|
+
puts 'Creating bucket'
|
54
61
|
directory = connection.directories.create(key: bucket, prefix: path)
|
55
62
|
end
|
56
63
|
|
@@ -63,6 +70,7 @@ module Nanoc::Extra::Deployers
|
|
63
70
|
files += set
|
64
71
|
end
|
65
72
|
keys_to_destroy = files.all.map(&:key)
|
73
|
+
keys_to_invalidate = []
|
66
74
|
|
67
75
|
# Upload all the files in the output folder to the clouds
|
68
76
|
puts 'Uploading local files'
|
@@ -75,6 +83,7 @@ module Nanoc::Extra::Deployers
|
|
75
83
|
body: File.open(file_path),
|
76
84
|
public: true)
|
77
85
|
keys_to_destroy.delete(key)
|
86
|
+
keys_to_invalidate.push(key)
|
78
87
|
end
|
79
88
|
end
|
80
89
|
|
@@ -84,6 +93,21 @@ module Nanoc::Extra::Deployers
|
|
84
93
|
directory.files.get(key).destroy
|
85
94
|
end
|
86
95
|
|
96
|
+
# invalidate CDN objects
|
97
|
+
if cdn_id
|
98
|
+
puts 'Invalidating CDN distribution'
|
99
|
+
keys_to_invalidate.concat(keys_to_destroy)
|
100
|
+
cdn = ::Fog::CDN.new(config)
|
101
|
+
# fog cannot mock CDN requests
|
102
|
+
unless self.dry_run?
|
103
|
+
distribution = cdn.get_distribution(cdn_id)
|
104
|
+
# usual limit per invalidation: 1000 objects
|
105
|
+
keys_to_invalidate.each_slice(1000) do |paths|
|
106
|
+
cdn.post_invalidation(distribution, paths)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
87
111
|
puts 'Done!'
|
88
112
|
end
|
89
113
|
|
@@ -4,6 +4,17 @@ require 'set'
|
|
4
4
|
|
5
5
|
module ::Nanoc::Extra
|
6
6
|
class LinkCollector
|
7
|
+
URI_ATTRS = {
|
8
|
+
'a' => :href,
|
9
|
+
'audio' => :src,
|
10
|
+
'form' => :action,
|
11
|
+
'iframe' => :src,
|
12
|
+
'img' => :src,
|
13
|
+
'link' => :href,
|
14
|
+
'script' => :src,
|
15
|
+
'video' => :src
|
16
|
+
}
|
17
|
+
|
7
18
|
def initialize(filenames, mode = nil)
|
8
19
|
Nanoc::Extra::JRubyNokogiriWarner.check_and_warn
|
9
20
|
|
@@ -33,24 +44,46 @@ module ::Nanoc::Extra
|
|
33
44
|
filenames_per_href
|
34
45
|
end
|
35
46
|
|
47
|
+
def filenames_per_resource_uri
|
48
|
+
require 'nokogiri'
|
49
|
+
filenames_per_resource_uri = {}
|
50
|
+
@filenames.each do |filename|
|
51
|
+
resource_uris_in_file(filename).each do |resouce_uri|
|
52
|
+
filenames_per_resource_uri[resouce_uri] ||= Set.new
|
53
|
+
filenames_per_resource_uri[resouce_uri] << filename
|
54
|
+
end
|
55
|
+
end
|
56
|
+
filenames_per_resource_uri
|
57
|
+
end
|
58
|
+
|
36
59
|
def external_href?(href)
|
37
60
|
href =~ %r{^(\/\/|[a-z\-]+:)}
|
38
61
|
end
|
39
62
|
|
40
63
|
def hrefs_in_file(filename)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
64
|
+
uris_in_file filename, %w(a img)
|
65
|
+
end
|
66
|
+
|
67
|
+
def resource_uris_in_file(filename)
|
68
|
+
uris_in_file filename, %w(audio form img iframe link script video)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
45
72
|
|
46
|
-
|
47
|
-
|
48
|
-
|
73
|
+
def uris_in_file(filename, tag_names)
|
74
|
+
uris = Set.new
|
75
|
+
doc = Nokogiri::HTML(::File.read(filename))
|
76
|
+
tag_names.each do |tag_name|
|
77
|
+
attr = URI_ATTRS[tag_name]
|
78
|
+
doc.css(tag_name).each do |e|
|
79
|
+
uris << e[attr] unless e[attr].nil?
|
80
|
+
end
|
81
|
+
end
|
49
82
|
|
50
83
|
# Strip fragment
|
51
|
-
|
84
|
+
uris.map! { |href| href.gsub(/#.*$/, '') }
|
52
85
|
|
53
|
-
|
86
|
+
uris.select(&@filter)
|
54
87
|
end
|
55
88
|
end
|
56
89
|
end
|
data/lib/nanoc/extra/pruner.rb
CHANGED
@@ -29,7 +29,7 @@ module Nanoc::Filters
|
|
29
29
|
#
|
30
30
|
# * `:coderay` for [Coderay](http://coderay.rubychan.de/)
|
31
31
|
# * `:pygmentize` for [pygmentize](http://pygments.org/docs/cmdline/), the
|
32
|
-
#
|
32
|
+
# command-line frontend for [Pygments](http://pygments.org/)
|
33
33
|
# * `:pygmentsrb` for [pygments.rb](https://github.com/tmm1/pygments.rb),
|
34
34
|
# a Ruby interface for [Pygments](http://pygments.org/)
|
35
35
|
# * `:simon_highlight` for [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html)
|
@@ -201,7 +201,7 @@ module Nanoc::Filters
|
|
201
201
|
end
|
202
202
|
|
203
203
|
# Runs the content through [pygmentize](http://pygments.org/docs/cmdline/),
|
204
|
-
# the
|
204
|
+
# the command-line frontend for [Pygments](http://pygments.org/).
|
205
205
|
#
|
206
206
|
# @api private
|
207
207
|
#
|
@@ -216,7 +216,7 @@ module Nanoc::Filters
|
|
216
216
|
check_availability('pygmentize', '-V')
|
217
217
|
|
218
218
|
params[:encoding] ||= 'utf-8'
|
219
|
-
params[:nowrap]
|
219
|
+
params[:nowrap] ||= 'True'
|
220
220
|
|
221
221
|
cmd = ['pygmentize', '-l', language, '-f', 'html']
|
222
222
|
cmd << '-O' << params.map { |k, v| "#{k}=#{v}" }.join(',') unless params.empty?
|
@@ -246,7 +246,7 @@ module Nanoc::Filters
|
|
246
246
|
args[:lexer] ||= language
|
247
247
|
args[:options] ||= {}
|
248
248
|
args[:options][:encoding] ||= 'utf-8'
|
249
|
-
args[:options][:nowrap]
|
249
|
+
args[:options][:nowrap] ||= 'True'
|
250
250
|
|
251
251
|
Pygments.highlight(code, args)
|
252
252
|
end
|
data/lib/nanoc/filters/pandoc.rb
CHANGED
@@ -5,14 +5,33 @@ module Nanoc::Filters
|
|
5
5
|
requires 'pandoc-ruby'
|
6
6
|
|
7
7
|
# Runs the content through [Pandoc](http://johnmacfarlane.net/pandoc/)
|
8
|
-
# using [PandocRuby](https://github.com/alphabetum/pandoc-ruby).
|
9
|
-
#
|
8
|
+
# using [PandocRuby](https://github.com/alphabetum/pandoc-ruby).
|
9
|
+
#
|
10
|
+
# Arguments can be passed to PandocRuby in two ways:
|
11
|
+
#
|
12
|
+
# * Use the `:args` option. This approach is more flexible, since it
|
13
|
+
# allows passing an array instead of a hash.
|
14
|
+
#
|
15
|
+
# * Pass the arguments directly to the filter. With this approach, only
|
16
|
+
# hashes can be passed, which is more limiting than the `:args` approach.
|
17
|
+
#
|
18
|
+
# The `:args` approach is recommended.
|
19
|
+
#
|
20
|
+
# @example Passing arguments using `:arg`
|
21
|
+
#
|
22
|
+
# filter :pandoc, args: [:s, {:f => :markdown, :to => :html}, 'no-wrap', :toc]
|
23
|
+
#
|
24
|
+
# @example Passing arguments not using `:arg`
|
25
|
+
#
|
26
|
+
# filter :pandoc, :f => :markdown, :to => :html
|
10
27
|
#
|
11
28
|
# @param [String] content The content to filter
|
12
29
|
#
|
13
30
|
# @return [String] The filtered content
|
14
|
-
def run(content,
|
15
|
-
|
31
|
+
def run(content, params = {})
|
32
|
+
args = params.key?(:args) ? params[:args] : params
|
33
|
+
|
34
|
+
PandocRuby.convert(content, *args)
|
16
35
|
end
|
17
36
|
end
|
18
37
|
end
|
@@ -10,8 +10,10 @@ class ::Sass::Importers::Filesystem
|
|
10
10
|
|
11
11
|
# Create dependency
|
12
12
|
filter = options[:nanoc_current_filter]
|
13
|
-
|
14
|
-
|
13
|
+
if filter
|
14
|
+
item = filter.imported_filename_to_item(full_filename)
|
15
|
+
filter.depend_on([item]) unless item.nil?
|
16
|
+
end
|
15
17
|
|
16
18
|
# Call original _find
|
17
19
|
_orig_find(dir, name, options)
|
@@ -56,6 +56,7 @@ module Nanoc::Helpers
|
|
56
56
|
|
57
57
|
attr_accessor :limit
|
58
58
|
attr_accessor :relevant_articles
|
59
|
+
attr_accessor :preserve_order
|
59
60
|
attr_accessor :content_proc
|
60
61
|
attr_accessor :excerpt_proc
|
61
62
|
attr_accessor :title
|
@@ -85,9 +86,13 @@ module Nanoc::Helpers
|
|
85
86
|
protected
|
86
87
|
|
87
88
|
def sorted_relevant_articles
|
88
|
-
|
89
|
-
|
90
|
-
|
89
|
+
all = relevant_articles
|
90
|
+
|
91
|
+
unless @preserve_order
|
92
|
+
all = all.sort_by { |a| attribute_to_time(a[:created_at]) }
|
93
|
+
end
|
94
|
+
|
95
|
+
all.reverse.first(limit)
|
91
96
|
end
|
92
97
|
|
93
98
|
def last_article
|
@@ -172,7 +177,7 @@ module Nanoc::Helpers
|
|
172
177
|
if a[:author_name] || a[:author_uri]
|
173
178
|
xml.author do
|
174
179
|
xml.name a[:author_name] || author_name
|
175
|
-
xml.uri a[:author_uri]
|
180
|
+
xml.uri a[:author_uri] || author_uri
|
176
181
|
end
|
177
182
|
end
|
178
183
|
|
@@ -268,8 +273,13 @@ module Nanoc::Helpers
|
|
268
273
|
# @option params [Number] :limit (5) The maximum number of articles to
|
269
274
|
# show
|
270
275
|
#
|
271
|
-
# @option params [Array] :articles (
|
272
|
-
#
|
276
|
+
# @option params [Array] :articles (articles) A list of articles to include
|
277
|
+
# in the feed
|
278
|
+
#
|
279
|
+
# @option params [Boolean] :preserve_order (false) Whether or not the
|
280
|
+
# ordering of the list of articles should be preserved. If false, the
|
281
|
+
# articles will be sorted by `created_at`. If true, the list of articles
|
282
|
+
# will be used as-is, and should have the most recent articles last.
|
273
283
|
#
|
274
284
|
# @option params [Proc] :content_proc (->{ |article|
|
275
285
|
# article.compiled_content(:snapshot => :pre) }) A proc that returns the
|
@@ -303,6 +313,7 @@ module Nanoc::Helpers
|
|
303
313
|
# Fill builder
|
304
314
|
builder.limit = params[:limit] || 5
|
305
315
|
builder.relevant_articles = params[:articles] || articles || []
|
316
|
+
builder.preserve_order = params.fetch(:preserve_order, false)
|
306
317
|
builder.content_proc = params[:content_proc] || ->(a) { a.compiled_content(snapshot: :pre) }
|
307
318
|
builder.excerpt_proc = params[:excerpt_proc] || ->(a) { a[:excerpt] }
|
308
319
|
builder.title = params[:title] || @item[:title] || @site.config[:title]
|
@@ -29,7 +29,7 @@ module Nanoc::Helpers
|
|
29
29
|
#
|
30
30
|
# @return [String] A hyperlinked list of tags for the given item
|
31
31
|
def tags_for(item, params = {})
|
32
|
-
base_url = params[:base_url]
|
32
|
+
base_url = params[:base_url] || 'http://technorati.com/tag/'
|
33
33
|
none_text = params[:none_text] || '(none)'
|
34
34
|
separator = params[:separator] || ', '
|
35
35
|
|
data/lib/nanoc/helpers/text.rb
CHANGED
data/lib/nanoc/version.rb
CHANGED
data/tasks/test.rake
CHANGED
@@ -12,7 +12,7 @@ def run_tests(dir_glob)
|
|
12
12
|
test_files = Dir["#{dir_glob}*_spec.rb"] + Dir["#{dir_glob}test_*.rb"]
|
13
13
|
test_files.each { |f| require f }
|
14
14
|
|
15
|
-
res =
|
15
|
+
res = Minitest.run(ENV['ARGS'].split)
|
16
16
|
exit(res) if res != 0
|
17
17
|
end
|
18
18
|
|
@@ -96,6 +96,14 @@ class Nanoc::ItemArrayTest < Nanoc::TestCase
|
|
96
96
|
assert_nil @items.at('/tenthousand/')
|
97
97
|
end
|
98
98
|
|
99
|
+
def test_regex
|
100
|
+
foo = Nanoc::Item.new('Item Foo', {}, '/foo/')
|
101
|
+
@items << foo
|
102
|
+
|
103
|
+
assert_equal [@one], @items[/n/]
|
104
|
+
assert_equal [@two, foo], @items[%r{o/}]
|
105
|
+
end
|
106
|
+
|
99
107
|
def test_less_than_less_than
|
100
108
|
assert_nil @items[2]
|
101
109
|
assert_nil @items['/foo/']
|
data/test/base/test_item_rep.rb
CHANGED
@@ -77,6 +77,57 @@ class Nanoc::ItemRepTest < Nanoc::TestCase
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
def test_compiled_content_with_moving_pre_snapshot
|
81
|
+
# Create rep
|
82
|
+
item = Nanoc::Item.new(
|
83
|
+
'blah blah', {}, '/',
|
84
|
+
binary: false
|
85
|
+
)
|
86
|
+
rep = Nanoc::ItemRep.new(item, nil)
|
87
|
+
rep.expects(:compiled?).returns(false)
|
88
|
+
rep.instance_eval { @content = { pre: 'pre!', last: 'last!' } }
|
89
|
+
|
90
|
+
# Check
|
91
|
+
assert_raises(Nanoc::Errors::UnmetDependency) do
|
92
|
+
rep.compiled_content(snapshot: :pre)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_compiled_content_with_non_moving_pre_snapshot
|
97
|
+
# Create rep
|
98
|
+
item = Nanoc::Item.new(
|
99
|
+
'blah blah', {}, '/',
|
100
|
+
binary: false
|
101
|
+
)
|
102
|
+
rep = Nanoc::ItemRep.new(item, nil)
|
103
|
+
rep.expects(:compiled?).returns(false)
|
104
|
+
rep.snapshots = [[:pre, true]]
|
105
|
+
rep.instance_eval { @content = { pre: 'pre!', post: 'post!', last: 'last!' } }
|
106
|
+
|
107
|
+
# Check
|
108
|
+
assert_equal 'pre!', rep.compiled_content(snapshot: :pre)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_compiled_content_with_final_pre_snapshot_in_layout
|
112
|
+
# Mock layout
|
113
|
+
layout = Nanoc::Layout.new(
|
114
|
+
%(BEFORE <%= @item_rep.compiled_content(snapshot: :pre) %> AFTER),
|
115
|
+
{},
|
116
|
+
'/somelayout/')
|
117
|
+
|
118
|
+
# Create item and item rep
|
119
|
+
item = Nanoc::Item.new(
|
120
|
+
'blah blah', {}, '/',
|
121
|
+
binary: false
|
122
|
+
)
|
123
|
+
rep = create_rep_for(item, :foo)
|
124
|
+
rep.assigns = { item_rep: rep }
|
125
|
+
|
126
|
+
# Run and check
|
127
|
+
rep.layout(layout, :erb, {})
|
128
|
+
assert_equal('BEFORE blah blah AFTER', rep.instance_eval { @content[:last] })
|
129
|
+
end
|
130
|
+
|
80
131
|
def test_filter
|
81
132
|
# Mock site
|
82
133
|
site = MiniTest::Mock.new
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Nanoc::ItemRepRecorderProxyTest < Nanoc::TestCase
|
4
|
+
def test_double_names
|
5
|
+
proxy = Nanoc::ItemRepRecorderProxy.new(mock)
|
6
|
+
|
7
|
+
proxy.snapshot(:foo, stuff: :giraffe)
|
8
|
+
assert_raises(Nanoc::Errors::CannotCreateMultipleSnapshotsWithSameName) do
|
9
|
+
proxy.snapshot(:foo, stuff: :donkey)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_double_params
|
14
|
+
proxy = Nanoc::ItemRepRecorderProxy.new(mock)
|
15
|
+
|
16
|
+
proxy.snapshot(:foo)
|
17
|
+
proxy.snapshot(:bar)
|
18
|
+
end
|
19
|
+
end
|
data/test/base/test_rule.rb
CHANGED
@@ -12,4 +12,14 @@ class Nanoc::RuleTest < Nanoc::TestCase
|
|
12
12
|
def test_apply_to
|
13
13
|
# TODO: implement
|
14
14
|
end
|
15
|
+
|
16
|
+
def test_matches
|
17
|
+
regexp = %r</(.*)/(.*)/>
|
18
|
+
identifier = '/anything/else/'
|
19
|
+
expected = ['anything', 'else']
|
20
|
+
|
21
|
+
rule = Nanoc::Rule.new(regexp, :string, Proc.new {})
|
22
|
+
|
23
|
+
assert_equal expected, rule.send(:matches, identifier)
|
24
|
+
end
|
15
25
|
end
|