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,25 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class OutdatednessStatus
6
- attr_reader :reasons
7
- attr_reader :props
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class OutdatednessStatus
7
+ attr_reader :reasons
8
+ attr_reader :props
8
9
 
9
- def initialize(reasons: [], props: Props.new)
10
- @reasons = reasons
11
- @props = props
12
- end
10
+ def initialize(reasons: [], props: Props.new)
11
+ @reasons = reasons
12
+ @props = props
13
+ end
13
14
 
14
- def useful_to_apply?(rule)
15
- (rule.affected_props - @props.active).any?
16
- end
15
+ def useful_to_apply?(rule)
16
+ (rule.affected_props - @props.active).any?
17
+ end
17
18
 
18
- def update(reason)
19
- self.class.new(
20
- reasons: @reasons + [reason],
21
- props: @props.merge(reason.props),
22
- )
19
+ def update(reason)
20
+ self.class.new(
21
+ reasons: @reasons + [reason],
22
+ props: @props.merge(reason.props),
23
+ )
24
+ end
23
25
  end
24
26
  end
25
27
  end
@@ -1,148 +1,150 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class Props
6
- include Nanoc::Int::ContractsSupport
7
-
8
- attr_reader :attributes
9
- attr_reader :raw_content
10
-
11
- # TODO: Split raw_content for documents and collections
12
- C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool]
13
- C_ATTRS = C::Or[C::IterOf[Symbol], C::Bool]
14
- contract C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTRS], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
15
- def initialize(raw_content: false, attributes: false, compiled_content: false, path: false)
16
- @compiled_content = compiled_content
17
- @path = path
18
-
19
- @attributes =
20
- case attributes
21
- when Set
22
- attributes
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class Props
7
+ include Nanoc::Core::ContractsSupport
8
+
9
+ attr_reader :attributes
10
+ attr_reader :raw_content
11
+
12
+ # TODO: Split raw_content for documents and collections
13
+ C_RAW_CONTENT = C::Or[C::IterOf[C::Or[String, Regexp]], C::Bool]
14
+ C_ATTRS = C::Or[C::IterOf[Symbol], C::Bool]
15
+ contract C::KeywordArgs[raw_content: C::Optional[C_RAW_CONTENT], attributes: C::Optional[C_ATTRS], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]] => C::Any
16
+ def initialize(raw_content: false, attributes: false, compiled_content: false, path: false)
17
+ @compiled_content = compiled_content
18
+ @path = path
19
+
20
+ @attributes =
21
+ case attributes
22
+ when Set
23
+ attributes
24
+ when Enumerable
25
+ Set.new(attributes)
26
+ else
27
+ attributes
28
+ end
29
+
30
+ @raw_content =
31
+ case raw_content
32
+ when Set
33
+ raw_content
34
+ when Enumerable
35
+ Set.new(raw_content)
36
+ else
37
+ raw_content
38
+ end
39
+ end
40
+
41
+ contract C::None => String
42
+ def inspect
43
+ (+'').tap do |s|
44
+ s << 'Props('
45
+ s << (raw_content? ? 'r' : '_')
46
+ s << (attributes? ? 'a' : '_')
47
+ s << (compiled_content? ? 'c' : '_')
48
+ s << (path? ? 'p' : '_')
49
+ s << ')'
50
+ end
51
+ end
52
+
53
+ contract C::None => String
54
+ def to_s
55
+ (+'').tap do |s|
56
+ s << (raw_content? ? 'r' : '_')
57
+ s << (attributes? ? 'a' : '_')
58
+ s << (compiled_content? ? 'c' : '_')
59
+ s << (path? ? 'p' : '_')
60
+ end
61
+ end
62
+
63
+ contract C::None => C::Bool
64
+ def raw_content?
65
+ case @raw_content
23
66
  when Enumerable
24
- Set.new(attributes)
67
+ @raw_content.any?
25
68
  else
26
- attributes
69
+ @raw_content
27
70
  end
