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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +8 -0
  3. data/lib/nanoc.rb +4 -1
  4. data/lib/nanoc/base.rb +0 -1
  5. data/lib/nanoc/base/errors.rb +4 -49
  6. data/lib/nanoc/base/repos.rb +0 -15
  7. data/lib/nanoc/base/repos/site_loader.rb +1 -1
  8. data/lib/nanoc/base/services.rb +0 -2
  9. data/lib/nanoc/base/services/compiler.rb +1 -1
  10. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +1 -1
  11. data/lib/nanoc/base/services/compiler/stages/build_reps.rb +1 -1
  12. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +1 -1
  13. data/lib/nanoc/base/services/compiler/stages/load_stores.rb +1 -1
  14. data/lib/nanoc/base/services/compiler_loader.rb +6 -6
  15. data/lib/nanoc/base/services/outdatedness_checker.rb +10 -10
  16. data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +4 -4
  17. data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +2 -2
  18. data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +2 -2
  19. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +3 -3
  20. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +3 -3
  21. data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +2 -2
  22. data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +3 -3
  23. data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +2 -2
  24. data/lib/nanoc/base/services/pruner.rb +1 -1
  25. data/lib/nanoc/base/views/view_context_for_compilation.rb +1 -1
  26. data/lib/nanoc/base/views/view_context_for_pre_compilation.rb +1 -1
  27. data/lib/nanoc/base/views/view_context_for_shell.rb +2 -2
  28. data/lib/nanoc/checking/check.rb +17 -1
  29. data/lib/nanoc/cli/commands/shell.rb +1 -1
  30. data/lib/nanoc/cli/error_handler.rb +1 -1
  31. data/lib/nanoc/filters/handlebars.rb +2 -2
  32. data/lib/nanoc/filters/sass/importer.rb +3 -2
  33. data/lib/nanoc/rule_dsl/action_provider.rb +1 -1
  34. data/lib/nanoc/spec.rb +4 -4
  35. data/lib/nanoc/version.rb +1 -1
  36. metadata +5 -21
  37. data/lib/nanoc/base/entities.rb +0 -7
  38. data/lib/nanoc/base/entities/outdatedness_reasons.rb +0 -88
  39. data/lib/nanoc/base/entities/outdatedness_status.rb +0 -27
  40. data/lib/nanoc/base/repos/action_sequence_store.rb +0 -50
  41. data/lib/nanoc/base/repos/binary_compiled_content_cache.rb +0 -128
  42. data/lib/nanoc/base/repos/checksum_store.rb +0 -74
  43. data/lib/nanoc/base/repos/compiled_content_cache.rb +0 -68
  44. data/lib/nanoc/base/repos/compiled_content_store.rb +0 -77
  45. data/lib/nanoc/base/repos/dependency_store.rb +0 -204
  46. data/lib/nanoc/base/repos/item_rep_repo.rb +0 -37
  47. data/lib/nanoc/base/repos/outdatedness_store.rb +0 -55
  48. data/lib/nanoc/base/repos/prefixed_data_source.rb +0 -31
  49. data/lib/nanoc/base/repos/store.rb +0 -114
  50. data/lib/nanoc/base/repos/textual_compiled_content_cache.rb +0 -82
  51. data/lib/nanoc/base/services/dependency_tracker.rb +0 -63
  52. 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