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,77 +1,82 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class ItemRepWriter
6
- include Nanoc::Int::ContractsSupport
7
- include Nanoc::Assertions::Mixin
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class ItemRepWriter
7
+ include Nanoc::Core::ContractsSupport
8
+ include Nanoc::Assertions::Mixin
8
9
 
9
- TMP_TEXT_ITEMS_DIR = 'text_items'
10
+ TMP_TEXT_ITEMS_DIR = 'text_items'
10
11
 
11
- def write_all(item_rep, snapshot_repo)
12
- written_paths = Set.new
12
+ def write_all(item_rep, compiled_content_store)
13
+ written_paths = Set.new
13
14
 
14
- item_rep.snapshot_defs.map(&:name).each do |snapshot_name|
15
- write(item_rep, snapshot_repo, snapshot_name, written_paths)
15
+ item_rep.snapshot_defs.map(&:name).each do |snapshot_name|
16
+ write(item_rep, compiled_content_store, snapshot_name, written_paths)
17
+ end
16
18
  end
17
- end
18
19
 
19
- def write(item_rep, snapshot_repo, snapshot_name, written_paths)
20
- item_rep.raw_paths.fetch(snapshot_name, []).each do |raw_path|
21
- write_single(item_rep, snapshot_repo, snapshot_name, raw_path, written_paths)
20
+ def write(item_rep, compiled_content_store, snapshot_name, written_paths)
21
+ item_rep.raw_paths.fetch(snapshot_name, []).each do |raw_path|
22
+ write_single(item_rep, compiled_content_store, snapshot_name, raw_path, written_paths)
23
+ end
22
24
  end
23
- end
24
25
 
25
- def write_single(item_rep, snapshot_repo, snapshot_name, raw_path, written_paths)
26
- assert Nanoc::Assertions::PathIsAbsolute.new(path: raw_path)
26
+ def write_single(item_rep, compiled_content_store, snapshot_name, raw_path, written_paths)
27
+ assert Nanoc::Assertions::PathIsAbsolute.new(path: raw_path)
27
28
 
28
- # Don’t write twice
29
- # TODO: test written_paths behavior
30
- return if written_paths.include?(raw_path)
29
+ # Don’t write twice
30
+ # TODO: test written_paths behavior
31
+ return if written_paths.include?(raw_path)
31
32
 
32
- written_paths << raw_path
33
+ written_paths << raw_path
33
34
 
34
- # Create parent directory
35
- FileUtils.mkdir_p(File.dirname(raw_path))
35
+ # Create parent directory
36
+ FileUtils.mkdir_p(File.dirname(raw_path))
36
37
 
37
- # Check if file will be created
38
- is_created = !File.file?(raw_path)
38
+ # Check if file will be created
39
+ is_created = !File.file?(raw_path)
39
40
 
40
- # Notify
41
- Nanoc::Int::NotificationCenter.post(
42
- :rep_write_started, item_rep, raw_path
43
- )
41
+ # Notify
42
+ Nanoc::Core::NotificationCenter.post(
43
+ :rep_write_started, item_rep, raw_path
44
+ )
44
45
 
45
- content = snapshot_repo.get(item_rep, snapshot_name)
46
- if content.binary?
47
- temp_path = content.filename
48
- else
49
- temp_path = temp_filename
50
- File.write(temp_path, content.string)
51
- end
46
+ # Sync (needed so that diff generator can read the old contents)
47
+ Nanoc::Core::NotificationCenter.sync
52
48
 
53
- # Check whether content was modified
54
- is_modified = is_created || !FileUtils.identical?(raw_path, temp_path)
49
+ content = compiled_content_store.get(item_rep, snapshot_name)
50
+ if content.binary?
51
+ temp_path = content.filename
52
+ else
53
+ temp_path = temp_filename
54
+ File.write(temp_path, content.string)
55
+ end
55
56
 
56
- # Write
57
- if is_modified
58
- begin
59
- FileUtils.ln(temp_path, raw_path, force: true)
60
- rescue Errno::EXDEV
61
- FileUtils.cp(temp_path, raw_path)
57
+ # Check whether content was modified
58
+ is_modified = is_created || !FileUtils.identical?(raw_path, temp_path)
59
+
60
+ # Write
61
+ if is_modified
62
+ begin
63
+ FileUtils.ln(temp_path, raw_path, force: true)
64
+ rescue Errno::EXDEV, Errno::EACCES
65
+ FileUtils.cp(temp_path, raw_path)
66
+ end
62
67
  end