71
+ end
28
72
 
29
- @raw_content =
30
- case raw_content
31
- when Set
32
- raw_content
73
+ contract C::None => C::Bool
74
+ def attributes?
75
+ case @attributes
33
76
  when Enumerable
34
- Set.new(raw_content)
77
+ @attributes.any?
35
78
  else
36
- raw_content
79
+ @attributes
37
80
  end
38
- end
39
-
40
- contract C::None => String
41
- def inspect
42
- (+'').tap do |s|
43
- s << 'Props('
44
- s << (raw_content? ? 'r' : '_')
45
- s << (attributes? ? 'a' : '_')
46
- s << (compiled_content? ? 'c' : '_')
47
- s << (path? ? 'p' : '_')
48
- s << ')'
49
81
  end
50
- end
51
82
 
52
- contract C::None => String
53
- def to_s
54
- (+'').tap do |s|
55
- s << (raw_content? ? 'r' : '_')
56
- s << (attributes? ? 'a' : '_')
57
- s << (compiled_content? ? 'c' : '_')
58
- s << (path? ? 'p' : '_')
83
+ contract C::None => C::Bool
84
+ def compiled_content?
85
+ @compiled_content
59
86
  end
60
- end
61
87
 
62
- contract C::None => C::Bool
63
- def raw_content?
64
- case @raw_content
65
- when Enumerable
66
- @raw_content.any?
67
- else
68
- @raw_content
88
+ contract C::None => C::Bool
89
+ def path?
90
+ @path
69
91
  end
70
- end
71
92
 
72
- contract C::None => C::Bool
73
- def attributes?
74
- case @attributes
75
- when Enumerable
76
- @attributes.any?
77
- else
78
- @attributes
93
+ contract Nanoc::Int::Props => Nanoc::Int::Props
94
+ def merge(other)
95
+ Props.new(
96
+ raw_content: merge_raw_content(other),
97
+ attributes: merge_attributes(other),
98
+ compiled_content: compiled_content? || other.compiled_content?,
99
+ path: path? || other.path?,
100
+ )
79
101
  end
80
- end
81
102
 
82
- contract C::None => C::Bool
83
- def compiled_content?
84
- @compiled_content
85
- end
86
-
87
- contract C::None => C::Bool
88
- def path?
89
- @path
90
- end
91
-
92
- contract Nanoc::Int::Props => Nanoc::Int::Props
93
- def merge(other)
94
- Props.new(
95
- raw_content: merge_raw_content(other),
96
- attributes: merge_attributes(other),
97
- compiled_content: compiled_content? || other.compiled_content?,
98
- path: path? || other.path?,
99
- )
100
- end
101
-
102
- def merge_raw_content(other)
103
- merge_prop(raw_content, other.raw_content)
104
- end
103
+ def merge_raw_content(other)
104
+ merge_prop(raw_content, other.raw_content)
105
+ end
105
106
 
106
- def merge_attributes(other)
107
- merge_prop(attributes, other.attributes)
108
- end
107
+ def merge_attributes(other)
108
+ merge_prop(attributes, other.attributes)
109
+ end
109
110
 
110
- def merge_prop(own, other)
111
- case own
112
- when true
113
- true
114
- when false
115
- other
116
- else
117
- case other
111
+ def merge_prop(own, other)
112
+ case own
118
113
  when true
119
114
  true
120
115
  when false
121
- own
116
+ other
122
117
  else
123
- own + other
118
+ case other
119
+ when true
120
+ true
121
+ when false
122
+ own
123
+ else
124
+ own + other
125
+ end
124
126
  end
125
127
  end
126
- end
127
128
 
128
- contract C::None => Set
129
- def active
130
- Set.new.tap do |pr|
131
- pr << :raw_content if raw_content?
132
- pr << :attributes if attributes?
133
- pr << :compiled_content if compiled_content?
134
- pr << :path if path?
129
+ contract C::None => Set
130
+ def active
131
+ Set.new.tap do |pr|
132
+ pr << :raw_content if raw_content?
133
+ pr << :attributes if attributes?
134
+ pr << :compiled_content if compiled_content?
135
+ pr << :path if path?
136
+ end
135
137
  end
