nanoc 4.11.1 → 4.11.2
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/NEWS.md +6 -0
- data/lib/nanoc/base/feature.rb +4 -0
- data/lib/nanoc/base/repos.rb +2 -0
- data/lib/nanoc/base/repos/binary_compiled_content_cache.rb +128 -0
- data/lib/nanoc/base/repos/compiled_content_cache.rb +29 -23
- data/lib/nanoc/base/repos/textual_compiled_content_cache.rb +82 -0
- data/lib/nanoc/base/services/compiler/phases/cache.rb +1 -2
- data/lib/nanoc/base/services/compiler_loader.rb +10 -1
- data/lib/nanoc/base/views/post_compile_item_rep_view.rb +1 -1
- data/lib/nanoc/filters/sass/importer.rb +34 -6
- data/lib/nanoc/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c038b8ba7dfde390ca7151a64421060d91173371c080b1de0e8cf2b44cea073f
|
4
|
+
data.tar.gz: aef94fe2c56a0c01506d933fe68497b9e930b8b3b81933f5140dc15b9307b024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9687e4103a49256b1065f92107f0659f204e5b65b975af71f0240f9eb2857086b096081282a3038a25e1595a7af5c18077b44fbe4c6ce0ed388eca142369eae
|
7
|
+
data.tar.gz: ed741694c5373b8d8770211695dd7e6a53e2fe393ed1dfd96a6464e2ffd030e754a6c4e7eeb0cc04e0fe26bc09e4395849071967c8d0e0539a91affe01302fa3
|
data/NEWS.md
CHANGED
data/lib/nanoc/base/feature.rb
CHANGED
@@ -98,3 +98,7 @@ Nanoc::Feature.define('live_cmd', version: '4.11')
|
|
98
98
|
# Tracking issue:
|
99
99
|
# https://github.com/nanoc/features/issues/40
|
100
100
|
Nanoc::Feature.define('toml', version: '4.11')
|
101
|
+
|
102
|
+
# Tracking issue:
|
103
|
+
# https://github.com/nanoc/features/issues/20
|
104
|
+
Nanoc::Feature.define('binary_compiled_content_cache', version: '4.11')
|
data/lib/nanoc/base/repos.rb
CHANGED
@@ -6,6 +6,8 @@ Nanoc::DataSource = Nanoc::Core::DataSource
|
|
6
6
|
require_relative 'repos/store'
|
7
7
|
|
8
8
|
require_relative 'repos/checksum_store'
|
9
|
+
require_relative 'repos/binary_compiled_content_cache'
|
10
|
+
require_relative 'repos/textual_compiled_content_cache'
|
9
11
|
require_relative 'repos/compiled_content_cache'
|
10
12
|
require_relative 'repos/config_loader'
|
11
13
|
require_relative 'repos/dependency_store'
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Int
|
5
|
+
# Represents a cache than can be used to store already compiled content,
|
6
|
+
# to prevent it from being needlessly recompiled.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class BinaryCompiledContentCache < ::Nanoc::Int::Store
|
10
|
+
include Nanoc::Core::ContractsSupport
|
11
|
+
|
12
|
+
contract C::KeywordArgs[config: Nanoc::Core::Configuration] => C::Any
|
13
|
+
def initialize(config:)
|
14
|
+
super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'binary_content'), 1)
|
15
|
+
|
16
|
+
@cache = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
contract Nanoc::Core::ItemRep => C::Maybe[C::HashOf[Symbol => Nanoc::Core::Content]]
|
20
|
+
# Returns the cached compiled content for the given item representation.
|
21
|
+
#
|
22
|
+
# This cached compiled content is a hash where the keys are the snapshot
|
23
|
+
# names, and the values the compiled content at the given snapshot.
|
24
|
+
def [](rep)
|
25
|
+
item_cache = @cache[rep.item.identifier] || {}
|
26
|
+
|
27
|
+
rep_cache = item_cache[rep.name]
|
28
|
+
return nil if rep_cache.nil?
|
29
|
+
|
30
|
+
rep_cache.transform_values do |filename|
|
31
|
+
Nanoc::Core::Content.create(filename, binary: true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
contract Nanoc::Core::ItemRep => C::Bool
|
36
|
+
def include?(rep)
|
37
|
+
item_cache = @cache[rep.item.identifier] || {}
|
38
|
+
item_cache.key?(rep.name)
|
39
|
+
end
|
40
|
+
|
41
|
+
contract Nanoc::Core::ItemRep, C::HashOf[Symbol => Nanoc::Core::BinaryContent] => C::HashOf[Symbol => Nanoc::Core::Content]
|
42
|
+
# Sets the compiled content for the given representation.
|
43
|
+
#
|
44
|
+
# This cached compiled content is a hash where the keys are the snapshot
|
45
|
+
# names, and the values the compiled content at the given snapshot.
|
46
|
+
def []=(rep, content)
|
47
|
+
@cache[rep.item.identifier] ||= {}
|
48
|
+
@cache[rep.item.identifier][rep.name] ||= {}
|
49
|
+
rep_cache = @cache[rep.item.identifier][rep.name]
|
50
|
+
|
51
|
+
content.each do |snapshot, binary_content|
|
52
|
+
filename = build_filename(rep, snapshot)
|
53
|
+
rep_cache[snapshot] = filename
|
54
|
+
|
55
|
+
# Avoid reassigning the same content if this binary cached content was
|
56
|
+
# already used, because it was available and the item wasn’t oudated.
|
57
|
+
next if binary_content.filename == filename
|
58
|
+
|
59
|
+
# Copy
|
60
|
+
#
|
61
|
+
# NOTE: hardlinking is not an option in this case, because hardlinking
|
62
|
+
# would make it possible for the content to be (inadvertently)
|
63
|
+
# changed outside of Nanoc.
|
64
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
65
|
+
FileUtils.cp(binary_content.filename, filename)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def prune(items:)
|
70
|
+
item_identifiers = Set.new(items.map(&:identifier))
|
71
|
+
|
72
|
+
@cache.each_key do |key|
|
73
|
+
# TODO: remove unused item reps
|
74
|
+
next if item_identifiers.include?(key)
|
75
|
+
|
76
|
+
@cache.delete(key)
|
77
|
+
path = dirname_for_item_identifier(key)
|
78
|
+
FileUtils.rm_rf(path)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def data
|
83
|
+
@cache
|
84
|
+
end
|
85
|
+
|
86
|
+
def data=(new_data)
|
87
|
+
@cache = {}
|
88
|
+
|
89
|
+
new_data.each_pair do |item_identifier, content_per_rep|
|
90
|
+
@cache[item_identifier] ||= content_per_rep
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def dirname
|
97
|
+
filename + '_data'
|
98
|
+
end
|
99
|
+
|
100
|
+
def string_to_path_component(string)
|
101
|
+
string.gsub(/[^a-zA-Z0-9]+/, '_') +
|
102
|
+
'-' +
|
103
|
+
Digest::SHA1.hexdigest(string)[0..9]
|
104
|
+
end
|
105
|
+
|
106
|
+
def dirname_for_item_identifier(item_identifier)
|
107
|
+
File.join(
|
108
|
+
dirname,
|
109
|
+
string_to_path_component(item_identifier.to_s),
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
def dirname_for_item_rep(rep)
|
114
|
+
File.join(
|
115
|
+
dirname_for_item_identifier(rep.item.identifier),
|
116
|
+
string_to_path_component(rep.name.to_s),
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
def build_filename(rep, snapshot_name)
|
121
|
+
File.join(
|
122
|
+
dirname_for_item_rep(rep),
|
123
|
+
string_to_path_component(snapshot_name.to_s),
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -11,9 +11,10 @@ module Nanoc
|
|
11
11
|
|
12
12
|
contract C::KeywordArgs[config: Nanoc::Core::Configuration] => C::Any
|
13
13
|
def initialize(config:)
|
14
|
-
|
14
|
+
@textual_cache = Nanoc::Int::TextualCompiledContentCache.new(config: config)
|
15
|
+
@binary_cache = Nanoc::Int::BinaryCompiledContentCache.new(config: config)
|
15
16
|
|
16
|
-
@
|
17
|
+
@wrapped_caches = [@textual_cache, @binary_cache]
|
17
18
|
end
|
18
19
|
|
19
20
|
contract Nanoc::Core::ItemRep => C::Maybe[C::HashOf[Symbol => Nanoc::Core::Content]]
|
@@ -22,40 +23,45 @@ module Nanoc
|
|
22
23
|
# This cached compiled content is a hash where the keys are the snapshot
|
23
24
|
# names. and the values the compiled content at the given snapshot.
|
24
25
|
def [](rep)
|
25
|
-
|
26
|
-
|
26
|
+
textual_content_map = @textual_cache[rep]
|
27
|
+
binary_content_map = @binary_cache[rep]
|
28
|
+
|
29
|
+
# If either the textual or the binary content cache is nil, assume the
|
30
|
+
# cache is entirely absent.
|
31
|
+
#
|
32
|
+
# This is necessary to support the case where only textual content is
|
33
|
+
# cached (which was the case in older versions of Nanoc).
|
34
|
+
return nil if [textual_content_map, binary_content_map].any?(&:nil?)
|
35
|
+
|
36
|
+
textual_content_map.merge(binary_content_map)
|
27
37
|
end
|
28
38
|
|
29
|
-
contract Nanoc::Core::ItemRep, C::HashOf[Symbol => Nanoc::Core::Content] => C::
|
39
|
+
contract Nanoc::Core::ItemRep, C::HashOf[Symbol => Nanoc::Core::Content] => C::Any
|
30
40
|
# Sets the compiled content for the given representation.
|
31
41
|
#
|
32
42
|
# This cached compiled content is a hash where the keys are the snapshot
|
33
|
-
# names
|
43
|
+
# names and the values the compiled content at the given snapshot.
|
34
44
|
def []=(rep, content)
|
35
|
-
@
|
36
|
-
@
|
45
|
+
@textual_cache[rep] = content.select { |_key, c| c.textual? }
|
46
|
+
@binary_cache[rep] = content.select { |_key, c| c.binary? }
|
37
47
|
end
|
38
48
|
|
39
|
-
def prune(
|
40
|
-
|
41
|
-
|
42
|
-
@cache.keys.each do |key|
|
43
|
-
@cache.delete(key) unless item_identifiers.include?(key)
|
44
|
-
end
|
49
|
+
def prune(*args)
|
50
|
+
@wrapped_caches.each { |w| w.prune(*args) }
|
45
51
|
end
|
46
52
|
|
47
|
-
|
48
|
-
|
49
|
-
def
|
50
|
-
@
|
53
|
+
# True if there is cached compiled content available for this item, and
|
54
|
+
# all entries are present (either textual or binary).
|
55
|
+
def full_cache_available?(rep)
|
56
|
+
@textual_cache.include?(rep) && @binary_cache.include?(rep)
|
51
57
|
end
|
52
58
|
|
53
|
-
def
|
54
|
-
@
|
59
|
+
def load(*args)
|
60
|
+
@wrapped_caches.each { |w| w.load(*args) }
|
61
|
+
end
|
55
62
|
|
56
|
-
|
57
|
-
|
58
|
-
end
|
63
|
+
def store(*args)
|
64
|
+
@wrapped_caches.each { |w| w.store(*args) }
|
59
65
|
end
|
60
66
|
end
|
61
67
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
module Int
|
5
|
+
# Represents a cache than can be used to store already compiled content,
|
6
|
+
# to prevent it from being needlessly recompiled.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class TextualCompiledContentCache < ::Nanoc::Int::Store
|
10
|
+
include Nanoc::Core::ContractsSupport
|
11
|
+
|
12
|
+
contract C::KeywordArgs[config: Nanoc::Core::Configuration] => C::Any
|
13
|
+
def initialize(config:)
|
14
|
+
super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'compiled_content'), 2)
|
15
|
+
|
16
|
+
@cache = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
contract Nanoc::Core::ItemRep => C::Maybe[C::HashOf[Symbol => Nanoc::Core::Content]]
|
20
|
+
# Returns the cached compiled content for the given item representation.
|
21
|
+
#
|
22
|
+
# This cached compiled content is a hash where the keys are the snapshot
|
23
|
+
# names, and the values the compiled content at the given snapshot.
|
24
|
+
def [](rep)
|
25
|
+
item_cache = @cache[rep.item.identifier] || {}
|
26
|
+
item_cache[rep.name]
|
27
|
+
end
|
28
|
+
|
29
|
+
contract Nanoc::Core::ItemRep => C::Bool
|
30
|
+
def include?(rep)
|
31
|
+
item_cache = @cache[rep.item.identifier] || {}
|
32
|
+
item_cache.key?(rep.name)
|
33
|
+
end
|
34
|
+
|
35
|
+
contract Nanoc::Core::ItemRep, C::HashOf[Symbol => Nanoc::Core::Content] => C::Any
|
36
|
+
# Sets the compiled content for the given representation.
|
37
|
+
#
|
38
|
+
# This cached compiled content is a hash where the keys are the snapshot
|
39
|
+
# names, and the values the compiled content at the given snapshot.
|
40
|
+
def []=(rep, content)
|
41
|
+
# FIXME: once the binary content cache is properly enabled (no longer
|
42
|
+
# behind a feature flag), change contract to be TextualContent, rather
|
43
|
+
# than Content.
|
44
|
+
|
45
|
+
@cache[rep.item.identifier] ||= {}
|
46
|
+
@cache[rep.item.identifier][rep.name] = content
|
47
|
+
end
|
48
|
+
|
49
|
+
def prune(items:)
|
50
|
+
item_identifiers = Set.new(items.map(&:identifier))
|
51
|
+
|
52
|
+
@cache.each_key do |key|
|
53
|
+
# TODO: remove unused item reps
|
54
|
+
next if item_identifiers.include?(key)
|
55
|
+
|
56
|
+
@cache.delete(key)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# True if there is cached compiled content available for this item, and
|
61
|
+
# all entries are textual.
|
62
|
+
def full_cache_available?(rep)
|
63
|
+
cache = self[rep]
|
64
|
+
cache ? cache.none? { |_snapshot_name, content| content.binary? } : false
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def data
|
70
|
+
@cache
|
71
|
+
end
|
72
|
+
|
73
|
+
def data=(new_data)
|
74
|
+
@cache = {}
|
75
|
+
|
76
|
+
new_data.each_pair do |item_identifier, content_per_rep|
|
77
|
+
@cache[item_identifier] ||= content_per_rep
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -21,7 +21,7 @@ module Nanoc
|
|
21
21
|
Nanoc::Int::OutdatednessStore.new(config: site.config)
|
22
22
|
|
23
23
|
compiled_content_cache =
|
24
|
-
|
24
|
+
compiled_content_cache_class.new(config: site.config)
|
25
25
|
|
26
26
|
params = {
|
27
27
|
compiled_content_cache: compiled_content_cache,
|
@@ -34,6 +34,15 @@ module Nanoc
|
|
34
34
|
|
35
35
|
Nanoc::Int::Compiler.new(site, params)
|
36
36
|
end
|
37
|
+
|
38
|
+
def compiled_content_cache_class
|
39
|
+
feature_name = Nanoc::Feature::BINARY_COMPILED_CONTENT_CACHE
|
40
|
+
if Nanoc::Feature.enabled?(feature_name)
|
41
|
+
Nanoc::Int::CompiledContentCache
|
42
|
+
else
|
43
|
+
Nanoc::Int::TextualCompiledContentCache
|
44
|
+
end
|
45
|
+
end
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
@@ -8,7 +8,7 @@ module Nanoc
|
|
8
8
|
|
9
9
|
def compiled_content(snapshot: nil)
|
10
10
|
compilation_context = @context.compilation_context
|
11
|
-
snapshot_contents = compilation_context.compiled_content_cache[_unwrap]
|
11
|
+
snapshot_contents = compilation_context.compiled_content_cache[_unwrap] || {}
|
12
12
|
|
13
13
|
snapshot_name = snapshot || (snapshot_contents[:pre] ? :pre : :last)
|
14
14
|
|
@@ -36,13 +36,9 @@ module Nanoc::Filters::SassCommon
|
|
36
36
|
items = filter.items.find_all(identifier)
|
37
37
|
return if items.empty?
|
38
38
|
|
39
|
-
content =
|
40
|
-
items.first.compiled_content
|
41
|
-
else
|
42
|
-
items.map { |item| %(@import "#{item.identifier}";) }.join("\n")
|
43
|
-
end
|
39
|
+
content, syntax = import(items)
|
44
40
|
|
45
|
-
options[:syntax] =
|
41
|
+
options[:syntax] = syntax
|
46
42
|
options[:filename] = identifier.to_s
|
47
43
|
options[:importer] = self
|
48
44
|
::Sass::Engine.new(content, options)
|
@@ -85,5 +81,37 @@ module Nanoc::Filters::SassCommon
|
|
85
81
|
map = self.class.raw_filename_to_item_map_for_config(filter.config, filter.items)
|
86
82
|
map[realpath]
|
87
83
|
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def import(items)
|
88
|
+
if items.size == 1
|
89
|
+
import_single(items.first)
|
90
|
+
else
|
91
|
+
import_all(items)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def import_single(item)
|
96
|
+
syntax = if (ext = item.identifier.ext).nil?
|
97
|
+
nil
|
98
|
+
else
|
99
|
+
ext.downcase.to_sym
|
100
|
+
end
|
101
|
+
|
102
|
+
[
|
103
|
+
item.compiled_content,
|
104
|
+
syntax,
|
105
|
+
]
|
106
|
+
end
|
107
|
+
|
108
|
+
def import_all(items)
|
109
|
+
import_all = items.map { |i| %(@import "#{i.identifier}";) }.join("\n")
|
110
|
+
|
111
|
+
[
|
112
|
+
import_all,
|
113
|
+
:scss,
|
114
|
+
]
|
115
|
+
end
|
88
116
|
end
|
89
117
|
end
|
data/lib/nanoc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.11.
|
4
|
+
version: 4.11.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-02-
|
11
|
+
date: 2019-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 4.11.
|
47
|
+
version: 4.11.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 4.11.
|
54
|
+
version: 4.11.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: parallel
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/nanoc/base/repos.rb
|
127
127
|
- lib/nanoc/base/repos/action_sequence_store.rb
|
128
128
|
- lib/nanoc/base/repos/aggregate_data_source.rb
|
129
|
+
- lib/nanoc/base/repos/binary_compiled_content_cache.rb
|
129
130
|
- lib/nanoc/base/repos/checksum_store.rb
|
130
131
|
- lib/nanoc/base/repos/compiled_content_cache.rb
|
131
132
|
- lib/nanoc/base/repos/compiled_content_store.rb
|
@@ -137,6 +138,7 @@ files:
|
|
137
138
|
- lib/nanoc/base/repos/prefixed_data_source.rb
|
138
139
|
- lib/nanoc/base/repos/site_loader.rb
|
139
140
|
- lib/nanoc/base/repos/store.rb
|
141
|
+
- lib/nanoc/base/repos/textual_compiled_content_cache.rb
|
140
142
|
- lib/nanoc/base/services.rb
|
141
143
|
- lib/nanoc/base/services/action_provider.rb
|
142
144
|
- lib/nanoc/base/services/action_sequence_builder.rb
|