nanoc 4.11.0 → 4.11.1

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