136
- end
137
138
 
138
- contract C::None => Hash
139
- def to_h
140
- {
141
- raw_content: raw_content,
142
- attributes: attributes,
143
- compiled_content: compiled_content?,
144
- path: path?,
145
- }
139
+ contract C::None => Hash
140
+ def to_h
141
+ {
142
+ raw_content: raw_content,
143
+ attributes: attributes,
144
+ compiled_content: compiled_content?,
145
+ path: path?,
146
+ }
147
+ end
146
148
  end
147
149
  end
148
150
  end
@@ -1,68 +1,64 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # @api private
5
- class Site
6
- include Nanoc::Int::ContractsSupport
3
+ module Nanoc
4
+ module Int
5
+ # @api private
6
+ class Site
7
+ include Nanoc::Core::ContractsSupport
7
8
 
8
- attr_reader :code_snippets
9
- attr_reader :config
10
- attr_accessor :data_source
9
+ attr_reader :code_snippets
10
+ attr_reader :config
11
+ attr_accessor :data_source
11
12
 
12
- contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::IterOf[Nanoc::Int::CodeSnippet], data_source: C::Named['Nanoc::DataSource']] => C::Any
13
- def initialize(config:, code_snippets:, data_source:)
14
- @config = config
15
- @code_snippets = code_snippets
16
- @data_source = data_source
13
+ contract C::KeywordArgs[config: Nanoc::Core::Configuration, code_snippets: C::IterOf[Nanoc::Core::CodeSnippet], data_source: C::Named['Nanoc::DataSource']] => C::Any
14
+ def initialize(config:, code_snippets:, data_source:)
15
+ @config = config
16
+ @code_snippets = code_snippets
17
+ @data_source = data_source
17
18
 
18
- @preprocessed = false
19
+ @preprocessed = false
19
20
 
20
- ensure_identifier_uniqueness(@data_source.items, 'item')
21
- ensure_identifier_uniqueness(@data_source.layouts, 'layout')
22
- end
21
+ ensure_identifier_uniqueness(@data_source.items, 'item')
22
+ ensure_identifier_uniqueness(@data_source.layouts, 'layout')
23
+ end
23
24
 
24
- contract C::None => self
25
- def compile
26
- Nanoc::Int::Compiler.new_for(self).run_until_end
27
- self
28
- end
25
+ def mark_as_preprocessed
26
+ @preprocessed = true
27
+ end
29
28
 
30
- def mark_as_preprocessed
31
- @preprocessed = true
32
- end
29
+ def preprocessed?
30
+ @preprocessed
31
+ end
33
32
 
34
- def preprocessed?
35
- @preprocessed
36
- end
33
+ def items
34
+ @data_source.items
35
+ end
37
36
 
38
- def items
39
- @data_source.items
40
- end
37
+ def layouts
38
+ @data_source.layouts
39
+ end
41
40
 
42
- def layouts
43
- @data_source.layouts
44
- end
41
+ contract C::None => self
42
+ def freeze
43
+ config.freeze
44
+ items.freeze
45
+ layouts.freeze
46
+ code_snippets.__nanoc_freeze_recursively
47
+ self
48
+ end
45
49
 
46
- contract C::None => self
47
- def freeze
48
- config.freeze
49
- items.freeze
50
- layouts.freeze
51
- code_snippets.__nanoc_freeze_recursively
52
- self
53
- end
50
+ contract C::IterOf[C::Or[Nanoc::Core::Item, Nanoc::Core::Layout]], String => self
51
+ def ensure_identifier_uniqueness(objects, type)
52
+ seen = Set.new
53
+ objects.each do |obj|
54
+ if seen.include?(obj.identifier)
55
+ raise Nanoc::Int::Errors::DuplicateIdentifier.new(obj.identifier, type)
56
+ end
54
57
 
