nanoc 4.11.0 → 4.11.1

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 (154) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +6 -0
  3. data/lib/nanoc.rb +4 -7
  4. data/lib/nanoc/base.rb +3 -3
  5. data/lib/nanoc/base/assertions.rb +1 -1
  6. data/lib/nanoc/base/entities.rb +2 -20
  7. data/lib/nanoc/base/entities/action_sequence.rb +60 -64
  8. data/lib/nanoc/base/entities/checksum_collection.rb +23 -21
  9. data/lib/nanoc/base/entities/dependency.rb +24 -22
  10. data/lib/nanoc/base/entities/outdatedness_reasons.rb +74 -72
  11. data/lib/nanoc/base/entities/outdatedness_status.rb +19 -17
  12. data/lib/nanoc/base/entities/props.rb +119 -117
  13. data/lib/nanoc/base/entities/site.rb +46 -50
  14. data/lib/nanoc/base/errors.rb +183 -198
  15. data/lib/nanoc/base/repos.rb +4 -2
  16. data/lib/nanoc/base/repos/action_sequence_store.rb +44 -42
  17. data/lib/nanoc/base/repos/aggregate_data_source.rb +24 -22
  18. data/lib/nanoc/base/repos/checksum_store.rb +51 -49
  19. data/lib/nanoc/base/repos/compiled_content_cache.rb +47 -45
  20. data/lib/nanoc/base/repos/compiled_content_store.rb +76 -0
  21. data/lib/nanoc/base/repos/config_loader.rb +74 -72
  22. data/lib/nanoc/base/repos/dependency_store.rb +174 -172
  23. data/lib/nanoc/base/repos/in_mem_data_source.rb +17 -15
  24. data/lib/nanoc/base/repos/item_rep_repo.rb +26 -24
  25. data/lib/nanoc/base/repos/outdatedness_store.rb +50 -48
  26. data/lib/nanoc/base/repos/prefixed_data_source.rb +21 -19
  27. data/lib/nanoc/base/repos/site_loader.rb +75 -73
  28. data/lib/nanoc/base/repos/store.rb +93 -91
  29. data/lib/nanoc/base/services.rb +7 -3
  30. data/lib/nanoc/base/services/action_provider.rb +23 -21
  31. data/lib/nanoc/base/services/action_sequence_builder.rb +42 -34
  32. data/lib/nanoc/base/services/compilation_context.rb +49 -47
  33. data/lib/nanoc/base/services/compiler.rb +177 -170
  34. data/lib/nanoc/base/services/compiler/phases.rb +8 -1
  35. data/lib/nanoc/base/services/compiler/phases/abstract.rb +44 -38
  36. data/lib/nanoc/base/services/compiler/phases/cache.rb +34 -28
  37. data/lib/nanoc/base/services/compiler/phases/mark_done.rb +17 -11
  38. data/lib/nanoc/base/services/compiler/phases/notify.rb +21 -0
  39. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +37 -31
  40. data/lib/nanoc/base/services/compiler/phases/resume.rb +47 -48
  41. data/lib/nanoc/base/services/compiler/phases/write.rb +65 -59
  42. data/lib/nanoc/base/services/compiler/stage.rb +27 -8
  43. data/lib/nanoc/base/services/compiler/stages.rb +7 -1
  44. data/lib/nanoc/base/services/compiler/stages/build_reps.rb +25 -19
  45. data/lib/nanoc/base/services/compiler/stages/calculate_checksums.rb +34 -28
  46. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +33 -27
  47. data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +79 -69
  48. data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +46 -40
  49. data/lib/nanoc/base/services/compiler/stages/forget_outdated_dependencies.rb +15 -9
  50. data/lib/nanoc/base/services/compiler/stages/load_stores.rb +28 -22
  51. data/lib/nanoc/base/services/compiler/stages/postprocess.rb +16 -10
  52. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +25 -19
  53. data/lib/nanoc/base/services/compiler/stages/prune.rb +23 -17
  54. data/lib/nanoc/base/services/compiler/stages/store_post_compilation_state.rb +15 -9
  55. data/lib/nanoc/base/services/compiler/stages/store_pre_compilation_state.rb +26 -20
  56. data/lib/nanoc/base/services/compiler_loader.rb +26 -24
  57. data/lib/nanoc/base/services/dependency_tracker.rb +47 -45
  58. data/lib/nanoc/base/services/executor.rb +16 -15
  59. data/lib/nanoc/base/services/filter.rb +37 -5
  60. data/lib/nanoc/base/services/instrumentor.rb +12 -10
  61. data/lib/nanoc/base/services/item_rep_builder.rb +21 -19
  62. data/lib/nanoc/base/services/item_rep_router.rb +72 -70
  63. data/lib/nanoc/base/services/item_rep_selector.rb +48 -46
  64. data/lib/nanoc/base/services/item_rep_writer.rb +58 -53
  65. data/lib/nanoc/base/services/outdatedness_checker.rb +181 -179
  66. data/lib/nanoc/base/services/outdatedness_rule.rb +23 -21
  67. data/lib/nanoc/base/services/outdatedness_rules.rb +5 -3
  68. data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +28 -24
  69. data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +20 -16
  70. data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +13 -9
  71. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +12 -8
  72. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +12 -8
  73. data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +10 -6
  74. data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +39 -35
  75. data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +19 -15
  76. data/lib/nanoc/base/services/pruner.rb +2 -2
  77. data/lib/nanoc/base/views.rb +7 -0
  78. data/lib/nanoc/base/views/basic_item_view.rb +1 -1
  79. data/lib/nanoc/base/views/compilation_item_rep_view.rb +2 -2
  80. data/lib/nanoc/base/views/identifiable_collection_view.rb +2 -2
  81. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +1 -1
  82. data/lib/nanoc/base/views/mixins/mutable_document_view_mixin.rb +5 -5
  83. data/lib/nanoc/base/views/mutable_item_collection_view.rb +3 -3
  84. data/lib/nanoc/base/views/mutable_layout_collection_view.rb +2 -2
  85. data/lib/nanoc/base/views/view_context_for_compilation.rb +6 -6
  86. data/lib/nanoc/base/views/view_context_for_pre_compilation.rb +2 -2
  87. data/lib/nanoc/base/views/view_context_for_shell.rb +2 -2
  88. data/lib/nanoc/checking/check.rb +1 -1
  89. data/lib/nanoc/cli/commands/compile_listeners/abstract.rb +24 -7
  90. data/lib/nanoc/cli/commands/compile_listeners/debug_printer.rb +79 -15
  91. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +4 -7
  92. data/lib/nanoc/cli/commands/compile_listeners/file_action_printer.rb +15 -24
  93. data/lib/nanoc/cli/commands/compile_listeners/timing_recorder.rb +22 -18
  94. data/lib/nanoc/cli/commands/create-site.rb +2 -7
  95. data/lib/nanoc/cli/commands/shell.rb +1 -1
  96. data/lib/nanoc/cli/commands/show-data.rb +9 -9
  97. data/lib/nanoc/cli/logger.rb +1 -1
  98. data/lib/nanoc/data_sources/filesystem.rb +8 -8
  99. data/lib/nanoc/filters/erb.rb +1 -1
  100. data/lib/nanoc/filters/erubi.rb +1 -1
  101. data/lib/nanoc/filters/erubis.rb +1 -1
  102. data/lib/nanoc/filters/haml.rb +1 -1
  103. data/lib/nanoc/filters/sass.rb +1 -1
  104. data/lib/nanoc/filters/slim.rb +1 -1
  105. data/lib/nanoc/helpers/breadcrumbs.rb +2 -2
  106. data/lib/nanoc/helpers/capturing.rb +9 -8
  107. data/lib/nanoc/helpers/filtering.rb +2 -2
  108. data/lib/nanoc/helpers/rendering.rb +1 -1
  109. data/lib/nanoc/rule_dsl.rb +10 -0
  110. data/lib/nanoc/rule_dsl/action_provider.rb +3 -3
  111. data/lib/nanoc/rule_dsl/action_recorder.rb +3 -3
  112. data/lib/nanoc/rule_dsl/action_sequence_calculator.rb +7 -7
  113. data/lib/nanoc/rule_dsl/compilation_rule.rb +2 -2
  114. data/lib/nanoc/rule_dsl/compilation_rule_context.rb +9 -9
  115. data/lib/nanoc/rule_dsl/compiler_dsl.rb +4 -4
  116. data/lib/nanoc/rule_dsl/routing_rule.rb +3 -3
  117. data/lib/nanoc/rule_dsl/rule.rb +5 -5
  118. data/lib/nanoc/rule_dsl/rule_context.rb +3 -3
  119. data/lib/nanoc/rule_dsl/rules_collection.rb +4 -4
  120. data/lib/nanoc/spec.rb +15 -15
  121. data/lib/nanoc/version.rb +1 -1
  122. metadata +10 -111
  123. data/lib/nanoc/base/contracts_support.rb +0 -130
  124. data/lib/nanoc/base/core_ext.rb +0 -5
  125. data/lib/nanoc/base/core_ext/array.rb +0 -50
  126. data/lib/nanoc/base/core_ext/hash.rb +0 -54
  127. data/lib/nanoc/base/core_ext/string.rb +0 -16
  128. data/lib/nanoc/base/entities/code_snippet.rb +0 -53
  129. data/lib/nanoc/base/entities/configuration-schema.json +0 -122
  130. data/lib/nanoc/base/entities/configuration.rb +0 -206
  131. data/lib/nanoc/base/entities/content.rb +0 -112
  132. data/lib/nanoc/base/entities/context.rb +0 -70
  133. data/lib/nanoc/base/entities/directed_graph.rb +0 -195
  134. data/lib/nanoc/base/entities/document.rb +0 -125
  135. data/lib/nanoc/base/entities/identifiable_collection.rb +0 -141
  136. data/lib/nanoc/base/entities/identifier.rb +0 -222
  137. data/lib/nanoc/base/entities/item.rb +0 -10
  138. data/lib/nanoc/base/entities/item_collection.rb +0 -14
  139. data/lib/nanoc/base/entities/item_rep.rb +0 -91
  140. data/lib/nanoc/base/entities/layout.rb +0 -10
  141. data/lib/nanoc/base/entities/layout_collection.rb +0 -14
  142. data/lib/nanoc/base/entities/lazy_value.rb +0 -43
  143. data/lib/nanoc/base/entities/pattern.rb +0 -85
  144. data/lib/nanoc/base/entities/processing_action.rb +0 -21
  145. data/lib/nanoc/base/entities/processing_actions.rb +0 -5
  146. data/lib/nanoc/base/entities/processing_actions/filter.rb +0 -36
  147. data/lib/nanoc/base/entities/processing_actions/layout.rb +0 -36
  148. data/lib/nanoc/base/entities/processing_actions/snapshot.rb +0 -46
  149. data/lib/nanoc/base/entities/snapshot_def.rb +0 -22
  150. data/lib/nanoc/base/repos/data_source.rb +0 -168
  151. data/lib/nanoc/base/repos/snapshot_repo.rb +0 -67
  152. data/lib/nanoc/base/services/checksummer.rb +0 -274
  153. data/lib/nanoc/base/services/notification_center.rb +0 -87
  154. data/lib/nanoc/base/services/temp_filename_factory.rb +0 -52