63
- end
64
68
 
65
- item_rep.modified = is_modified
69
+ item_rep.modified = is_modified
66
70
 
67
- # Notify
68
- Nanoc::Int::NotificationCenter.post(
69
- :rep_write_ended, item_rep, content.binary?, raw_path, is_created, is_modified
70
- )
71
- end
71
+ # Notify
72
+ Nanoc::Core::NotificationCenter.post(
73
+ :rep_write_ended, item_rep, content.binary?, raw_path, is_created, is_modified
74
+ )
75
+ end
72
76
 
73
- def temp_filename
74
- Nanoc::Int::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR)
77
+ def temp_filename
78
+ Nanoc::Core::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR)
79
+ end
75
80
  end
76
81
  end
77
82
  end
@@ -1,216 +1,218 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # Responsible for determining whether an item or a layout is outdated.
5
- #
6
- # @api private
7
- class OutdatednessChecker
8
- class Basic
9
- DDMemoize.activate(self)
10
-
11
- include Nanoc::Int::ContractsSupport
12
-
13
- Rules = Nanoc::Int::OutdatednessRules
14
-
15
- RULES_FOR_ITEM_REP =
16
- [
17
- Rules::RulesModified,
18
- Rules::ContentModified,
19
- Rules::AttributesModified,
20
- Rules::NotWritten,
21
- Rules::CodeSnippetsModified,
22
- Rules::UsesAlwaysOutdatedFilter,
23
- ].freeze
24
-
25
- RULES_FOR_LAYOUT =
26
- [
27
- Rules::RulesModified,
28
- Rules::ContentModified,
29
- Rules::AttributesModified,
30
- Rules::UsesAlwaysOutdatedFilter,
31
- ].freeze
32
-
33
- RULES_FOR_CONFIG =
34
- [
35
- Rules::AttributesModified,
36
- ].freeze
37
-
38
- RULES_FOR_ITEM_COLLECTION =
39
- [
40
- Rules::ItemCollectionExtended,
41
- ].freeze
42
-
43
- RULES_FOR_LAYOUT_COLLECTION =
44
- [
45
- Rules::LayoutCollectionExtended,
46
- ].freeze
47
-
48
- C_OBJ_MAYBE_REP = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Configuration, Nanoc::Int::Layout, Nanoc::Int::ItemCollection, Nanoc::Int::LayoutCollection]
49
-
50
- contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Int::ItemRepRepo] => C::Any
51
- def initialize(outdatedness_checker:, reps:)
52
- @outdatedness_checker = outdatedness_checker
53
- @reps = reps
54
- end
3
+ module Nanoc
4
+ module Int
5
+ # Responsible for determining whether an item or a layout is outdated.
6
+ #
7
+ # @api private
8
+ class OutdatednessChecker
9
+ class Basic
10
+ DDMemoize.activate(self)
11
+
12
+ include Nanoc::Core::ContractsSupport
13
+
14
+ Rules = Nanoc::Int::OutdatednessRules
15
+
16
+ RULES_FOR_ITEM_REP =
17
+ [
18
+ Rules::RulesModified,
19
+ Rules::ContentModified,
20
+ Rules::AttributesModified,
21
+ Rules::NotWritten,
22
+ Rules::CodeSnippetsModified,
23
+ Rules::UsesAlwaysOutdatedFilter,
24
+ ].freeze
25
+
26
+ RULES_FOR_LAYOUT =
27
+ [
28
+ Rules::RulesModified,
29
+ Rules::ContentModified,
30
+ Rules::AttributesModified,
31
+ Rules::UsesAlwaysOutdatedFilter,
32
+ ].freeze
33
+
34
+ RULES_FOR_CONFIG =
35
+ [
36
+ Rules::AttributesModified,
37
+ ].freeze
38
+
39
+ RULES_FOR_ITEM_COLLECTION =
40
+ [
41
+ Rules::ItemCollectionExtended,
42
+ ].freeze
43
+
44
+ RULES_FOR_LAYOUT_COLLECTION =
45
+ [
46
+ Rules::LayoutCollectionExtended,
47
+ ].freeze
48
+
49
+ C_OBJ_MAYBE_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection, Nanoc::Core::LayoutCollection]
50
+
51
+ contract C::KeywordArgs[outdatedness_checker: OutdatednessChecker, reps: Nanoc::Int::ItemRepRepo] => C::Any
52
+ def initialize(outdatedness_checker:, reps:)
53
+ @outdatedness_checker = outdatedness_checker
54
+ @reps = reps
55
+ end
55
56
 