55
- contract C::IterOf[C::Or[Nanoc::Int::Item, Nanoc::Int::Layout]], String => self
56
- def ensure_identifier_uniqueness(objects, type)
57
- seen = Set.new
58
- objects.each do |obj|
59
- if seen.include?(obj.identifier)
60
- raise Nanoc::Int::Errors::DuplicateIdentifier.new(obj.identifier, type)
58
+ seen << obj.identifier
61
59
  end
62
-
63
- seen << obj.identifier
60
+ self
64
61
  end
65
- self
66
62
  end
67
63
  end
68
64
  end
@@ -1,248 +1,233 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Nanoc::Int
4
- # Module that contains all Nanoc-specific errors.
5
- #
6
- # @api private
7
- module Errors
8
- Generic = ::Nanoc::Error
9
-
10
- # Generic trivial error. Superclass for all Nanoc-specific errors that are
11
- # considered "trivial", i.e. errors that do not require a full crash report.
12
- class GenericTrivial < Generic
13
- end
14
-
15
- # Error that is raised when compilation of an item rep fails. The
16
- # underlying error is available by calling `#unwrap`.
17
- class CompilationError < Generic
18
- attr_reader :item_rep
3
+ module Nanoc
4
+ module Int
5
+ # Module that contains all Nanoc-specific errors.
6
+ #
7
+ # @api private
8
+ module Errors
9
+ Generic = ::Nanoc::Error
10
+
11
+ # Generic trivial error. Superclass for all Nanoc-specific errors that are
12
+ # considered "trivial", i.e. errors that do not require a full crash report.
13
+ class GenericTrivial < Generic
14
+ end
15
+
16
+ # Error that is raised when compilation of an item rep fails. The
17
+ # underlying error is available by calling `#unwrap`.
18
+ class CompilationError < Generic
19
+ attr_reader :item_rep
20
+
21
+ def initialize(wrapped, item_rep)
22
+ @wrapped = wrapped
23
+ @item_rep = item_rep
24
+ end
19
25
 
20
- def initialize(wrapped, item_rep)
21
- @wrapped = wrapped
22
- @item_rep = item_rep
26
+ def unwrap
27
+ @wrapped
28
+ end
23
29
  end
24
30
 
25
- def unwrap
26
- @wrapped
31
+ # Error that is raised when a site is loaded that uses a data source with
32
+ # an unknown identifier.
33
+ class UnknownDataSource < Generic
34
+ # @param [String] data_source_name The data source name for which no
35
+ # data source could be found
36
+ def initialize(data_source_name)
37
+ super("The data source specified in the site’s configuration file, “#{data_source_name}”, does not exist.")
38
+ end
27
39
  end
28
- end
29
40
 
30
- # Error that is raised when a site is loaded that uses a data source with
31
- # an unknown identifier.
32
- class UnknownDataSource < Generic
33
- # @param [String] data_source_name The data source name for which no
34
- # data source could be found
35
- def initialize(data_source_name)
36
- super("The data source specified in the site’s configuration file, “#{data_source_name}”, does not exist.")
41
+ # Error that is raised during site compilation when an item uses a layout
42
+ # that is not present in the site.
43
+ class UnknownLayout < Generic
44
+ # @param [String] layout_identifier The layout identifier for which no
45
+ # layout could be found
46
+ def initialize(layout_identifier)
47
+ super("The site does not have a layout with identifier “#{layout_identifier}”.")
48
+ end
37
49
  end
38
- end
39
50
 