@@ -1,93 +1,95 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class ConfigLoader
6
- class NoConfigFileFoundError < ::Nanoc::Error
7
- def initialize
8
- super('No configuration file found')
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class ConfigLoader
7
+ class NoConfigFileFoundError < ::Nanoc::Error
8
+ def initialize
9
+ super('No configuration file found')
10
+ end
9
11
  end
10
- end
11
12
 
12
- class NoParentConfigFileFoundError < ::Nanoc::Error
13
- def initialize(filename)
14
- super("There is no parent configuration file at #{filename}")
13
+ class NoParentConfigFileFoundError < ::Nanoc::Error
14
+ def initialize(filename)
15
+ super("There is no parent configuration file at #{filename}")
16
+ end
15
17
  end
16
- end
17
18
 
18
- class CyclicalConfigFileError < ::Nanoc::Error
19
- def initialize(filename)
20
- super("The parent configuration file at #{filename} includes one of its descendants")
19
+ class CyclicalConfigFileError < ::Nanoc::Error
20
+ def initialize(filename)
21
+ super("The parent configuration file at #{filename} includes one of its descendants")
22
+ end
21
23
  end
22
- end
23
24
 
24
- # @return [Boolean]
25
- def self.cwd_is_nanoc_site?
26
- !config_filename_for_cwd.nil?
27
- end
25
+ # @return [Boolean]
26
+ def self.cwd_is_nanoc_site?
27
+ !config_filename_for_cwd.nil?
28
+ end
28
29
 