56
- contract C_OBJ_MAYBE_REP => C::Maybe[OutdatednessStatus]
57
- memoized def outdatedness_status_for(obj)
58
- case obj
59
- when Nanoc::Int::ItemRep
60
- apply_rules(RULES_FOR_ITEM_REP, obj)
61
- when Nanoc::Int::Item
62
- apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
63
- when Nanoc::Int::Layout
64
- apply_rules(RULES_FOR_LAYOUT, obj)
65
- when Nanoc::Int::Configuration
66
- apply_rules(RULES_FOR_CONFIG, obj)
67
- when Nanoc::Int::ItemCollection
68
- apply_rules(RULES_FOR_ITEM_COLLECTION, obj)
69
- when Nanoc::Int::LayoutCollection
70
- apply_rules(RULES_FOR_LAYOUT_COLLECTION, obj)
71
- else
72
- raise Nanoc::Int::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
57
+ contract C_OBJ_MAYBE_REP => C::Maybe[OutdatednessStatus]
58
+ memoized def outdatedness_status_for(obj)
59
+ case obj
60
+ when Nanoc::Core::ItemRep
61
+ apply_rules(RULES_FOR_ITEM_REP, obj)
62
+ when Nanoc::Core::Item
63
+ apply_rules_multi(RULES_FOR_ITEM_REP, @reps[obj])
64
+ when Nanoc::Core::Layout
65
+ apply_rules(RULES_FOR_LAYOUT, obj)
66
+ when Nanoc::Core::Configuration
67
+ apply_rules(RULES_FOR_CONFIG, obj)
68
+ when Nanoc::Core::ItemCollection
69
+ apply_rules(RULES_FOR_ITEM_COLLECTION, obj)
70
+ when Nanoc::Core::LayoutCollection
71
+ apply_rules(RULES_FOR_LAYOUT_COLLECTION, obj)
72
+ else
73
+ raise Nanoc::Int::Errors::InternalInconsistency, "do not know how to check outdatedness of #{obj.inspect}"
74
+ end
73
75
  end
74
- end
75
76
 
76
- private
77
+ private
77
78
 
78
- contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, OutdatednessStatus => C::Maybe[OutdatednessStatus]
79
- def apply_rules(rules, obj, status = OutdatednessStatus.new)
80
- rules.inject(status) do |acc, rule|
81
- if !acc.useful_to_apply?(rule)
82
- acc
83
- else
84
- reason = rule.instance.call(obj, @outdatedness_checker)
85
- if reason
86
- acc.update(reason)
87
- else
79
+ contract C::ArrayOf[Class], C_OBJ_MAYBE_REP, OutdatednessStatus => C::Maybe[OutdatednessStatus]
80
+ def apply_rules(rules, obj, status = OutdatednessStatus.new)
81
+ rules.inject(status) do |acc, rule|
82
+ if !acc.useful_to_apply?(rule)
88
83
  acc
84
+ else
85
+ reason = rule.instance.call(obj, @outdatedness_checker)
86
+ if reason
87
+ acc.update(reason)
88
+ else
89
+ acc
90
+ end
89
91
  end
90
92
  end
91
93
  end
92
- end
93
94
 
94
- contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[OutdatednessStatus]
95
- def apply_rules_multi(rules, objs)
96
- objs.inject(OutdatednessStatus.new) { |acc, elem| apply_rules(rules, elem, acc) }
95
+ contract C::ArrayOf[Class], C::ArrayOf[C_OBJ_MAYBE_REP] => C::Maybe[OutdatednessStatus]
96
+ def apply_rules_multi(rules, objs)
97
+ objs.inject(OutdatednessStatus.new) { |acc, elem| apply_rules(rules, elem, acc) }
98
+ end
97
99
  end
98
- end
99
-
100
- DDMemoize.activate(self)
101
100
 
102
- include Nanoc::Int::ContractsSupport
103
-
104
- attr_reader :checksum_store
105
- attr_reader :checksums
106
- attr_reader :dependency_store
107
- attr_reader :action_sequence_store
108
- attr_reader :action_sequences
109
- attr_reader :site
101
+ DDMemoize.activate(self)
110
102
 
