nanoc 4.11.8 → 4.11.9
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 +8 -0
- data/lib/nanoc.rb +4 -1
- data/lib/nanoc/base.rb +0 -1
- data/lib/nanoc/base/errors.rb +4 -49
- data/lib/nanoc/base/repos.rb +0 -15
- data/lib/nanoc/base/repos/site_loader.rb +1 -1
- data/lib/nanoc/base/services.rb +0 -2
- data/lib/nanoc/base/services/compiler.rb +1 -1
- data/lib/nanoc/base/services/compiler/phases/recalculate.rb +1 -1
- data/lib/nanoc/base/services/compiler/stages/build_reps.rb +1 -1
- data/lib/nanoc/base/services/compiler/stages/cleanup.rb +1 -1
- data/lib/nanoc/base/services/compiler/stages/load_stores.rb +1 -1
- data/lib/nanoc/base/services/compiler_loader.rb +6 -6
- data/lib/nanoc/base/services/outdatedness_checker.rb +10 -10
- data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +4 -4
- data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +2 -2
- data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +2 -2
- data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +3 -3
- data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +3 -3
- data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +2 -2
- data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +3 -3
- data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +2 -2
- data/lib/nanoc/base/services/pruner.rb +1 -1
- data/lib/nanoc/base/views/view_context_for_compilation.rb +1 -1
- data/lib/nanoc/base/views/view_context_for_pre_compilation.rb +1 -1
- data/lib/nanoc/base/views/view_context_for_shell.rb +2 -2
- data/lib/nanoc/checking/check.rb +17 -1
- data/lib/nanoc/cli/commands/shell.rb +1 -1
- data/lib/nanoc/cli/error_handler.rb +1 -1
- data/lib/nanoc/filters/handlebars.rb +2 -2
- data/lib/nanoc/filters/sass/importer.rb +3 -2
- data/lib/nanoc/rule_dsl/action_provider.rb +1 -1
- data/lib/nanoc/spec.rb +4 -4
- data/lib/nanoc/version.rb +1 -1
- metadata +5 -21
- data/lib/nanoc/base/entities.rb +0 -7
- data/lib/nanoc/base/entities/outdatedness_reasons.rb +0 -88
- data/lib/nanoc/base/entities/outdatedness_status.rb +0 -27
- data/lib/nanoc/base/repos/action_sequence_store.rb +0 -50
- data/lib/nanoc/base/repos/binary_compiled_content_cache.rb +0 -128
- data/lib/nanoc/base/repos/checksum_store.rb +0 -74
- data/lib/nanoc/base/repos/compiled_content_cache.rb +0 -68
- data/lib/nanoc/base/repos/compiled_content_store.rb +0 -77
- data/lib/nanoc/base/repos/dependency_store.rb +0 -204
- data/lib/nanoc/base/repos/item_rep_repo.rb +0 -37
- data/lib/nanoc/base/repos/outdatedness_store.rb +0 -55
- data/lib/nanoc/base/repos/prefixed_data_source.rb +0 -31
- data/lib/nanoc/base/repos/store.rb +0 -114
- data/lib/nanoc/base/repos/textual_compiled_content_cache.rb +0 -82
- data/lib/nanoc/base/services/dependency_tracker.rb +0 -63
- data/lib/nanoc/base/services/outdatedness_rule.rb +0 -34
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
# Stores item reps (in memory).
|
6
|
-
#
|
7
|
-
# @api private
|
8
|
-
class ItemRepRepo
|
9
|
-
include Enumerable
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@reps = []
|
13
|
-
@reps_by_item = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def <<(rep)
|
17
|
-
@reps << rep
|
18
|
-
|
19
|
-
@reps_by_item[rep.item] ||= []
|
20
|
-
@reps_by_item[rep.item] << rep
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_a
|
24
|
-
@reps
|
25
|
-
end
|
26
|
-
|
27
|
-
def each(&block)
|
28
|
-
@reps.each(&block)
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def [](item)
|
33
|
-
@reps_by_item.fetch(item, [])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
# @api private
|
6
|
-
class OutdatednessStore < ::Nanoc::Int::Store
|
7
|
-
include Nanoc::Core::ContractsSupport
|
8
|
-
|
9
|
-
contract C::KeywordArgs[config: Nanoc::Core::Configuration] => C::Any
|
10
|
-
def initialize(config:)
|
11
|
-
super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'outdatedness'), 1)
|
12
|
-
|
13
|
-
@outdated_refs = Set.new
|
14
|
-
end
|
15
|
-
|
16
|
-
contract Nanoc::Core::ItemRep => C::Bool
|
17
|
-
def include?(obj)
|
18
|
-
@outdated_refs.include?(obj.reference)
|
19
|
-
end
|
20
|
-
|
21
|
-
contract Nanoc::Core::ItemRep => self
|
22
|
-
def add(obj)
|
23
|
-
@outdated_refs << obj.reference
|
24
|
-
self
|
25
|
-
end
|
26
|
-
|
27
|
-
contract Nanoc::Core::ItemRep => self
|
28
|
-
def remove(obj)
|
29
|
-
@outdated_refs.delete(obj.reference)
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
contract C::None => C::Bool
|
34
|
-
def empty?
|
35
|
-
@outdated_refs.empty?
|
36
|
-
end
|
37
|
-
|
38
|
-
contract C::None => self
|
39
|
-
def clear
|
40
|
-
@outdated_refs = Set.new
|
41
|
-
self
|
42
|
-
end
|
43
|
-
|
44
|
-
protected
|
45
|
-
|
46
|
-
def data
|
47
|
-
@outdated_refs
|
48
|
-
end
|
49
|
-
|
50
|
-
def data=(new_data)
|
51
|
-
@outdated_refs = Set.new(new_data)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
class PrefixedDataSource < Nanoc::DataSource
|
6
|
-
def initialize(data_source, items_prefix, layouts_prefix)
|
7
|
-
super({}, '/', '/', {})
|
8
|
-
|
9
|
-
@data_source = data_source
|
10
|
-
@items_prefix = items_prefix
|
11
|
-
@layouts_prefix = layouts_prefix
|
12
|
-
end
|
13
|
-
|
14
|
-
def items
|
15
|
-
@data_source.items.map { |d| d.with_identifier_prefix(@items_prefix) }
|
16
|
-
end
|
17
|
-
|
18
|
-
def layouts
|
19
|
-
@data_source.layouts.map { |d| d.with_identifier_prefix(@layouts_prefix) }
|
20
|
-
end
|
21
|
-
|
22
|
-
def item_changes
|
23
|
-
@data_source.item_changes
|
24
|
-
end
|
25
|
-
|
26
|
-
def layout_changes
|
27
|
-
@data_source.layout_changes
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
# An abstract superclass for classes that need to store data to the
|
6
|
-
# filesystem, such as checksums, cached compiled content and dependency
|
7
|
-
# graphs.
|
8
|
-
#
|
9
|
-
# Each store has a version number. When attempting to load data from a store
|
10
|
-
# that has an incompatible version number, no data will be loaded, but
|
11
|
-
# {#version_mismatch_detected} will be called.
|
12
|
-
#
|
13
|
-
# @abstract Subclasses must implement {#data} and {#data=}, and may
|
14
|
-
# implement {#no_data_found} and {#version_mismatch_detected}.
|
15
|
-
#
|
16
|
-
# @api private
|
17
|
-
class Store
|
18
|
-
include Nanoc::Core::ContractsSupport
|
19
|
-
|
20
|
-
# @return [String] The name of the file where data will be loaded from and
|
21
|
-
# stored to.
|
22
|
-
attr_reader :filename
|
23
|
-
|
24
|
-
# @return [Numeric] The version number corresponding to the file format
|
25
|
-
# the data is in. When the file format changes, the version number
|
26
|
-
# should be incremented.
|
27
|
-
attr_reader :version
|
28
|
-
|
29
|
-
# Creates a new store for the given filename.
|
30
|
-
#
|
31
|
-
# @param [String] filename The name of the file where data will be loaded
|
32
|
-
# from and stored to.
|
33
|
-
#
|
34
|
-
# @param [Numeric] version The version number corresponding to the file
|
35
|
-
# format the data is in. When the file format changes, the version
|
36
|
-
# number should be incremented.
|
37
|
-
def initialize(filename, version)
|
38
|
-
@filename = filename
|
39
|
-
@version = version
|
40
|
-
end
|
41
|
-
|
42
|
-
# Logic for building tmp path from active environment and store name
|
43
|
-
# @api private
|
44
|
-
contract C::KeywordArgs[config: Nanoc::Core::Configuration, store_name: String] => C::AbsolutePathString
|
45
|
-
def self.tmp_path_for(store_name:, config:)
|
46
|
-
File.absolute_path(
|
47
|
-
File.join(tmp_path_prefix(config.output_dir), store_name),
|
48
|
-
config.dir,
|
49
|
-
)
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.tmp_path_prefix(output_dir)
|
53
|
-
dir = Digest::SHA1.hexdigest(output_dir)[0..12]
|
54
|
-
File.join('tmp', 'nanoc', dir)
|
55
|
-
end
|
56
|
-
|
57
|
-
# @group Loading and storing data
|
58
|
-
|
59
|
-
# @return The data that should be written to the disk
|
60
|
-
#
|
61
|
-
# @abstract This method must be implemented by the subclass.
|
62
|
-
def data
|
63
|
-
raise NotImplementedError.new('Nanoc::Int::Store subclasses must implement #data and #data=')
|
64
|
-
end
|
65
|
-
|
66
|
-
# @param new_data The data that has been loaded from the disk
|
67
|
-
#
|
68
|
-
# @abstract This method must be implemented by the subclass.
|
69
|
-
#
|
70
|
-
# @return [void]
|
71
|
-
def data=(new_data) # rubocop:disable Lint/UnusedMethodArgument
|
72
|
-
raise NotImplementedError.new('Nanoc::Int::Store subclasses must implement #data and #data=')
|
73
|
-
end
|
74
|
-
|
75
|
-
# Loads the data from the filesystem into memory. This method will set the
|
76
|
-
# loaded data using the {#data=} method.
|
77
|
-
#
|
78
|
-
# @return [void]
|
79
|
-
def load
|
80
|
-
return unless File.file?(filename)
|
81
|
-
|
82
|
-
begin
|
83
|
-
pstore.transaction do
|
84
|
-
return if pstore[:version] != version
|
85
|
-
|
86
|
-
self.data = pstore[:data]
|
87
|
-
end
|
88
|
-
rescue
|
89
|
-
FileUtils.rm_f(filename)
|
90
|
-
load
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# Stores the data contained in memory to the filesystem. This method will
|
95
|
-
# use the {#data} method to fetch the data that should be written.
|
96
|
-
#
|
97
|
-
# @return [void]
|
98
|
-
def store
|
99
|
-
FileUtils.mkdir_p(File.dirname(filename))
|
100
|
-
|
101
|
-
pstore.transaction do
|
102
|
-
pstore[:data] = data
|
103
|
-
pstore[:version] = version
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
def pstore
|
110
|
-
@pstore ||= PStore.new(filename)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,82 +0,0 @@
|
|
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
|
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
# @api private
|
6
|
-
class DependencyTracker
|
7
|
-
include Nanoc::Core::ContractsSupport
|
8
|
-
|
9
|
-
C_OBJ = C::Or[Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration, Nanoc::Core::IdentifiableCollection]
|
10
|
-
C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool]
|
11
|
-
C_ATTR = C::Or[C::IterOf[Symbol], C::Bool]
|
12
|
-
C_ARGS = C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTR], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]]
|
13
|
-
|
14
|
-
class Null
|
15
|
-
include Nanoc::Core::ContractsSupport
|
16
|
-
|
17
|
-
contract C_OBJ, C_ARGS => C::Any
|
18
|
-
def enter(_obj, raw_content: false, attributes: false, compiled_content: false, path: false); end
|
19
|
-
|
20
|
-
contract C_OBJ => C::Any
|
21
|
-
def exit; end
|
22
|
-
|
23
|
-
contract C_OBJ, C_ARGS => C::Any
|
24
|
-
def bounce(_obj, raw_content: false, attributes: false, compiled_content: false, path: false); end
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_reader :dependency_store
|
28
|
-
|
29
|
-
def initialize(dependency_store)
|
30
|
-
@dependency_store = dependency_store
|
31
|
-
@stack = []
|
32
|
-
end
|
33
|
-
|
34
|
-
contract C_OBJ, C_ARGS => C::Any
|
35
|
-
def enter(obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
36
|
-
unless @stack.empty?
|
37
|
-
Nanoc::Core::NotificationCenter.post(:dependency_created, @stack.last, obj)
|
38
|
-
@dependency_store.record_dependency(
|
39
|
-
@stack.last,
|
40
|
-
obj,
|
41
|
-
raw_content: raw_content,
|
42
|
-
attributes: attributes,
|
43
|
-
compiled_content: compiled_content,
|
44
|
-
path: path,
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
|
-
@stack.push(obj)
|
49
|
-
end
|
50
|
-
|
51
|
-
contract C_OBJ => C::Any
|
52
|
-
def exit
|
53
|
-
@stack.pop
|
54
|
-
end
|
55
|
-
|
56
|
-
contract C_OBJ, C_ARGS => C::Any
|
57
|
-
def bounce(obj, raw_content: false, attributes: false, compiled_content: false, path: false)
|
58
|
-
enter(obj, raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
|
59
|
-
exit
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nanoc
|
4
|
-
module Int
|
5
|
-
# @api private
|
6
|
-
class OutdatednessRule
|
7
|
-
include Nanoc::Core::ContractsSupport
|
8
|
-
include Singleton
|
9
|
-
|
10
|
-
def call(obj, outdatedness_checker)
|
11
|
-
Nanoc::Core::Instrumentor.call(:outdatedness_rule_ran, self.class) do
|
12
|
-
apply(obj, outdatedness_checker)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def apply(_obj, _outdatedness_checker)
|
17
|
-
raise NotImplementedError.new('Nanoc::Int::OutdatednessRule subclasses must implement #apply')
|
18
|
-
end
|
19
|
-
|
20
|
-
contract C::None => String
|
21
|
-
def inspect
|
22
|
-
"#{self.class.name}(#{reason})"
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.affects_props(*names)
|
26
|
-
@affected_props = Set.new(names)
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.affected_props
|
30
|
-
@affected_props
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|