29
- # @return [String]
30
- def self.config_filename_for_cwd
31
- filenames =
32
- if Nanoc::Feature.enabled?(Nanoc::Feature::TOML)
33
- %w[nanoc.yaml config.yaml nanoc.toml]
34
- else
35
- %w[nanoc.yaml config.yaml]
36
- end
37
- candidate = filenames.find { |f| File.file?(f) }
38
- candidate && File.expand_path(candidate)
39
- end
30
+ # @return [String]
31
+ def self.config_filename_for_cwd
32
+ filenames =
33
+ if Nanoc::Feature.enabled?(Nanoc::Feature::TOML)
34
+ %w[nanoc.yaml config.yaml nanoc.toml]
35
+ else
36
+ %w[nanoc.yaml config.yaml]
37
+ end
38
+ candidate = filenames.find { |f| File.file?(f) }
39
+ candidate && File.expand_path(candidate)
40
+ end
40
41
 
41
- def new_from_cwd
42
- # Determine path
43
- filename = self.class.config_filename_for_cwd
44
- raise NoConfigFileFoundError if filename.nil?
42
+ def new_from_cwd
43
+ # Determine path
44
+ filename = self.class.config_filename_for_cwd
45
+ raise NoConfigFileFoundError if filename.nil?
45
46
 