111
- Reasons = Nanoc::Int::OutdatednessReasons
103
+ include Nanoc::Core::ContractsSupport
104
+
105
+ attr_reader :checksum_store
106
+ attr_reader :checksums
107
+ attr_reader :dependency_store
108
+ attr_reader :action_sequence_store
109
+ attr_reader :action_sequences
110
+ attr_reader :site
111
+
112
+ Reasons = Nanoc::Int::OutdatednessReasons
113
+
114
+ C_OBJ = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep, Nanoc::Core::Configuration, Nanoc::Core::Layout, Nanoc::Core::ItemCollection]
115
+ C_ITEM_OR_REP = C::Or[Nanoc::Core::Item, Nanoc::Core::ItemRep]
116
+ C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Int::ActionSequence]
117
+
118
+ contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, checksums: Nanoc::Int::ChecksumCollection, dependency_store: Nanoc::Int::DependencyStore, action_sequence_store: Nanoc::Int::ActionSequenceStore, action_sequences: C_ACTION_SEQUENCES, reps: Nanoc::Int::ItemRepRepo] => C::Any
119
+ def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
120
+ @site = site
121
+ @checksum_store = checksum_store
122
+ @checksums = checksums
123
+ @dependency_store = dependency_store
124
+ @action_sequence_store = action_sequence_store
125
+ @action_sequences = action_sequences
126
+ @reps = reps
112
127
 
113
- C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Configuration, Nanoc::Int::Layout, Nanoc::Int::ItemCollection]
114
- C_ITEM_OR_REP = C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep]
115
- C_ACTION_SEQUENCES = C::HashOf[C_OBJ => Nanoc::Int::ActionSequence]
128
+ @objects_outdated_due_to_dependencies = {}
129
+ end
116
130
 
117
- contract C::KeywordArgs[site: Nanoc::Int::Site, checksum_store: Nanoc::Int::ChecksumStore, checksums: Nanoc::Int::ChecksumCollection, dependency_store: Nanoc::Int::DependencyStore, action_sequence_store: Nanoc::Int::ActionSequenceStore, action_sequences: C_ACTION_SEQUENCES, reps: Nanoc::Int::ItemRepRepo] => C::Any
118
- def initialize(site:, checksum_store:, checksums:, dependency_store:, action_sequence_store:, action_sequences:, reps:)
119
- @site = site
120
- @checksum_store = checksum_store
121
- @checksums = checksums
122
- @dependency_store = dependency_store
123
- @action_sequence_store = action_sequence_store
124
- @action_sequences = action_sequences
125
- @reps = reps
131
+ def action_sequence_for(rep)
132
+ @action_sequences.fetch(rep)
133
+ end
126
134
 
127
- @objects_outdated_due_to_dependencies = {}
128
- end
135
+ contract C_OBJ => C::Bool
136
+ def outdated?(obj)
137
+ outdatedness_reasons_for(obj).any?
138
+ end
129
139
 
130
- def action_sequence_for(rep)
131
- @action_sequences.fetch(rep)
132
- end
140
+ contract C_OBJ => C::IterOf[Reasons::Generic]
141
+ def outdatedness_reasons_for(obj)
142
+ reasons = basic.outdatedness_status_for(obj).reasons
143
+ if reasons.any?
144
+ reasons
145
+ elsif outdated_due_to_dependencies?(obj)
146
+ [Reasons::DependenciesOutdated]
147
+ else
148
+ []
149
+ end
150
+ end
133
151
 
134
- contract C_OBJ => C::Bool
135
- def outdated?(obj)
136
- outdatedness_reasons_for(obj).any?
137
- end
152
+ private
138
153
 
139
- contract C_OBJ => C::IterOf[Reasons::Generic]
140
- def outdatedness_reasons_for(obj)
141
- reasons = basic.outdatedness_status_for(obj).reasons
142
- if reasons.any?
143
- reasons
144
- elsif outdated_due_to_dependencies?(obj)
145
- [Reasons::DependenciesOutdated]
146
- else
147
- []
154
+ contract C::None => Basic
155
+ def basic
156
+ @_basic ||= Basic.new(outdatedness_checker: self, reps: @reps)
148
157
  end
149
- end
150
158
 
151
- private
159
+ contract C_ITEM_OR_REP, Hamster::Set => C::Bool
160
+ def outdated_due_to_dependencies?(obj, processed = Hamster::Set.new)
161
+ # Convert from rep to item if necessary
162
+ obj = obj.item if obj.is_a?(Nanoc::Core::ItemRep)
152
163
 
