nanoc 4.11.8 → 4.11.9

Sign up to get free protection for your applications and to get access to all the features.
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