46
- # Read
47
- config =
48
- apply_parent_config(
49
- Nanoc::Int::Configuration.new(
50
- hash: load_file(filename),
51
- dir: File.dirname(filename),
52
- ),
53
- [filename],
54
- ).with_defaults
47
+ # Read
48
+ config =
49
+ apply_parent_config(
50
+ Nanoc::Core::Configuration.new(
51
+ hash: load_file(filename),
52
+ dir: File.dirname(filename),
53
+ ),
54
+ [filename],
55
+ ).with_defaults
55
56
 
56
- # Load environment
57
- config.with_environment
58
- end
57
+ # Load environment
58
+ config.with_environment
59
+ end
59
60
 
60
- def load_file(filename)
61
- case File.extname(filename)
62
- when '.yaml'
63
- YAML.load_file(filename)
64
- when '.toml'
65
- Tomlrb.load_file(filename)
66
- else
67
- raise Nanoc::Int::Errors::InternalInconsistency, 'Unhandled config file extension'
61
+ def load_file(filename)
62
+ case File.extname(filename)
63
+ when '.yaml'
64
+ YAML.load_file(filename)
65
+ when '.toml'
66
+ Tomlrb.load_file(filename)
67
+ else
68
+ raise Nanoc::Int::Errors::InternalInconsistency, 'Unhandled config file extension'
69
+ end
68
70
  end
69
- end
70
71
 
71
- # @api private
72
- def apply_parent_config(config, processed_paths = [])
73
- parent_path = config[:parent_config_file]
74
- return config if parent_path.nil?
72
+ # @api private
73
+ def apply_parent_config(config, processed_paths = [])
74
+ parent_path = config[:parent_config_file]
75
+ return config if parent_path.nil?
75
76
 