40
- # Error that is raised during site compilation when an item uses a layout
41
- # that is not present in the site.
42
- class UnknownLayout < Generic
43
- # @param [String] layout_identifier The layout identifier for which no
44
- # layout could be found
45
- def initialize(layout_identifier)
46
- super("The site does not have a layout with identifier “#{layout_identifier}”.")
51
+ # Error that is raised during site compilation when a layout is compiled
52
+ # for which the filter cannot be determined. This is similar to the
53
+ # {UnknownFilter} error, but specific for filters for layouts.
54
+ class CannotDetermineFilter < Generic
55
+ # @param [String] layout_identifier The identifier of the layout for
56
+ # which the filter could not be determined
57
+ def initialize(layout_identifier)
58
+ super("The filter to be used for the “#{layout_identifier}” layout could not be determined. Make sure the layout does have a filter.")
59
+ end
47
60
  end
48
- end
49
61
 
50
- # Error that is raised during site compilation when an item uses a filter
51
- # that is not known.
52
- class UnknownFilter < Generic
53
- # @param [Symbol] filter_name The filter name for which no filter could
54
- # be found
55
- def initialize(filter_name)
56
- super("The requested filter, “#{filter_name}”, does not exist.")
57
- end
58
- end
62
+ # Error that is raised during site compilation when an item (directly or
63
+ # indirectly) includes its own item content, leading to endless recursion.
64
+ class DependencyCycle < Generic
65
+ def initialize(stack)
66
+ start_idx = stack.index(stack.last)
67
+ cycle = stack[start_idx..-2]
59
68
 
60
- # Error that is raised during site compilation when a layout is compiled
61
- # for which the filter cannot be determined. This is similar to the
62
- # {UnknownFilter} error, but specific for filters for layouts.
63
- class CannotDetermineFilter < Generic
64
- # @param [String] layout_identifier The identifier of the layout for
65
- # which the filter could not be determined
66
- def initialize(layout_identifier)
67
- super("The filter to be used for the “#{layout_identifier}” layout could not be determined. Make sure the layout does have a filter.")
68
- end
69
- end
70
-
71
- # Error that is raised during site compilation when an item (directly or
72
- # indirectly) includes its own item content, leading to endless recursion.
73
- class DependencyCycle < Generic
74
- def initialize(stack)
75
- start_idx = stack.index(stack.last)
76
- cycle = stack[start_idx..-2]
69
+ msg_bits = []
70
+ msg_bits << 'The site cannot be compiled because there is a dependency cycle:'
71
+ msg_bits << ''
72
+ cycle.each.with_index do |r, i|
73
+ msg_bits << " (#{i + 1}) item #{r.item.identifier}, rep #{r.name.inspect}, uses compiled content of"
74
+ end
75
+ msg_bits << msg_bits.pop + ' (1)'
77
76
 
78
- msg_bits = []
79
- msg_bits << 'The site cannot be compiled because there is a dependency cycle:'
80
- msg_bits << ''
81
- cycle.each.with_index do |r, i|
82
- msg_bits << " (#{i + 1}) item #{r.item.identifier}, rep #{r.name.inspect}, uses compiled content of"
77
+ super(msg_bits.map { |x| x + "\n" }.join(''))
83
78
  end
84
- msg_bits << msg_bits.pop + ' (1)'
85
-
86
- super(msg_bits.map { |x| x + "\n" }.join(''))
87
79
  end
88
- end
89
80
 
90
- # Error that is raised when no rules file can be found in the current
91
- # working directory.
92
- class NoRulesFileFound < Generic
93
- def initialize
94
- super('This site does not have a rules file, which is required for Nanoc sites.')
81
+ # Error that is raised when no rules file can be found in the current
82
+ # working directory.
83
+ class NoRulesFileFound < Generic
84
+ def initialize
85
+ super('This site does not have a rules file, which is required for Nanoc sites.')
86
+ end
95
87
  end
96
- end
97
88
 
