nanoc-core 4.13.4 → 4.14.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.
- checksums.yaml +4 -4
- data/lib/nanoc/core/basic_outdatedness_checker.rb +26 -27
- data/lib/nanoc/core/binary_compiled_content_cache.rb +11 -5
- data/lib/nanoc/core/compilation_phases/resume.rb +2 -2
- data/lib/nanoc/core/config_loader.rb +7 -2
- data/lib/nanoc/core/contracts_support.rb +2 -2
- data/lib/nanoc/core/dependency_props.rb +7 -7
- data/lib/nanoc/core/dependency_store.rb +4 -4
- data/lib/nanoc/core/dependency_tracker.rb +4 -4
- data/lib/nanoc/core/feature.rb +1 -1
- data/lib/nanoc/core/instrumentor.rb +2 -2
- data/lib/nanoc/core/item_rep_writer.rb +7 -5
- data/lib/nanoc/core/notification_center.rb +2 -2
- data/lib/nanoc/core/outdatedness_checker.rb +1 -1
- data/lib/nanoc/core/structured_data_loader.rb +36 -0
- data/lib/nanoc/core/toml_loader.rb +18 -0
- data/lib/nanoc/core/version.rb +1 -1
- data/lib/nanoc/core/view.rb +1 -1
- data/lib/nanoc/core/yaml_loader.rb +2 -2
- data/lib/nanoc/core.rb +7 -1
- metadata +6 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 789cc6b4702b215a8124a7fd9e223bbd5ae0ab388100d2825cc0aab1a2871706
|
|
4
|
+
data.tar.gz: 41badc8b04d48a56d08b12394a16677973326c82ff94b61e987c332e27ddcfb5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f65db903bb45e40731a74aff7ed48a9189ed8327e77bc10323a72084e180845fedb2af85b8c4e9f93b1a9b1beb8a9c3b84af562ef89108de994153af7846f79
|
|
7
|
+
data.tar.gz: 68ba69732bf619f3b30a73b4029d08cfe38e2e4451da63517aca1fc6040cf8d2451438c023844b5dc626c3c6da3ab4009bcd8c35bffc2b72599f6fad866a5a6f
|
|
@@ -77,29 +77,27 @@ module Nanoc
|
|
|
77
77
|
@action_sequences = action_sequences
|
|
78
78
|
|
|
79
79
|
# Memoize
|
|
80
|
-
@
|
|
80
|
+
@_apply_rules = {}
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
contract C_OBJ_MAYBE_REP => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
|
84
84
|
def outdatedness_status_for(obj)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
|
|
102
|
-
end
|
|
85
|
+
case obj
|
|
86
|
+
when Nanoc::Core::ItemRep
|
|
87
|
+
apply_rules(RULES_FOR_ITEM_REP, obj)
|
|
88
|
+
when Nanoc::Core::Item
|
|
89
|
+
apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
|
|
90
|
+
when Nanoc::Core::Layout
|
|
91
|
+
apply_rules(RULES_FOR_LAYOUT, obj)
|
|
92
|
+
when Nanoc::Core::Configuration
|
|
93
|
+
apply_rules(RULES_FOR_CONFIG, obj)
|
|
94
|
+
when Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection
|
|
95
|
+
# Collections are never outdated. Objects inside them might be,
|
|
96
|
+
# however.
|
|
97
|
+
apply_rules([], obj)
|
|
98
|
+
else
|
|
99
|
+
raise Nanoc::Core::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
|
|
100
|
+
end
|
|
103
101
|
end
|
|
104
102
|
|
|
105
103
|
def action_sequence_for(rep)
|
|
@@ -110,18 +108,19 @@ module Nanoc
|
|
|
110
108
|
|
|
111
109
|
contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, Nanoc::Core::OutdatednessStatus => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
|
112
110
|
def apply_rules(rules, obj, status = Nanoc::Core::OutdatednessStatus.new)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
@_apply_rules[obj] ||=
|
|
112
|
+
rules.inject(status) do |acc, rule|
|
|
113
|
+
if acc.useful_to_apply?(rule)
|
|
114
|
+
reason = rule.instance.call(obj, self)
|
|
115
|
+
if reason
|
|
116
|
+
acc.update(reason)
|
|
117
|
+
else
|
|
118
|
+
acc
|
|
119
|
+
end
|
|
118
120
|
else
|
|
119
121
|
acc
|
|
120
122
|
end
|
|
121
|
-
else
|
|
122
|
-
acc
|
|
123
123
|
end
|
|
124
|
-
end
|
|
125
124
|
end
|
|
126
125
|
|
|
127
126
|
contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[Nanoc::Core::OutdatednessStatus]
|
|
@@ -92,6 +92,10 @@ module Nanoc
|
|
|
92
92
|
end
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def use_clonefile?
|
|
96
|
+
defined?(Clonefile)
|
|
97
|
+
end
|
|
98
|
+
|
|
95
99
|
private
|
|
96
100
|
|
|
97
101
|
def dirname
|
|
@@ -132,11 +136,13 @@ module Nanoc
|
|
|
132
136
|
# changed outside of Nanoc.
|
|
133
137
|
|
|
134
138
|
# Try clonefile
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
139
|
+
if use_clonefile?
|
|
140
|
+
FileUtils.rm_f(to)
|
|
141
|
+
begin
|
|
142
|
+
res = Clonefile.always(from, to)
|
|
143
|
+
return if res
|
|
144
|
+
rescue Clonefile::UnsupportedPlatform, Errno::ENOTSUP, Errno::EXDEV, Errno::EINVAL
|
|
145
|
+
end
|
|
140
146
|
end
|
|
141
147
|
|
|
142
148
|
# Fall back to old-school copy
|
|
@@ -10,8 +10,8 @@ module Nanoc
|
|
|
10
10
|
DONE = Object.new
|
|
11
11
|
|
|
12
12
|
contract Nanoc::Core::ItemRep, C::KeywordArgs[is_outdated: C::Bool], C::Func[C::None => C::Any] => C::Any
|
|
13
|
-
def run(rep, is_outdated:, &
|
|
14
|
-
fiber = fiber_for(rep, is_outdated:, &
|
|
13
|
+
def run(rep, is_outdated:, &)
|
|
14
|
+
fiber = fiber_for(rep, is_outdated:, &)
|
|
15
15
|
while fiber.alive?
|
|
16
16
|
res = fiber.resume
|
|
17
17
|
|
|
@@ -29,7 +29,11 @@ module Nanoc
|
|
|
29
29
|
|
|
30
30
|
# @return [String]
|
|
31
31
|
def self.config_filename_for_cwd
|
|
32
|
-
filenames =
|
|
32
|
+
filenames = [
|
|
33
|
+
'nanoc.yaml',
|
|
34
|
+
'nanoc.toml',
|
|
35
|
+
'config.yaml',
|
|
36
|
+
]
|
|
33
37
|
candidate = filenames.find { |f| File.file?(f) }
|
|
34
38
|
candidate && File.expand_path(candidate)
|
|
35
39
|
end
|
|
@@ -54,7 +58,8 @@ module Nanoc
|
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
def load_file(filename)
|
|
57
|
-
|
|
61
|
+
loader = StructuredDataLoader.for_extension(File.extname(filename))
|
|
62
|
+
loader.load_file(filename)
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
# @api private
|
|
@@ -14,24 +14,24 @@ module Nanoc
|
|
|
14
14
|
C::Or[
|
|
15
15
|
C::SetOf[C::Or[String, Regexp]],
|
|
16
16
|
C::ArrayOf[C::Or[String, Regexp]],
|
|
17
|
-
C::Bool
|
|
17
|
+
C::Bool,
|
|
18
18
|
]
|
|
19
19
|
|
|
20
20
|
C_ATTR =
|
|
21
21
|
C::Or[
|
|
22
22
|
C::SetOf[
|
|
23
23
|
C::Or[
|
|
24
|
-
Symbol,
|
|
25
|
-
[Symbol, C::Any] # pair (specific value)
|
|
24
|
+
Symbol, # any value
|
|
25
|
+
[Symbol, C::Any], # pair (specific value)
|
|
26
26
|
],
|
|
27
27
|
],
|
|
28
28
|
C::ArrayOf[
|
|
29
29
|
C::Or[
|
|
30
|
-
Symbol,
|
|
31
|
-
[Symbol, C::Any] # pair (specific value)
|
|
30
|
+
Symbol, # any value
|
|
31
|
+
[Symbol, C::Any], # pair (specific value)
|
|
32
32
|
],
|
|
33
33
|
],
|
|
34
|
-
C::Bool
|
|
34
|
+
C::Bool,
|
|
35
35
|
]
|
|
36
36
|
|
|
37
37
|
C_ARGS =
|
|
@@ -39,7 +39,7 @@ module Nanoc
|
|
|
39
39
|
raw_content: C::Optional[C_RAW_CONTENT],
|
|
40
40
|
attributes: C::Optional[C_ATTR],
|
|
41
41
|
compiled_content: C::Optional[C::Bool],
|
|
42
|
-
path: C::Optional[C::Bool]
|
|
42
|
+
path: C::Optional[C::Bool],
|
|
43
43
|
]
|
|
44
44
|
|
|
45
45
|
contract C_ARGS => C::Any
|
|
@@ -9,14 +9,14 @@ module Nanoc
|
|
|
9
9
|
C_RAW_CONTENT =
|
|
10
10
|
C::Or[
|
|
11
11
|
C::ArrayOf[C::Or[String, Regexp]],
|
|
12
|
-
C::Bool
|
|
12
|
+
C::Bool,
|
|
13
13
|
]
|
|
14
14
|
|
|
15
15
|
C_ATTR =
|
|
16
16
|
C::Or[
|
|
17
17
|
C::ArrayOf[Symbol],
|
|
18
18
|
C::HashOf[Symbol => C::Any],
|
|
19
|
-
C::Bool
|
|
19
|
+
C::Bool,
|
|
20
20
|
]
|
|
21
21
|
|
|
22
22
|
C_KEYWORD_PROPS =
|
|
@@ -24,7 +24,7 @@ module Nanoc
|
|
|
24
24
|
raw_content: C::Optional[C_RAW_CONTENT],
|
|
25
25
|
attributes: C::Optional[C_ATTR],
|
|
26
26
|
compiled_content: C::Optional[C::Bool],
|
|
27
|
-
path: C::Optional[C::Bool]
|
|
27
|
+
path: C::Optional[C::Bool],
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
C_OBJ_SRC = Nanoc::Core::Item
|
|
@@ -34,7 +34,7 @@ module Nanoc
|
|
|
34
34
|
Nanoc::Core::Item,
|
|
35
35
|
Nanoc::Core::Layout,
|
|
36
36
|
Nanoc::Core::Configuration,
|
|
37
|
-
Nanoc::Core::IdentifiableCollection
|
|
37
|
+
Nanoc::Core::IdentifiableCollection,
|
|
38
38
|
]
|
|
39
39
|
|
|
40
40
|
attr_reader :items
|
|
@@ -11,20 +11,20 @@ module Nanoc
|
|
|
11
11
|
Nanoc::Core::Item,
|
|
12
12
|
Nanoc::Core::Layout,
|
|
13
13
|
Nanoc::Core::Configuration,
|
|
14
|
-
Nanoc::Core::IdentifiableCollection
|
|
14
|
+
Nanoc::Core::IdentifiableCollection,
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
C_RAW_CONTENT =
|
|
18
18
|
C::Or[
|
|
19
19
|
C::ArrayOf[C::Or[String, Regexp]],
|
|
20
|
-
C::Bool
|
|
20
|
+
C::Bool,
|
|
21
21
|
]
|
|
22
22
|
|
|
23
23
|
C_ATTR =
|
|
24
24
|
C::Or[
|
|
25
25
|
C::ArrayOf[Symbol],
|
|
26
26
|
C::HashOf[Symbol => C::Any],
|
|
27
|
-
C::Bool
|
|
27
|
+
C::Bool,
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
C_ARGS =
|
|
@@ -32,7 +32,7 @@ module Nanoc
|
|
|
32
32
|
raw_content: C::Optional[C_RAW_CONTENT],
|
|
33
33
|
attributes: C::Optional[C_ATTR],
|
|
34
34
|
compiled_content: C::Optional[C::Bool],
|
|
35
|
-
path: C::Optional[C::Bool]
|
|
35
|
+
path: C::Optional[C::Bool],
|
|
36
36
|
]
|
|
37
37
|
|
|
38
38
|
attr_reader :dependency_store
|
data/lib/nanoc/core/feature.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Nanoc
|
|
|
23
23
|
@enabled = false
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def self.call(key, *
|
|
26
|
+
def self.call(key, *)
|
|
27
27
|
return yield unless @enabled
|
|
28
28
|
|
|
29
29
|
begin
|
|
@@ -32,7 +32,7 @@ module Nanoc
|
|
|
32
32
|
yield
|
|
33
33
|
ensure
|
|
34
34
|
stopwatch.stop
|
|
35
|
-
Nanoc::Core::NotificationCenter.post(key, stopwatch.duration, *
|
|
35
|
+
Nanoc::Core::NotificationCenter.post(key, stopwatch.duration, *)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
end
|
|
@@ -79,11 +79,13 @@ module Nanoc
|
|
|
79
79
|
|
|
80
80
|
def smart_cp(from, to)
|
|
81
81
|
# Try clonefile
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
if defined?(Clonefile)
|
|
83
|
+
FileUtils.rm_f(to)
|
|
84
|
+
begin
|
|
85
|
+
res = Clonefile.always(from, to)
|
|
86
|
+
return if res
|
|
87
|
+
rescue Clonefile::UnsupportedPlatform, Errno::ENOTSUP, Errno::EXDEV, Errno::EINVAL
|
|
88
|
+
end
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
# Try with hardlink
|
|
@@ -28,7 +28,7 @@ module Nanoc
|
|
|
28
28
|
dependency_store: Nanoc::Core::DependencyStore,
|
|
29
29
|
action_sequence_store: Nanoc::Core::ActionSequenceStore,
|
|
30
30
|
action_sequences: C_ACTION_SEQUENCES,
|
|
31
|
-
reps: Nanoc::Core::ItemRepRepo
|
|
31
|
+
reps: Nanoc::Core::ItemRepRepo,
|
|
32
32
|
] => C::Any
|
|
33
33
|
def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
|
|
34
34
|
@site = site
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
module Core
|
|
5
|
+
# @api private
|
|
6
|
+
module StructuredDataLoader
|
|
7
|
+
class UnknownLanguageError < StandardError
|
|
8
|
+
def initialize(lang)
|
|
9
|
+
super("cannot find loader for language: #{lang.inspect}")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.for_language(language)
|
|
14
|
+
case language
|
|
15
|
+
when :yaml
|
|
16
|
+
YamlLoader
|
|
17
|
+
when :toml
|
|
18
|
+
TomlLoader
|
|
19
|
+
else
|
|
20
|
+
raise UnknownLanguageError.enw(language)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.for_extension(ext)
|
|
25
|
+
case ext
|
|
26
|
+
when '.yaml'
|
|
27
|
+
YamlLoader
|
|
28
|
+
when '.toml'
|
|
29
|
+
TomlLoader
|
|
30
|
+
else
|
|
31
|
+
raise UnknownLanguageError.enw(language)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Nanoc
|
|
4
|
+
module Core
|
|
5
|
+
# @api private
|
|
6
|
+
module TomlLoader
|
|
7
|
+
def self.load(string)
|
|
8
|
+
require 'perfect_toml'
|
|
9
|
+
PerfectTOML.parse(string)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.load_file(filename)
|
|
13
|
+
require 'perfect_toml'
|
|
14
|
+
load(File.read(filename))
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/nanoc/core/version.rb
CHANGED
data/lib/nanoc/core/view.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Nanoc
|
|
|
10
10
|
contract C::Maybe[C::Or[
|
|
11
11
|
Nanoc::Core::ViewContextForCompilation,
|
|
12
12
|
Nanoc::Core::ViewContextForPreCompilation,
|
|
13
|
-
Nanoc::Core::ViewContextForShell
|
|
13
|
+
Nanoc::Core::ViewContextForShell,
|
|
14
14
|
]] => C::Any
|
|
15
15
|
def initialize(context)
|
|
16
16
|
@context = context
|
data/lib/nanoc/core.rb
CHANGED
|
@@ -10,7 +10,6 @@ require 'yaml'
|
|
|
10
10
|
require 'zlib'
|
|
11
11
|
|
|
12
12
|
# External gems
|
|
13
|
-
require 'clonefile'
|
|
14
13
|
require 'concurrent-ruby'
|
|
15
14
|
require 'json_schema'
|
|
16
15
|
require 'ddmetrics'
|
|
@@ -21,6 +20,13 @@ require 'slow_enumerator_tools'
|
|
|
21
20
|
require 'tty-platform'
|
|
22
21
|
require 'zeitwerk'
|
|
23
22
|
|
|
23
|
+
# External gems (optional)
|
|
24
|
+
begin
|
|
25
|
+
require 'clonefile'
|
|
26
|
+
rescue LoadError
|
|
27
|
+
# ignore
|
|
28
|
+
end
|
|
29
|
+
|
|
24
30
|
module Nanoc
|
|
25
31
|
module Core
|
|
26
32
|
# Similar to `nil` except that it can only be compared against using
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nanoc-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Defreyne
|
|
@@ -23,20 +23,6 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '0.2'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: clonefile
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.5.3
|
|
33
|
-
type: :runtime
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.5.3
|
|
40
26
|
- !ruby/object:Gem::Dependency
|
|
41
27
|
name: concurrent-ruby
|
|
42
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -300,9 +286,11 @@ files:
|
|
|
300
286
|
- lib/nanoc/core/snapshot_def.rb
|
|
301
287
|
- lib/nanoc/core/store.rb
|
|
302
288
|
- lib/nanoc/core/string_pattern.rb
|
|
289
|
+
- lib/nanoc/core/structured_data_loader.rb
|
|
303
290
|
- lib/nanoc/core/temp_filename_factory.rb
|
|
304
291
|
- lib/nanoc/core/textual_compiled_content_cache.rb
|
|
305
292
|
- lib/nanoc/core/textual_content.rb
|
|
293
|
+
- lib/nanoc/core/toml_loader.rb
|
|
306
294
|
- lib/nanoc/core/trivial_error.rb
|
|
307
295
|
- lib/nanoc/core/utils.rb
|
|
308
296
|
- lib/nanoc/core/version.rb
|
|
@@ -316,7 +304,7 @@ licenses:
|
|
|
316
304
|
- MIT
|
|
317
305
|
metadata:
|
|
318
306
|
rubygems_mfa_required: 'true'
|
|
319
|
-
source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-core-v4.
|
|
307
|
+
source_code_uri: https://github.com/nanoc/nanoc/tree/nanoc-core-v4.14.0/nanoc-core
|
|
320
308
|
rdoc_options: []
|
|
321
309
|
require_paths:
|
|
322
310
|
- lib
|
|
@@ -324,14 +312,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
324
312
|
requirements:
|
|
325
313
|
- - ">="
|
|
326
314
|
- !ruby/object:Gem::Version
|
|
327
|
-
version: '3.
|
|
315
|
+
version: '3.2'
|
|
328
316
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
329
317
|
requirements:
|
|
330
318
|
- - ">="
|
|
331
319
|
- !ruby/object:Gem::Version
|
|
332
320
|
version: '0'
|
|
333
321
|
requirements: []
|
|
334
|
-
rubygems_version: 3.
|
|
322
|
+
rubygems_version: 3.7.2
|
|
335
323
|
specification_version: 4
|
|
336
324
|
summary: Core of Nanoc
|
|
337
325
|
test_files: []
|