76
- # Get absolute path
77
- parent_path = File.absolute_path(parent_path, File.dirname(processed_paths.last))
78
- unless File.file?(parent_path)
79
- raise NoParentConfigFileFoundError.new(parent_path)
80
- end
77
+ # Get absolute path
78
+ parent_path = File.absolute_path(parent_path, File.dirname(processed_paths.last))
79
+ unless File.file?(parent_path)
80
+ raise NoParentConfigFileFoundError.new(parent_path)
81
+ end
81
82
 
82
- # Check recursion
83
- if processed_paths.include?(parent_path)
84
- raise CyclicalConfigFileError.new(parent_path)
85
- end
83
+ # Check recursion
84
+ if processed_paths.include?(parent_path)
85
+ raise CyclicalConfigFileError.new(parent_path)
86
+ end
86
87
 
87
- # Load
88
- parent_config = Nanoc::Int::Configuration.new(hash: load_file(parent_path), dir: config.dir)
89
- full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path])
90
- full_parent_config.merge(config.without(:parent_config_file))
88
+ # Load
89
+ parent_config = Nanoc::Core::Configuration.new(hash: load_file(parent_path), dir: config.dir)
90
+ full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path])
91
+ full_parent_config.merge(config.without(:parent_config_file))
92
+ end
91
93
  end
92
94
  end
93
95
  end
@@ -1,202 +1,204 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class DependencyStore < ::Nanoc::Int::Store
6
- include Nanoc::Int::ContractsSupport
7
-
8
- attr_reader :items
9
- attr_reader :layouts
10
-
11
- contract Nanoc::Int::ItemCollection, Nanoc::Int::LayoutCollection, Nanoc::Int::Configuration => C::Any
12
- def initialize(items, layouts, config)
13
- super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'dependencies'), 5)
14
-
15
- @items = items
16
- @layouts = layouts
17
-
18
- @refs2objs = {}
19
- items.each { |o| add_vertex_for(o) }
20
- layouts.each { |o| add_vertex_for(o) }
21
- add_vertex_for(config)
22
- add_vertex_for(items)
23
- add_vertex_for(layouts)
24
-
25
- @new_objects = []
26
- @graph = Nanoc::Int::DirectedGraph.new([nil] + objs2refs(@items) + objs2refs(@layouts))
27
- end
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class DependencyStore < ::Nanoc::Int::Store
7
+ include Nanoc::Core::ContractsSupport
8
+
9
+ attr_reader :items
10
+ attr_reader :layouts
11
+
12
+ contract Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection, Nanoc::Core::Configuration => C::Any
13
+ def initialize(items, layouts, config)
14
+ super(Nanoc::Int::Store.tmp_path_for(config: config, store_name: 'dependencies'), 5)
15
+
16
+ @items = items
17
+ @layouts = layouts
18
+
19
+ @refs2objs = {}
20
+ items.each { |o| add_vertex_for(o) }
21
+ layouts.each { |o| add_vertex_for(o) }
22
+ add_vertex_for(config)
23
+ add_vertex_for(items)
24
+ add_vertex_for(layouts)
25
+
26
+ @new_objects = []
27
+ @graph = Nanoc::Core::DirectedGraph.new([nil] + objs2refs(@items) + objs2refs(@layouts))
28
+ end
28
29
 