153
- contract C::None => Basic
154
- def basic
155
- @_basic ||= Basic.new(outdatedness_checker: self, reps: @reps)
156
- end
164
+ # Get from cache
165
+ if @objects_outdated_due_to_dependencies.key?(obj)
166
+ return @objects_outdated_due_to_dependencies[obj]
167
+ end
157
168
 
158
- contract C_ITEM_OR_REP, Hamster::Set => C::Bool
159
- def outdated_due_to_dependencies?(obj, processed = Hamster::Set.new)
160
- # Convert from rep to item if necessary
161
- obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep)
169
+ # Check processed
170
+ # Don’t return true; the false will be or’ed into a true if there
171
+ # really is a dependency that is causing outdatedness.
172
+ return false if processed.include?(obj)
162
173
 
163
- # Get from cache
164
- if @objects_outdated_due_to_dependencies.key?(obj)
165
- return @objects_outdated_due_to_dependencies[obj]
166
- end
174
+ # Calculate
175
+ is_outdated = dependency_store.dependencies_causing_outdatedness_of(obj).any? do |dep|
176
+ dependency_causes_outdatedness?(dep) ||
177
+ (dep.props.compiled_content? &&
178
+ outdated_due_to_dependencies?(dep.from, processed.merge([obj])))
179
+ end
167
180
 
168
- # Check processed
169
- # Don’t return true; the false will be or’ed into a true if there
170
- # really is a dependency that is causing outdatedness.
171
- return false if processed.include?(obj)
181
+ # Cache
182
+ @objects_outdated_due_to_dependencies[obj] = is_outdated
172
183
 
173
- # Calculate
174
- is_outdated = dependency_store.dependencies_causing_outdatedness_of(obj).any? do |dep|
175
- dependency_causes_outdatedness?(dep) ||
176
- (dep.props.compiled_content? &&
177
- outdated_due_to_dependencies?(dep.from, processed.merge([obj])))
184
+ # Done
185
+ is_outdated
178
186
  end
179
187
 
180
- # Cache
181
- @objects_outdated_due_to_dependencies[obj] = is_outdated
182
-
183
- # Done
184
- is_outdated
185
- end
186
-
187
- contract Nanoc::Int::Dependency => C::Bool
188
- def dependency_causes_outdatedness?(dependency)
189
- return true if dependency.from.nil?
188
+ contract Nanoc::Int::Dependency => C::Bool
189
+ def dependency_causes_outdatedness?(dependency)
190
+ return true if dependency.from.nil?
190
191
 
191
- status = basic.outdatedness_status_for(dependency.from)
192
+ status = basic.outdatedness_status_for(dependency.from)
192
193
 
193
- active = status.props.active & dependency.props.active
194
- active.delete(:attributes) if attributes_unaffected?(status, dependency)
195
- active.delete(:raw_content) if raw_content_unaffected?(status, dependency)
194
+ active = status.props.active & dependency.props.active
195
+ active.delete(:attributes) if attributes_unaffected?(status, dependency)
196
+ active.delete(:raw_content) if raw_content_unaffected?(status, dependency)
196
197
 
197
- active.any?
198
- end
198
+ active.any?
199
+ end
199
200
 
200
- def attributes_unaffected?(status, dependency)
201
- reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified) }
202
- reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & reason.attributes).empty?
203
- end
201
+ def attributes_unaffected?(status, dependency)
202
+ reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified) }
203
+ reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & reason.attributes).empty?
204
+ end
204
205
 
205
- def raw_content_unaffected?(status, dependency)
206
- reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::DocumentCollectionExtended) }
207
- if reason.nil?
208
- false
209
- elsif !dependency.props.raw_content.is_a?(Enumerable)
210
- false
211
- else
212
- patterns = dependency.props.raw_content.map { |r| Nanoc::Int::Pattern.from(r) }
213
- patterns.none? { |pat| reason.objects.any? { |obj| pat.match?(obj.identifier) } }
206
+ def raw_content_unaffected?(status, dependency)
207
+ reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::DocumentCollectionExtended) }
208
+ if reason.nil?
209
+ false
210
+ elsif !dependency.props.raw_content.is_a?(Enumerable)
211
+ false
212
+ else
213
+ patterns = dependency.props.raw_content.map { |r| Nanoc::Core::Pattern.from(r) }
214
+ patterns.none? { |pat| reason.objects.any? { |obj| pat.match?(obj.identifier) } }
215
+ end
214
216
  end
215
217
  end
216
218
  end