98
- # Error that is raised when no compilation rule that can be applied to the
99
- # current item can be found.
100
- class NoMatchingCompilationRuleFound < Generic
101
- # @param [Nanoc::Int::Item] item The item for which no compilation rule
102
- # could be found
103
- def initialize(item)
104
- super("No compilation rules were found for the “#{item.identifier}” item.")
89
+ # Error that is raised when no compilation rule that can be applied to the
90
+ # current item can be found.
91
+ class NoMatchingCompilationRuleFound < Generic
92
+ # @param [Nanoc::Core::Item] item The item for which no compilation rule
93
+ # could be found
94
+ def initialize(item)
95
+ super("No compilation rules were found for the “#{item.identifier}” item.")
96
+ end
105
97
  end
106
- end
107
98
 
108
- # Error that is raised when no routing rule that can be applied to the
109
- # current item can be found.
110
- class NoMatchingRoutingRuleFound < Generic
111
- # @param [Nanoc::Int::ItemRep] rep The item repiresentation for which no
112
- # routing rule could be found
113
- def initialize(rep)
114
- super("No routing rules were found for the “#{rep.item.identifier}” item (rep “#{rep.name}”).")
99
+ # Error that is raised when no routing rule that can be applied to the
100
+ # current item can be found.
101
+ class NoMatchingRoutingRuleFound < Generic
102
+ # @param [Nanoc::Core::ItemRep] rep The item repiresentation for which no
103
+ # routing rule could be found
104
+ def initialize(rep)
105
+ super("No routing rules were found for the “#{rep.item.identifier}” item (rep “#{rep.name}”).")
106
+ end
115
107
  end
116
- end
117
108
 
118
- # Error that is raised when an rep cannot be compiled because it depends
119
- # on other representations.
120
- class UnmetDependency < Generic
121
- # @return [Nanoc::Int::ItemRep] The item representation that cannot yet be
122
- # compiled
123
- attr_reader :rep
109
+ # Error that is raised when an rep cannot be compiled because it depends
110
+ # on other representations.
111
+ class UnmetDependency < Generic
112
+ # @return [Nanoc::Core::ItemRep] The item representation that cannot yet be
113
+ # compiled
114
+ attr_reader :rep
124
115
 
125
- # @param [Nanoc::Int::ItemRep] rep The item representation that cannot yet be
126
- # compiled
127
- def initialize(rep)
128
- @rep = rep
129
- super("The current item cannot be compiled yet because of an unmet dependency on the “#{rep.item.identifier}” item (rep “#{rep.name}”).")
130
- end
131
- end
116
+ # @return [Symbol] The name of the snapshot that cannot yet be compiled
117
+ attr_reader :snapshot_name
132
118
 