29
- C_OBJ_SRC = Nanoc::Int::Item
30
- C_OBJ_DST = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::IdentifiableCollection]
31
-
32
- contract C_OBJ_SRC => C::ArrayOf[Nanoc::Int::Dependency]
33
- def dependencies_causing_outdatedness_of(object)
34
- objects_causing_outdatedness_of(object).map do |other_object|
35
- props = props_for(other_object, object)
36
-
37
- Nanoc::Int::Dependency.new(
38
- other_object,
39
- object,
40
- Nanoc::Int::Props.new(
41
- raw_content: props.fetch(:raw_content, false),
42
- attributes: props.fetch(:attributes, false),
43
- compiled_content: props.fetch(:compiled_content, false),
44
- path: props.fetch(:path, false),
45
- ),
46
- )
30
+ C_OBJ_SRC = Nanoc::Core::Item
31
+ C_OBJ_DST = C::Or[Nanoc::Core::Item, Nanoc::Core::Layout, Nanoc::Core::Configuration, Nanoc::Core::IdentifiableCollection]
32
+
33
+ contract C_OBJ_SRC => C::ArrayOf[Nanoc::Int::Dependency]
34
+ def dependencies_causing_outdatedness_of(object)
35
+ objects_causing_outdatedness_of(object).map do |other_object|
36
+ props = props_for(other_object, object)
37
+
38
+ Nanoc::Int::Dependency.new(
39
+ other_object,
40
+ object,
41
+ Nanoc::Int::Props.new(
42
+ raw_content: props.fetch(:raw_content, false),
43
+ attributes: props.fetch(:attributes, false),
44
+ compiled_content: props.fetch(:compiled_content, false),
45
+ path: props.fetch(:path, false),
46
+ ),
47
+ )
48
+ end
47
49
  end
48
- end
49
50
 
50
- def items=(items)
51
- @items = items
52
- items.each { |o| @refs2objs[obj2ref(o)] = o }
53
- add_vertex_for(items)
54
- end
51
+ def items=(items)
52
+ @items = items
53
+ items.each { |o| @refs2objs[obj2ref(o)] = o }
54
+ add_vertex_for(items)
55
+ end
55
56
 
56
- def layouts=(layouts)
57
- @layouts = layouts
58
- layouts.each { |o| @refs2objs[obj2ref(o)] = o }
59
- add_vertex_for(layouts)
60
- end
57
+ def layouts=(layouts)
58
+ @layouts = layouts
59
+ layouts.each { |o| @refs2objs[obj2ref(o)] = o }
60
+ add_vertex_for(layouts)
61
+ end
61
62
 
62
- def new_items
63
- @new_objects.select { |o| o.is_a?(Nanoc::Int::Item) }
64
- end
63
+ def new_items
64
+ @new_objects.select { |o| o.is_a?(Nanoc::Core::Item) }
65
+ end
65
66
 
66
- def new_layouts
67
- @new_objects.select { |o| o.is_a?(Nanoc::Int::Layout) }
68
- end
67
+ def new_layouts
68
+ @new_objects.select { |o| o.is_a?(Nanoc::Core::Layout) }
69
+ end
69
70
 
70
- # Returns the direct dependencies for the given object.
71
- #
72
- # The direct dependencies of the given object include the items and
73
- # layouts that, when outdated will cause the given object to be marked as
74
- # outdated. Indirect dependencies will not be returned (e.g. if A depends
75
- # on B which depends on C, then the direct dependencies of A do not
76
- # include C).
77
- #
78
- # The direct predecessors can include nil, which indicates an item that is
79
- # no longer present in the site.
80
- #
81
- # @param [Nanoc::Int::Item, Nanoc::Int::Layout] object The object for
82
- # which to fetch the direct predecessors
83
- #
84
- # @return [Array<Nanoc::Int::Item, Nanoc::Int::Layout, nil>] The direct
85
- # predecessors of
86
- # the given object
87
- def objects_causing_outdatedness_of(object)
88
- refs2objs(@graph.direct_predecessors_of(obj2ref(object)))
89
- end
71
+ # Returns the direct dependencies for the given object.
72
+ #
73
+ # The direct dependencies of the given object include the items and
74
+ # layouts that, when outdated will cause the given object to be marked as
75
+ # outdated. Indirect dependencies will not be returned (e.g. if A depends
76
+ # on B which depends on C, then the direct dependencies of A do not
77
+ # include C).
78
+ #
79
+ # The direct predecessors can include nil, which indicates an item that is
80
+ # no longer present in the site.
81
+ #
82
+ # @param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for
83
+ # which to fetch the direct predecessors
84
+ #
85
+ # @return [Array<Nanoc::Core::Item, Nanoc::Core::Layout, nil>] The direct
86
+ # predecessors of
87
+ # the given object
88
+ def objects_causing_outdatedness_of(object)
89
+ refs2objs(@graph.direct_predecessors_of(obj2ref(object)))
90
+ end
90
91
 
