nanoc 4.0.0a1 → 4.0.0a2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -4
- data/NEWS.md +13 -0
- data/lib/nanoc/base.rb +2 -0
- data/lib/nanoc/base/compilation/compiler.rb +0 -1
- data/lib/nanoc/base/compilation/compiler_dsl.rb +21 -7
- data/lib/nanoc/base/compilation/item_rep_proxy.rb +10 -1
- data/lib/nanoc/base/compilation/rule.rb +10 -12
- data/lib/nanoc/base/compilation/rules_collection.rb +2 -2
- data/lib/nanoc/base/pattern.rb +63 -0
- data/lib/nanoc/base/source_data/data_source.rb +33 -18
- data/lib/nanoc/base/source_data/identifier.rb +65 -3
- data/lib/nanoc/base/source_data/item.rb +1 -1
- data/lib/nanoc/base/source_data/item_array.rb +17 -2
- data/lib/nanoc/base/source_data/layout.rb +1 -1
- data/lib/nanoc/base/source_data/site.rb +4 -3
- data/lib/nanoc/base/views/config.rb +22 -0
- data/lib/nanoc/base/views/item.rb +76 -0
- data/lib/nanoc/base/views/item_collection.rb +46 -4
- data/lib/nanoc/base/views/item_rep.rb +23 -0
- data/lib/nanoc/base/views/layout.rb +4 -0
- data/lib/nanoc/base/views/layout_collection.rb +7 -1
- data/lib/nanoc/base/views/mutable_config.rb +5 -0
- data/lib/nanoc/base/views/mutable_item.rb +15 -0
- data/lib/nanoc/base/views/mutable_item_collection.rb +25 -0
- data/lib/nanoc/base/views/mutable_layout.rb +5 -0
- data/lib/nanoc/base/views/mutable_layout_collection.rb +20 -2
- data/lib/nanoc/cli/cleaning_stream.rb +15 -0
- data/lib/nanoc/cli/commands/create-site.rb +17 -35
- data/lib/nanoc/cli/commands/shell.rb +7 -4
- data/lib/nanoc/data_sources.rb +0 -1
- data/lib/nanoc/data_sources/filesystem.rb +75 -76
- data/lib/nanoc/data_sources/filesystem_unified.rb +4 -27
- data/lib/nanoc/data_sources/filesystem_verbose.rb +4 -21
- data/lib/nanoc/version.rb +1 -1
- data/nanoc.gemspec +1 -1
- data/test/base/test_compiler.rb +35 -15
- data/test/base/test_compiler_dsl.rb +32 -30
- data/test/base/test_data_source.rb +2 -2
- data/test/base/test_item_array.rb +10 -1
- data/test/base/test_rule.rb +2 -2
- data/test/base/test_site.rb +32 -0
- data/test/cli/commands/test_create_site.rb +7 -1
- data/test/cli/commands/test_prune.rb +2 -2
- data/test/data_sources/test_filesystem.rb +29 -9
- data/test/data_sources/test_filesystem_unified.rb +48 -68
- data/test/helper.rb +1 -0
- data/test/helpers/test_breadcrumbs.rb +4 -4
- data/test/test_gem.rb +0 -1
- metadata +4 -5
- data/lib/nanoc/data_sources/static.rb +0 -62
- data/test/data_sources/test_static.rb +0 -93
@@ -70,7 +70,7 @@ module Nanoc::Int
|
|
70
70
|
|
71
71
|
# Get rest of params
|
72
72
|
@attributes = attributes.__nanoc_symbolize_keys_recursively
|
73
|
-
@identifier = Nanoc::Identifier.
|
73
|
+
@identifier = Nanoc::Identifier.from(identifier)
|
74
74
|
|
75
75
|
# Set mtime
|
76
76
|
@attributes.merge!(mtime: params[:mtime]) if params[:mtime]
|
@@ -21,7 +21,9 @@ module Nanoc::Int
|
|
21
21
|
DELEGATED_METHODS = (Array.instance_methods + Enumerable.instance_methods).map(&:to_sym) - EXCLUDED_METHODS
|
22
22
|
def_delegators :@items, *DELEGATED_METHODS
|
23
23
|
|
24
|
-
def initialize
|
24
|
+
def initialize(config)
|
25
|
+
@config = config
|
26
|
+
|
25
27
|
@items = []
|
26
28
|
end
|
27
29
|
|
@@ -33,7 +35,7 @@ module Nanoc::Int
|
|
33
35
|
|
34
36
|
def [](*args)
|
35
37
|
if 1 == args.size && args.first.is_a?(String)
|
36
|
-
item_with_identifier(args.first)
|
38
|
+
item_with_identifier(args.first) || item_matching_glob(args.first)
|
37
39
|
elsif 1 == args.size && args.first.is_a?(Regexp)
|
38
40
|
@items.select { |i| i.identifier.to_s =~ args.first }
|
39
41
|
else
|
@@ -60,6 +62,15 @@ module Nanoc::Int
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
65
|
+
def item_matching_glob(glob)
|
66
|
+
if use_globs?
|
67
|
+
pat = Nanoc::Int::Pattern.from(glob)
|
68
|
+
@items.find { |i| pat.match?(i.identifier) }
|
69
|
+
else
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
63
74
|
def build_mapping
|
64
75
|
@mapping = {}
|
65
76
|
@items.each do |item|
|
@@ -67,5 +78,9 @@ module Nanoc::Int
|
|
67
78
|
end
|
68
79
|
@mapping.freeze
|
69
80
|
end
|
81
|
+
|
82
|
+
def use_globs?
|
83
|
+
@config[:pattern_syntax] == 'glob'
|
84
|
+
end
|
70
85
|
end
|
71
86
|
end
|
@@ -29,7 +29,7 @@ module Nanoc::Int
|
|
29
29
|
def initialize(raw_content, attributes, identifier, params = {})
|
30
30
|
@raw_content = raw_content
|
31
31
|
@attributes = attributes.__nanoc_symbolize_keys_recursively
|
32
|
-
@identifier = Nanoc::Identifier.
|
32
|
+
@identifier = Nanoc::Identifier.from(identifier)
|
33
33
|
end
|
34
34
|
|
35
35
|
# Requests the attribute with the given key.
|
@@ -176,6 +176,7 @@ module Nanoc::Int
|
|
176
176
|
|
177
177
|
item_map = {}
|
178
178
|
@items.each do |item|
|
179
|
+
next if item.identifier !~ /\/\z/
|
179
180
|
item_map[item.identifier.to_s] = item
|
180
181
|
end
|
181
182
|
|
@@ -324,11 +325,11 @@ module Nanoc::Int
|
|
324
325
|
@items_loaded = true
|
325
326
|
|
326
327
|
# Get items
|
327
|
-
@items = Nanoc::Int::ItemArray.new
|
328
|
+
@items = Nanoc::Int::ItemArray.new(@config)
|
328
329
|
data_sources.each do |ds|
|
329
330
|
items_in_ds = ds.items
|
330
331
|
items_in_ds.each do |i|
|
331
|
-
i.identifier =
|
332
|
+
i.identifier = i.identifier.prefix(ds.items_root)
|
332
333
|
i.site = self
|
333
334
|
end
|
334
335
|
@items.concat(items_in_ds)
|
@@ -346,7 +347,7 @@ module Nanoc::Int
|
|
346
347
|
data_sources.each do |ds|
|
347
348
|
layouts_in_ds = ds.layouts
|
348
349
|
layouts_in_ds.each do |l|
|
349
|
-
l.identifier =
|
350
|
+
l.identifier = l.identifier.prefix(ds.layouts_root)
|
350
351
|
end
|
351
352
|
@layouts.concat(layouts_in_ds)
|
352
353
|
end
|
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Nanoc
|
4
4
|
class ConfigView
|
5
|
+
# @api private
|
6
|
+
NONE = Object.new
|
7
|
+
|
5
8
|
# @api private
|
6
9
|
def initialize(config)
|
7
10
|
@config = config
|
@@ -12,6 +15,25 @@ module Nanoc
|
|
12
15
|
@config
|
13
16
|
end
|
14
17
|
|
18
|
+
# @see Hash#fetch
|
19
|
+
def fetch(key, fallback=NONE, &block)
|
20
|
+
@config.fetch(key) do
|
21
|
+
if !fallback.equal?(NONE)
|
22
|
+
fallback
|
23
|
+
elsif block_given?
|
24
|
+
yield(key)
|
25
|
+
else
|
26
|
+
raise KeyError, "key not found: #{key.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see Hash#key?
|
32
|
+
def key?(key)
|
33
|
+
@config.key?(key)
|
34
|
+
end
|
35
|
+
|
36
|
+
# @see Hash#[]
|
15
37
|
def [](key)
|
16
38
|
@config[key]
|
17
39
|
end
|
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
module Nanoc
|
4
4
|
class ItemView
|
5
|
+
# @api private
|
6
|
+
NONE = Object.new
|
7
|
+
|
5
8
|
# @api private
|
6
9
|
def initialize(item)
|
7
10
|
@item = item
|
@@ -12,39 +15,112 @@ module Nanoc
|
|
12
15
|
@item
|
13
16
|
end
|
14
17
|
|
18
|
+
# @see Object#==
|
15
19
|
def ==(other)
|
16
20
|
identifier == other.identifier
|
17
21
|
end
|
18
22
|
alias_method :eql?, :==
|
19
23
|
|
24
|
+
# @see Object#hash
|
20
25
|
def hash
|
21
26
|
self.class.hash ^ identifier.hash
|
22
27
|
end
|
23
28
|
|
29
|
+
# @return [Nanoc::Identifier]
|
24
30
|
def identifier
|
25
31
|
@item.identifier
|
26
32
|
end
|
27
33
|
|
34
|
+
# @see Hash#fetch
|
35
|
+
def fetch(key, fallback=NONE, &block)
|
36
|
+
res = @item[key] # necessary for dependency tracking
|
37
|
+
|
38
|
+
if @item.attributes.key?(key)
|
39
|
+
res
|
40
|
+
else
|
41
|
+
if !fallback.equal?(NONE)
|
42
|
+
fallback
|
43
|
+
elsif block_given?
|
44
|
+
yield(key)
|
45
|
+
else
|
46
|
+
raise KeyError, "key not found: #{key.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# @see Hash#key?
|
52
|
+
def key?(key)
|
53
|
+
_res = @item[key] # necessary for dependency tracking
|
54
|
+
@item.attributes.key?(key)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @see Hash#[]
|
28
58
|
def [](key)
|
29
59
|
@item[key]
|
30
60
|
end
|
31
61
|
|
62
|
+
# Returns the compiled content.
|
63
|
+
#
|
64
|
+
# @option params [String] :rep (:default) The name of the representation
|
65
|
+
# from which the compiled content should be fetched. By default, the
|
66
|
+
# compiled content will be fetched from the default representation.
|
67
|
+
#
|
68
|
+
# @option params [String] :snapshot The name of the snapshot from which to
|
69
|
+
# fetch the compiled content. By default, the returned compiled content
|
70
|
+
# will be the content compiled right before the first layout call (if
|
71
|
+
# any).
|
72
|
+
#
|
73
|
+
# @return [String] The content of the given rep at the given snapshot.
|
32
74
|
def compiled_content(params = {})
|
33
75
|
@item.compiled_content(params)
|
34
76
|
end
|
35
77
|
|
78
|
+
# Returns the item path, as used when being linked to. It starts
|
79
|
+
# with a slash and it is relative to the output directory. It does not
|
80
|
+
# include the path to the output directory. It will not include the
|
81
|
+
# filename if the filename is an index filename.
|
82
|
+
#
|
83
|
+
# @option params [String] :rep (:default) The name of the representation
|
84
|
+
# from which the path should be fetched. By default, the path will be
|
85
|
+
# fetched from the default representation.
|
86
|
+
#
|
87
|
+
# @option params [Symbol] :snapshot (:last) The snapshot for which the
|
88
|
+
# path should be returned.
|
89
|
+
#
|
90
|
+
# @return [String] The item’s path.
|
36
91
|
def path(params = {})
|
37
92
|
@item.path(params)
|
38
93
|
end
|
39
94
|
|
95
|
+
# Returns the children of this item. For items with identifiers that have
|
96
|
+
# extensions, returns an empty collection.
|
97
|
+
#
|
98
|
+
# @return [Enumerable<Nanoc::ItemView>]
|
40
99
|
def children
|
41
100
|
@item.children.map { |i| Nanoc::ItemView.new(i) }
|
42
101
|
end
|
43
102
|
|
103
|
+
# Returns the parent of this item, if one exists. For items with identifiers
|
104
|
+
# that have extensions, returns nil.
|
105
|
+
#
|
106
|
+
# @return [Nanoc::ItemView] if the item has a parent
|
107
|
+
#
|
108
|
+
# @return [nil] if the item has no parent
|
109
|
+
def parent
|
110
|
+
Nanoc::ItemView.new(@item.parent)
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [Boolean] True if the item is binary, false otherwise
|
44
114
|
def binary?
|
45
115
|
@item.binary?
|
46
116
|
end
|
47
117
|
|
118
|
+
# For textual items, returns the raw (source) content of this item; for
|
119
|
+
# binary items, returns `nil`.
|
120
|
+
#
|
121
|
+
# @return [String] if the item is textual
|
122
|
+
#
|
123
|
+
# @return [nil] if the item is binary
|
48
124
|
def raw_content
|
49
125
|
@item.raw_content
|
50
126
|
end
|
@@ -19,20 +19,62 @@ module Nanoc
|
|
19
19
|
Nanoc::ItemView
|
20
20
|
end
|
21
21
|
|
22
|
+
# Calls the given block once for each item, passing that item as a parameter.
|
23
|
+
#
|
24
|
+
# @yieldparam [Nanoc::ItemView] item
|
25
|
+
#
|
26
|
+
# @yieldreturn [void]
|
27
|
+
#
|
28
|
+
# @return [self]
|
22
29
|
def each
|
23
30
|
@items.each { |i| yield view_class.new(i) }
|
31
|
+
self
|
24
32
|
end
|
25
33
|
|
34
|
+
# @return [Integer]
|
35
|
+
def size
|
36
|
+
@items.size
|
37
|
+
end
|
38
|
+
|
39
|
+
# @overload at(string)
|
40
|
+
#
|
41
|
+
# Finds the item whose identifier matches the given string.
|
42
|
+
#
|
43
|
+
# @param [String] string
|
44
|
+
#
|
45
|
+
# @return [nil] if no item matches the string
|
46
|
+
#
|
47
|
+
# @return [Nanoc::ItemView] if an item was found
|
26
48
|
def at(arg)
|
27
49
|
item = @items.at(arg)
|
28
50
|
item && view_class.new(item)
|
29
51
|
end
|
30
52
|
|
31
|
-
|
32
|
-
|
53
|
+
# @overload [](string)
|
54
|
+
#
|
55
|
+
# Finds the item whose identifier matches the given string.
|
56
|
+
#
|
57
|
+
# If the glob syntax is enabled, the string can be a glob, in which case
|
58
|
+
# this method finds the first item that matches the given glob.
|
59
|
+
#
|
60
|
+
# @param [String] string
|
61
|
+
#
|
62
|
+
# @return [nil] if no item matches the string
|
63
|
+
#
|
64
|
+
# @return [Nanoc::ItemView] if an item was found
|
65
|
+
#
|
66
|
+
# @overload [](regex)
|
67
|
+
#
|
68
|
+
# Finds the item whose identifier matches the given regular expression.
|
69
|
+
#
|
70
|
+
# @param [Regex] regex
|
71
|
+
#
|
72
|
+
# @return [nil] if no item matches the regex
|
73
|
+
#
|
74
|
+
# @return [Nanoc::ItemView] if an item was found
|
75
|
+
def [](arg)
|
76
|
+
res = @items[arg]
|
33
77
|
case res
|
34
|
-
when Array
|
35
|
-
res.map { |r| view_class.new(r) }
|
36
78
|
when nil
|
37
79
|
nil
|
38
80
|
else
|
@@ -12,27 +12,50 @@ module Nanoc
|
|
12
12
|
@item_rep
|
13
13
|
end
|
14
14
|
|
15
|
+
# @see Object#==
|
15
16
|
def ==(other)
|
16
17
|
item.identifier == other.item.identifier && name == other.name
|
17
18
|
end
|
18
19
|
alias_method :eql?, :==
|
19
20
|
|
21
|
+
# @see Object#hash
|
20
22
|
def hash
|
21
23
|
self.class.hash ^ item.identifier.hash ^ name.hash
|
22
24
|
end
|
23
25
|
|
26
|
+
# @return [Symbol]
|
24
27
|
def name
|
25
28
|
@item_rep.name
|
26
29
|
end
|
27
30
|
|
31
|
+
# Returns the compiled content.
|
32
|
+
#
|
33
|
+
# @option params [String] :snapshot The name of the snapshot from which to
|
34
|
+
# fetch the compiled content. By default, the returned compiled content
|
35
|
+
# will be the content compiled right before the first layout call (if
|
36
|
+
# any).
|
37
|
+
#
|
38
|
+
# @return [String] The content at the given snapshot.
|
28
39
|
def compiled_content(params = {})
|
29
40
|
@item_rep.compiled_content(params)
|
30
41
|
end
|
31
42
|
|
43
|
+
# Returns the item rep’s path, as used when being linked to. It starts
|
44
|
+
# with a slash and it is relative to the output directory. It does not
|
45
|
+
# include the path to the output directory. It will not include the
|
46
|
+
# filename if the filename is an index filename.
|
47
|
+
#
|
48
|
+
# @option params [Symbol] :snapshot (:last) The snapshot for which the
|
49
|
+
# path should be returned.
|
50
|
+
#
|
51
|
+
# @return [String] The item rep’s path.
|
32
52
|
def path(params = {})
|
33
53
|
@item_rep.path(params)
|
34
54
|
end
|
35
55
|
|
56
|
+
# Returns the item that this item rep belongs to.
|
57
|
+
#
|
58
|
+
# @return [Nanoc::ItemView]
|
36
59
|
def item
|
37
60
|
Nanoc::ItemView.new(@item_rep.item)
|
38
61
|
end
|
@@ -12,19 +12,23 @@ module Nanoc
|
|
12
12
|
@layout
|
13
13
|
end
|
14
14
|
|
15
|
+
# @see Object#==
|
15
16
|
def ==(other)
|
16
17
|
identifier == other.identifier
|
17
18
|
end
|
18
19
|
alias_method :eql?, :==
|
19
20
|
|
21
|
+
# @see Object#hash
|
20
22
|
def hash
|
21
23
|
self.class.hash ^ identifier.hash
|
22
24
|
end
|
23
25
|
|
26
|
+
# @return [Nanoc::Identifier]
|
24
27
|
def identifier
|
25
28
|
@layout.identifier
|
26
29
|
end
|
27
30
|
|
31
|
+
# @see Hash#[]
|
28
32
|
def [](key)
|
29
33
|
@layout[key]
|
30
34
|
end
|
@@ -11,7 +11,7 @@ module Nanoc
|
|
11
11
|
|
12
12
|
# @api private
|
13
13
|
def unwrap
|
14
|
-
@
|
14
|
+
@layouts
|
15
15
|
end
|
16
16
|
|
17
17
|
# @api private
|
@@ -19,8 +19,14 @@ module Nanoc
|
|
19
19
|
Nanoc::LayoutView
|
20
20
|
end
|
21
21
|
|
22
|
+
# Calls the given block once for each layout, passing that layout as a parameter.
|
23
|
+
#
|
24
|
+
# @yieldparam [Nanoc::LayoutView] layout
|
25
|
+
#
|
26
|
+
# @yieldreturn [void]
|
22
27
|
def each
|
23
28
|
@layouts.each { |l| yield view_class.new(l) }
|
29
|
+
self
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
@@ -2,8 +2,23 @@
|
|
2
2
|
|
3
3
|
module Nanoc
|
4
4
|
class MutableItemView < Nanoc::ItemView
|
5
|
+
# Sets the value for the given attribute.
|
6
|
+
#
|
7
|
+
# @param [Symbol] key
|
8
|
+
#
|
9
|
+
# @see Hash#[]=
|
5
10
|
def []=(key, value)
|
6
11
|
unwrap[key] = value
|
7
12
|
end
|
13
|
+
|
14
|
+
# Updates the attributes based on the given hash.
|
15
|
+
#
|
16
|
+
# @param [Hash] hash
|
17
|
+
#
|
18
|
+
# @return [self]
|
19
|
+
def update_attributes(hash)
|
20
|
+
hash.each { |k, v| unwrap[k] = v }
|
21
|
+
self
|
22
|
+
end
|
8
23
|
end
|
9
24
|
end
|