133
- # Error that is raised when a binary item is attempted to be laid out.
134
- class CannotLayoutBinaryItem < Generic
135
- # @param [Nanoc::Int::ItemRep] rep The item representation that was attempted
136
- # to be laid out
137
- def initialize(rep)
138
- super("The “#{rep.item.identifier}” item (rep “#{rep.name}”) cannot be laid out because it is a binary item. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
139
- end
140
- end
119
+ # @param [Nanoc::Core::ItemRep] rep The item representation that cannot yet be
120
+ # compiled
121
+ def initialize(rep, snapshot_name)
122
+ @rep = rep
123
+ @snapshot_name = snapshot_name
141
124
 
142
- # Error that is raised when a textual filter is attempted to be applied to
143
- # a binary item representation.
144
- class CannotUseTextualFilter < Generic
145
- # @param [Nanoc::Int::ItemRep] rep The item representation that was
146
- # attempted to be filtered
147
- #
148
- # @param [Class] filter_class The filter class that was used
149
- def initialize(rep, filter_class)
150
- super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because textual filters cannot be used on binary items.")
125
+ super("The current item cannot be compiled yet because of an unmet dependency on the “#{rep.item.identifier}” item (rep “#{rep.name}”, snapshot “#{snapshot_name}”).")
126
+ end
151
127
  end
152
- end
153
128
 
154
- # Error that is raised when a binary filter is attempted to be applied to
155
- # a textual item representation.
156
- class CannotUseBinaryFilter < Generic
157
- # @param [Nanoc::Int::ItemRep] rep The item representation that was
158
- # attempted to be filtered
159
- #
160
- # @param [Class] filter_class The filter class that was used
161
- def initialize(rep, filter_class)
162
- super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because binary filters cannot be used on textual items. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
129
+ # Error that is raised when a binary item is attempted to be laid out.
130
+ class CannotLayoutBinaryItem < Generic
131
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was attempted
132
+ # to be laid out
133
+ def initialize(rep)
134
+ super("The “#{rep.item.identifier}” item (rep “#{rep.name}”) cannot be laid out because it is a binary item. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
135
+ end
163
136
  end
164
- end
165
137
 
166
- # Error that is raised when the compiled content at a non-existing snapshot
167
- # is requested.
168
- class NoSuchSnapshot < Generic
169
- # @return [Nanoc::Int::ItemRep] The item rep from which the compiled content
170
- # was requested
171
- attr_reader :item_rep
172
-
173
- # @return [Symbol] The requested snapshot
174
- attr_reader :snapshot
175
-
176
- # @param [Nanoc::Int::ItemRep] item_rep The item rep from which the compiled
177
- # content was requested
178
- #
179
- # @param [Symbol] snapshot The requested snapshot
180
- def initialize(item_rep, snapshot)
181
- @item_rep = item_rep
182
- @snapshot = snapshot
183
- super("The “#{item_rep.inspect}” item rep does not have a snapshot “#{snapshot.inspect}”")
138
+ # Error that is raised when a textual filter is attempted to be applied to
139
+ # a binary item representation.
140
+ class CannotUseTextualFilter < Generic
141
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was
142
+ # attempted to be filtered
143
+ #
144
+ # @param [Class] filter_class The filter class that was used
145
+ def initialize(rep, filter_class)
146
+ super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because textual filters cannot be used on binary items.")
147
+ end
184
148
  end
185
- end
186
149
 
187
- # Error that is raised when a snapshot with an existing name is made.
188
- class CannotCreateMultipleSnapshotsWithSameName < Generic
189
- # @param [Nanoc::Int::ItemRep] rep The item representation for which a
190
- # snapshot was attempted to be made
191
- #
192
- # @param [Symbol] snapshot The name of the snapshot that was attempted to
193
- # be made
194
- def initialize(rep, snapshot)
195
- super("Attempted to create a snapshot with a duplicate name #{snapshot.inspect} for the item rep #{rep}")
150
+ # Error that is raised when a binary filter is attempted to be applied to
151
+ # a textual item representation.
152
+ class CannotUseBinaryFilter < Generic
153
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was
154
+ # attempted to be filtered
155
+ #
156
+ # @param [Class] filter_class The filter class that was used
157
+ def initialize(rep, filter_class)
158
+ super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier} item (rep “#{rep.name}”), because binary filters cannot be used on textual items. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
159
+ end
196
160
  end
197
- end
198
161
 
199
- # Error that is raised when the compiled content of a binary item is attempted to be accessed.
200
- class CannotGetCompiledContentOfBinaryItem < Generic
201
- # @param [Nanoc::Int::ItemRep] rep The binary item representation whose compiled content was attempted to be accessed
202
- def initialize(rep)
203
- super("You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is #{rep}.")
162
+ # Error that is raised when the compiled content at a non-existing snapshot
163
+ # is requested.
164
+ class NoSuchSnapshot < Generic
165
+ # @return [Nanoc::Core::ItemRep] The item rep from which the compiled content
166
+ # was requested
167
+ attr_reader :item_rep
168
+
169
+ # @return [Symbol] The requested snapshot
170
+ attr_reader :snapshot
171
+
172
+ # @param [Nanoc::Core::ItemRep] item_rep The item rep from which the compiled
173
+ # content was requested
174
+ #
175
+ # @param [Symbol] snapshot The requested snapshot
176
+ def initialize(item_rep, snapshot)
177
+ @item_rep = item_rep
178
+ @snapshot = snapshot
179
+ super("The “#{item_rep.inspect}” item rep does not have a snapshot “#{snapshot.inspect}”")
180
+ end
204
181
  end
205
- end
206
182
 
207
- # Error that is raised when multiple items or layouts with the same identifier exist.
208
- class DuplicateIdentifier < Generic
209
- def initialize(identifier, type)
210
- super("There are multiple #{type}s with the #{identifier} identifier.")
183
+ # Error that is raised when a snapshot with an existing name is made.
184
+ class CannotCreateMultipleSnapshotsWithSameName < Generic
185
+ # @param [Nanoc::Core::ItemRep] rep The item representation for which a
186
+ # snapshot was attempted to be made
187
+ #
188
+ # @param [Symbol] snapshot The name of the snapshot that was attempted to
189
+ # be made
190
+ def initialize(rep, snapshot)
191
+ super("Attempted to create a snapshot with a duplicate name #{snapshot.inspect} for the item rep #{rep}")
192
+ end
211
193
  end
212
- end
213
194
 
214
- # Error that is raised when attempting to call #parent or #children on an item with a legacy identifier.
215
- class CannotGetParentOrChildrenOfNonLegacyItem < Generic
216
- def initialize(identifier)
217
- super("You cannot get the parent or children of an item that has a “full” identifier (#{identifier}). Getting the parent or children of an item is only possible for items that have a legacy identifier.")
195
+ # Error that is raised when the compiled content of a binary item is attempted to be accessed.
196
+ class CannotGetCompiledContentOfBinaryItem < Generic
197
+ # @param [Nanoc::Core::ItemRep] rep The binary item representation whose compiled content was attempted to be accessed
198
+ def initialize(rep)
199
+ super("You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is #{rep}.")
200
+ end
218
201
  end
219
- end
220
202
 
221
- class UndefinedFilterForLayout < Generic
222
- def initialize(layout)
223
- super("There is no filter defined for the layout #{layout.identifier}")
203
+ # Error that is raised when multiple items or layouts with the same identifier exist.
204
+ class DuplicateIdentifier < Generic
205
+ def initialize(identifier, type)
206
+ super("There are multiple #{type}s with the #{identifier} identifier.")
207
+ end
224
208
  end
225
- end
226
209
 
227
- class OutputNotWritten < Generic
228
- def initialize(filter_name, output_filename)
229
- super("The #{filter_name.inspect} filter did not write anything to the required output file, #{output_filename}.")
210
+ # Error that is raised when attempting to call #parent or #children on an item with a legacy identifier.
211
+ class CannotGetParentOrChildrenOfNonLegacyItem < Generic
212
+ def initialize(identifier)
213
+ super("You cannot get the parent or children of an item that has a “full” identifier (#{identifier}). Getting the parent or children of an item is only possible for items that have a legacy identifier.")
214
+ end
230
215
  end
231
- end
232
216
 
233
- class FilterReturnedNil < Generic
234
- def initialize(filter_name)
235
- super("The #{filter_name.inspect} filter returned nil, but is required to return a String.")
217
+ class UndefinedFilterForLayout < Generic
218
+ def initialize(layout)
219
+ super("There is no filter defined for the layout #{layout.identifier}")
220
+ end
236
221
  end
237
- end
238
222
 
239
- class AmbiguousMetadataAssociation < Generic
240
- def initialize(content_filenames, meta_filename)
241
- super("There are multiple content files (#{content_filenames.join(', ')}) that could match the file containing metadata (#{meta_filename}).")
223
+ class AmbiguousMetadataAssociation < Generic
224
+ def initialize(content_filenames, meta_filename)
225
+ super("There are multiple content files (#{content_filenames.sort.join(', ')}) that could match the file containing metadata (#{meta_filename}).")
226
+ end
242
227
  end
243
- end
244
228
 
245
- class InternalInconsistency < Generic
229
+ class InternalInconsistency < Generic
230
+ end
246
231
  end
247
232
  end
248
233
  end