91
- C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool]
92
- C_ATTR = C::Or[C::IterOf[Symbol], C::Bool]
93
- C_KEYWORD_PROPS = 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]]
94
-
95
- contract C::Maybe[C_OBJ_SRC], C::Maybe[C_OBJ_DST], C_KEYWORD_PROPS => C::Any
96
- # Records a dependency from `src` to `dst` in the dependency graph. When
97
- # `dst` is oudated, `src` will also become outdated.
98
- #
99
- # @param [Nanoc::Int::Item, Nanoc::Int::Layout] src The source of the dependency,
100
- # i.e. the object that will become outdated if dst is outdated
101
- #
102
- # @param [Nanoc::Int::Item, Nanoc::Int::Layout] dst The destination of the
103
- # dependency, i.e. the object that will cause the source to become
104
- # outdated if the destination is outdated
105
- #
106
- # @return [void]
107
- def record_dependency(src, dst, raw_content: false, attributes: false, compiled_content: false, path: false)
108
- return if src == dst
109
-
110
- add_vertex_for(src)
111
- add_vertex_for(dst)
112
-
113
- src_ref = obj2ref(src)
114
- dst_ref = obj2ref(dst)
115
-
116
- existing_props = Nanoc::Int::Props.new(@graph.props_for(dst_ref, src_ref) || {})
117
- new_props = Nanoc::Int::Props.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
118
- props = existing_props.merge(new_props)
119
-
120
- @graph.add_edge(dst_ref, src_ref, props: props.to_h)
121
- end
92
+ C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool]
93
+ C_ATTR = C::Or[C::IterOf[Symbol], C::Bool]
94
+ C_KEYWORD_PROPS = 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]]
95
+
96
+ contract C::Maybe[C_OBJ_SRC], C::Maybe[C_OBJ_DST], C_KEYWORD_PROPS => C::Any
97
+ # Records a dependency from `src` to `dst` in the dependency graph. When
98
+ # `dst` is oudated, `src` will also become outdated.
99
+ #
100
+ # @param [Nanoc::Core::Item, Nanoc::Core::Layout] src The source of the dependency,
101
+ # i.e. the object that will become outdated if dst is outdated
102
+ #
103
+ # @param [Nanoc::Core::Item, Nanoc::Core::Layout] dst The destination of the
104
+ # dependency, i.e. the object that will cause the source to become
105
+ # outdated if the destination is outdated
106
+ #
107
+ # @return [void]
108
+ def record_dependency(src, dst, raw_content: false, attributes: false, compiled_content: false, path: false)
109
+ return if src == dst
110
+
111
+ add_vertex_for(src)
112
+ add_vertex_for(dst)
113
+
114
+ src_ref = obj2ref(src)
115
+ dst_ref = obj2ref(dst)
116
+
117
+ existing_props = Nanoc::Int::Props.new(@graph.props_for(dst_ref, src_ref) || {})
118
+ new_props = Nanoc::Int::Props.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
119
+ props = existing_props.merge(new_props)
120
+
121
+ @graph.add_edge(dst_ref, src_ref, props: props.to_h)
122
+ end
122
123
 
123
- def add_vertex_for(obj)
124
- @refs2objs[obj2ref(obj)] = obj
125
- end
124
+ def add_vertex_for(obj)
125
+ @refs2objs[obj2ref(obj)] = obj
126
+ end
126
127
 
127
- # Empties the list of dependencies for the given object. This is necessary
128
- # before recompiling the given object, because otherwise old dependencies
129
- # will stick around and new dependencies will appear twice. This function
130
- # removes all incoming edges for the given vertex.
131
- #
132
- # @param [Nanoc::Int::Item, Nanoc::Int::Layout] object The object for which to
133
- # forget all dependencies
134
- #
135
- # @return [void]
136
- def forget_dependencies_for(object)
137
- @graph.delete_edges_to(obj2ref(object))
138
- end
128
+ # Empties the list of dependencies for the given object. This is necessary
129
+ # before recompiling the given object, because otherwise old dependencies
130
+ # will stick around and new dependencies will appear twice. This function
131
+ # removes all incoming edges for the given vertex.
132
+ #
133
+ # @param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for which to
134
+ # forget all dependencies
135
+ #
136
+ # @return [void]
137
+ def forget_dependencies_for(object)
138
+ @graph.delete_edges_to(obj2ref(object))
139
+ end
139
140
 
140
- protected
141
+ protected
141
142
 
142
- def obj2ref(obj)
143
- obj&.reference
144
- end
143
+ def obj2ref(obj)
144
+ obj&.reference
145
+ end
145
146
 
146
- def ref2obj(reference)
147
- if reference
148
- @refs2objs[reference]
149
- else
150
- nil
147
+ def ref2obj(reference)
148
+ if reference
149
+ @refs2objs[reference]
150
+ else
151
+ nil
152
+ end
151
153
  end
152
- end
153
154
 
154
- def objs2refs(objs)
155
- objs.map { |o| obj2ref(o) }
156
- end
155
+ def objs2refs(objs)
156
+ objs.map { |o| obj2ref(o) }
157
+ end
157
158
 
158
- def refs2objs(refs)
159
- refs.map { |r| ref2obj(r) }
160
- end
159
+ def refs2objs(refs)
160
+ refs.map { |r| ref2obj(r) }
161
+ end
161
162
 
162
- def props_for(from, to)
163
- props = @graph.props_for(obj2ref(from), obj2ref(to)) || {}
163
+ def props_for(from, to)
164
+ props = @graph.props_for(obj2ref(from), obj2ref(to)) || {}
164
165
 
165
- if props.values.any? { |v| v }
166
- props
167
- else
168
- { raw_content: true, attributes: true, compiled_content: true, path: true }
166
+ if props.values.any? { |v| v }
167
+ props
168
+ else
169
+ { raw_content: true, attributes: true, compiled_content: true, path: true }
170
+ end
169
171
  end
170
- end
171
172
 
172
- def data
173
- {
174
- edges: @graph.edges,
175
- vertices: @graph.vertices,
176
- }
177
- end
173
+ def data
174
+ {
175
+ edges: @graph.edges,
176
+ vertices: @graph.vertices,
177
+ }
178
+ end
178
179
 
179
- def data=(new_data)
180
- objects = Set.new(@items.to_a + @layouts.to_a)
181
- refs = objs2refs(objects)
180
+ def data=(new_data)
181
+ objects = Set.new(@items.to_a + @layouts.to_a)
182
+ refs = objs2refs(objects)
182
183
 
183
- # Create new graph
184
- @graph = Nanoc::Int::DirectedGraph.new([nil] + refs)
184
+ # Create new graph
185
+ @graph = Nanoc::Core::DirectedGraph.new([nil] + refs)
185
186
 
186
- # Load vertices
187
- previous_refs = new_data[:vertices]
188
- previous_objects = Set.new(refs2objs(previous_refs))
187
+ # Load vertices
188
+ previous_refs = new_data[:vertices]
189
+ previous_objects = Set.new(refs2objs(previous_refs))
189
190
 
190
- # Load edges
191
- new_data[:edges].each do |edge|
192
- from_index, to_index, props = *edge
193
- from = from_index && previous_refs[from_index]
194
- to = to_index && previous_refs[to_index]
195
- @graph.add_edge(from, to, props: props)
196
- end
191
+ # Load edges
192
+ new_data[:edges].each do |edge|
193
+ from_index, to_index, props = *edge
194
+ from = from_index && previous_refs[from_index]
195
+ to = to_index && previous_refs[to_index]
196
+ @graph.add_edge(from, to, props: props)
197
+ end
197
198
 
198
- # Record dependency from all items on new items
199
- @new_objects = objects - previous_objects
199
+ # Record dependency from all items on new items
200
+ @new_objects = objects - previous_objects
201
+ end
200
202
  end
201
203
  end
202
204
  end