darkroom 0.0.9 → 0.0.10
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +175 -131
- data/VERSION +1 -1
- data/lib/darkroom/asset.rb +173 -151
- data/lib/darkroom/darkroom.rb +140 -124
- data/lib/darkroom/delegate.rb +208 -101
- data/lib/darkroom/delegates/{css.rb → css_delegate.rb} +1 -0
- data/lib/darkroom/delegates/{html.rb → html_delegate.rb} +4 -3
- data/lib/darkroom/delegates/{htx.rb → htx_delegate.rb} +3 -2
- data/lib/darkroom/delegates/{javascript.rb → javascript_delegate.rb} +9 -8
- data/lib/darkroom/errors/asset_error.rb +6 -17
- data/lib/darkroom/errors/asset_not_found_error.rb +4 -8
- data/lib/darkroom/errors/circular_reference_error.rb +4 -8
- data/lib/darkroom/errors/duplicate_asset_error.rb +7 -16
- data/lib/darkroom/errors/invalid_path_error.rb +5 -14
- data/lib/darkroom/errors/missing_library_error.rb +7 -16
- data/lib/darkroom/errors/processing_error.rb +13 -20
- data/lib/darkroom/errors/unrecognized_extension_error.rb +4 -8
- data/lib/darkroom/version.rb +1 -1
- data/lib/darkroom.rb +4 -6
- metadata +17 -21
data/lib/darkroom/delegate.rb
CHANGED
@@ -1,173 +1,280 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Darkroom
|
2
|
-
##
|
3
4
|
# Holds asset type-specific information and functionality.
|
4
|
-
#
|
5
|
-
# [minify_lib:] Name of a library to +require+ that is needed by the +minify+ lambda (optional).
|
6
|
-
# [minify:] Lambda to call that will return the minified version of the asset's content (optional). One
|
7
|
-
# argument is passed when called:
|
8
|
-
# * +content+ - Content to minify.
|
9
|
-
#
|
10
5
|
class Delegate
|
11
|
-
[
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
IMPORT_REGEX_CAPTURES = %w[path].freeze
|
7
|
+
REFERENCE_REGEX_CAPTURES = %w[quote path quoted entity format].freeze
|
8
|
+
LIB_REQUIRES = [:compile, :finalize, :minify].freeze
|
9
|
+
|
10
|
+
@content_type = nil
|
11
|
+
@parsers = nil
|
12
|
+
@compile_lib = nil
|
13
|
+
@compile_delegate = nil
|
14
|
+
@compile_handler = nil
|
15
|
+
@finalize_lib = nil
|
16
|
+
@finalize_handler = nil
|
17
|
+
@minify_lib = nil
|
18
|
+
@minify_handler = nil
|
19
|
+
|
20
|
+
# Public: Set and/or get the HTTP MIME type string, falling back to that of the parent class.
|
21
|
+
#
|
22
|
+
# Returns the String content type.
|
23
|
+
def self.content_type(content_type = (get = true; nil))
|
24
|
+
if get
|
25
|
+
defined?(@content_type) ? @content_type : superclass.content_type
|
26
|
+
else
|
27
|
+
@content_type = content_type
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
23
|
-
|
31
|
+
# Public: Get parsers, falling back to those of the parent class.
|
32
|
+
#
|
33
|
+
# Returns the Array of Proc parsers.
|
34
|
+
def self.parsers
|
35
|
+
defined?(@parsers) ? @parsers : superclass.parsers
|
36
|
+
end
|
24
37
|
|
25
|
-
|
26
|
-
# Sets or returns HTTP MIME type string.
|
38
|
+
# Public: Iterate over each parser.
|
27
39
|
#
|
28
|
-
|
29
|
-
|
40
|
+
# Yields each parser's Symbol kind, Regexp regex, and Proc handler.
|
41
|
+
#
|
42
|
+
# Returns nothing.
|
43
|
+
def self.each_parser
|
44
|
+
parsers&.each do |kind, (regex, handler)|
|
45
|
+
yield(kind, regex, handler)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Public: Get the name of the compile library to require, falling back to that of the parent class.
|
50
|
+
#
|
51
|
+
# Returns the String library name if present or nil otherwise.
|
52
|
+
def self.compile_lib
|
53
|
+
defined?(@compile_lib) ? @compile_lib : superclass.compile_lib
|
54
|
+
end
|
55
|
+
|
56
|
+
# Public: Get the Delegate class used once an asset is compiled, falling back to that of the parent
|
57
|
+
# class.
|
58
|
+
#
|
59
|
+
# Returns the Delegate class if present or nil otherwise.
|
60
|
+
def self.compile_delegate
|
61
|
+
defined?(@compile_delegate) ? @compile_delegate : superclass.compile_delegate
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Get the compile handler, falling back to that of the parent class.
|
65
|
+
#
|
66
|
+
# Returns the Proc handler if present or nil otherwise.
|
67
|
+
def self.compile_handler
|
68
|
+
defined?(@compile_handler) ? @compile_handler : superclass.compile_handler
|
69
|
+
end
|
70
|
+
|
71
|
+
# Public: Get the name of the finalize library to require, falling back to that of the parent class.
|
72
|
+
#
|
73
|
+
# Returns the String library name if present or nil otherwise.
|
74
|
+
def self.finalize_lib
|
75
|
+
defined?(@finalize_lib) ? @finalize_lib : superclass.finalize_lib
|
76
|
+
end
|
77
|
+
|
78
|
+
# Public: Get the finalize handler, falling back to that of the parent class.
|
79
|
+
#
|
80
|
+
# Returns the Proc handler if present or nil otherwise.
|
81
|
+
def self.finalize_handler
|
82
|
+
defined?(@finalize_handler) ? @finalize_handler : superclass.finalize_handler
|
30
83
|
end
|
31
84
|
|
32
|
-
|
33
|
-
# Configures how imports are handled.
|
85
|
+
# Public: Get the name of the minify library to require, falling back to that of the parent class.
|
34
86
|
#
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
|
87
|
+
# Returns the String library name if present or nil otherwise.
|
88
|
+
def self.minify_lib
|
89
|
+
defined?(@minify_lib) ? @minify_lib : superclass.minify_lib
|
90
|
+
end
|
91
|
+
|
92
|
+
# Public: Get the minify handler, falling back to that of the parent class.
|
93
|
+
#
|
94
|
+
# Returns the Proc handler if present or nil otherwise.
|
95
|
+
def self.minify_handler
|
96
|
+
defined?(@minify_handler) ? @minify_handler : superclass.minify_handler
|
97
|
+
end
|
98
|
+
|
99
|
+
# Internal: Configure import handling.
|
100
|
+
#
|
101
|
+
# regex - Regexp for finding import statements. Must contain a named components :quote (' or ") and
|
102
|
+
# :path (the path of the asset being imported).
|
103
|
+
# handler - Proc for special handling of import statements (optional), which is passed three keyword
|
104
|
+
# arguments:
|
105
|
+
#
|
106
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
107
|
+
# match: - MatchData object from the match against the regex.
|
108
|
+
# asset: - Asset object of the asset being imported.
|
44
109
|
#
|
110
|
+
# Returns nil for default behavior, or a String which is used as the substitution for the text
|
111
|
+
# matched by the regex. The portion of the matched text that is replaced can optionally be
|
112
|
+
# changed by returning second and third Integer values specifying start and end indexes
|
113
|
+
# within the regex match (e.g. ['my substitution', match.begin(:path) + 1,
|
114
|
+
# match.end(:path) - 1]).
|
115
|
+
# Throws :error with a String message when an error is encountered.
|
116
|
+
#
|
117
|
+
# Returns nothing.
|
118
|
+
# Raises RuntimeError if the regex does not have the required named captures.
|
45
119
|
def self.import(regex, &handler)
|
120
|
+
validate_regex!(:import, regex, IMPORT_REGEX_CAPTURES)
|
121
|
+
|
46
122
|
parse(:import, regex, &handler)
|
47
123
|
end
|
48
124
|
|
49
|
-
|
50
|
-
#
|
125
|
+
# Internal: Configure reference handling.
|
126
|
+
#
|
127
|
+
# regex - Regex for finding references. Must contain named components :quote (' or "), :path (the path
|
128
|
+
# of the asset being referenced), :quoted (everything inside the quotes), :entity ('path' or
|
129
|
+
# 'content'), and :format (see Asset::REFERENCE_FORMATS).
|
130
|
+
# handler - Proc for special handling of references (optional), which is passed four keyword arguments:
|
131
|
+
#
|
132
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
133
|
+
# match: - MatchData object from the match against the regex.
|
134
|
+
# asset: - Asset object of the asset being referenced.
|
135
|
+
# format: - String format of the reference (see Asset::REFERENCE_FORMATS).
|
51
136
|
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
# * +parse_data:+ - Hash for storing data across calls to this and other parse handlers.
|
59
|
-
# * +match:+ - MatchData object from the match against +regex+.
|
60
|
-
# * +asset:+ - Asset object of the asset being referenced.
|
61
|
-
# * +format:+ - Format of the reference (see Asset::REFERENCE_FORMATS).
|
62
|
-
# Return value is used as the substitution for the reference, with optional second and third
|
63
|
-
# values as integers representing the start and end indexes of the match to replace.
|
137
|
+
# Returns nil for default behavior, or a String which is used as the substitution for the text
|
138
|
+
# matched by the regex. The portion of the matched text that is replaced can optionally be
|
139
|
+
# changed by returning second and third Integer values specifying start and end indexes
|
140
|
+
# within the regex match (e.g. ['my substitution', match.begin(:path) + 1,
|
141
|
+
# match.end(:path) - 1]).
|
142
|
+
# Throws :error with a String message when an error is encountered.
|
64
143
|
#
|
144
|
+
# Returns nothing.
|
145
|
+
# Raises RuntimeError if the regex does not have the required named captures.
|
65
146
|
def self.reference(regex, &handler)
|
147
|
+
validate_regex!(:reference, regex, REFERENCE_REGEX_CAPTURES)
|
148
|
+
|
66
149
|
parse(:reference, regex, &handler)
|
67
150
|
end
|
68
151
|
|
69
|
-
|
70
|
-
#
|
152
|
+
# Internal: Configure a parser.
|
153
|
+
#
|
154
|
+
# kind - Symbol name to describe what is being parsed. Should be unique across all parse calls. When
|
155
|
+
# subclassing another Delegate, this can be used to override the parent class's regex and
|
156
|
+
# handler.
|
157
|
+
# regex - Regexp to match against.
|
158
|
+
# handler - Proc for handling matches of the regex, which is passed two keyword arguments:
|
159
|
+
#
|
160
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
161
|
+
# match: - MatchData object from the match against the regex.
|
71
162
|
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
# * +parse_data:+ - Hash for storing data across calls to this and other parse handlers.
|
78
|
-
# * +match:+ - MatchData object from the match against +regex+.
|
79
|
-
# Return value is used as the substitution for the reference, with optional second and third
|
80
|
-
# values as integers representing the start and end indexes of the match to replace.
|
163
|
+
# Returns a String which is used as the substitution for the text matched by the regex. The
|
164
|
+
# portion of the matched text that is replaced can optionally be changed by returning second
|
165
|
+
# and third Integer values specifying start and end indexes within the regex match (e.g.
|
166
|
+
# ['my substitution', match.begin(:path) + 1, match.end(:path) - 1]).
|
167
|
+
# Throws :error with a String message when an error is encountered.
|
81
168
|
#
|
169
|
+
# Returns nothing.
|
82
170
|
def self.parse(kind, regex, &handler)
|
83
|
-
@parsers
|
171
|
+
@parsers ||= parsers&.dup || {}
|
84
172
|
@parsers[kind] = [regex, handler]
|
85
173
|
end
|
86
174
|
|
87
|
-
|
88
|
-
# Configures compilation.
|
175
|
+
# Internal: Configure compilation.
|
89
176
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
# * +parse_data:+ - Hash of data collected during parsing.
|
95
|
-
# * +path:+ - Path of the asset being compiled.
|
96
|
-
# * +own_content:+ - Asset's own content (without imports).
|
97
|
-
# Asset's own content is set to the value returned.
|
177
|
+
# lib: - String name of a library to require that is needed by the handler (optional).
|
178
|
+
# delegate: - Delegate class to be used after the asset is compiled (optional).
|
179
|
+
# handler - Proc to call that will return the compiled version of the asset's own content, which is
|
180
|
+
# passed three keyword arguments:
|
98
181
|
#
|
182
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
183
|
+
# path: - String path of the asset.
|
184
|
+
# own_content: - String own content (without imports) of the asset.
|
185
|
+
#
|
186
|
+
# Returns a String which is used as a replacement for the asset's own content.
|
187
|
+
# Raises StandardError when an error is encountered.
|
188
|
+
#
|
189
|
+
# Returns nothing.
|
99
190
|
def self.compile(lib: nil, delegate: nil, &handler)
|
100
191
|
@compile_lib = lib
|
101
192
|
@compile_delegate = delegate
|
102
193
|
@compile_handler = handler
|
103
194
|
end
|
104
195
|
|
105
|
-
|
106
|
-
#
|
196
|
+
# Internal: Configure finalize behavior.
|
197
|
+
#
|
198
|
+
# lib: - String name of a library to require that is needed by the handler (optional).
|
199
|
+
# handler - Proc to call that will return the finalized version of the asset's compiled content (with
|
200
|
+
# imports prepended), which is passed three keyword arguments:
|
201
|
+
#
|
202
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
203
|
+
# path: - String path of the asset.
|
204
|
+
# content: - String content of the compiled asset (with imports prepended).
|
107
205
|
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
# imports prepended). Passed three keyword arguments when called:
|
111
|
-
# * +parse_data:+ - Hash of data collected during parsing.
|
112
|
-
# * +path:+ - Path of the asset being finalized.
|
113
|
-
# * +content:+ - Asset's compiled content (with imports prepended).
|
114
|
-
# Asset's content is set to the value returned.
|
206
|
+
# Returns a String which is used as a replacement for the asset's content.
|
207
|
+
# Raises StandardError when an error is encountered.
|
115
208
|
#
|
209
|
+
# Returns nothing.
|
116
210
|
def self.finalize(lib: nil, &handler)
|
117
211
|
@finalize_lib = lib
|
118
212
|
@finalize_handler = handler
|
119
213
|
end
|
120
214
|
|
121
|
-
|
122
|
-
# Configures minification.
|
215
|
+
# Internal: Configure minification.
|
123
216
|
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
130
|
-
#
|
217
|
+
# lib: - String name of a library to require that is needed by the handler (optional).
|
218
|
+
# handler - Proc to call that will return the minified version of the asset's finalized content, which
|
219
|
+
# is passed three keyword arguments:
|
220
|
+
#
|
221
|
+
# parse_data: - Hash for storing arbitrary data across calls to this and other handlers.
|
222
|
+
# path: - String oath of the asset being minified.
|
223
|
+
# content: - string content of the finalized asset.
|
224
|
+
#
|
225
|
+
# Returns a String which is used as the minified version of the asset's content.
|
226
|
+
# Raises StandardError when an error is encountered.
|
131
227
|
#
|
132
228
|
def self.minify(lib: nil, &handler)
|
133
229
|
@minify_lib = lib
|
134
230
|
@minify_handler = handler
|
135
231
|
end
|
136
232
|
|
137
|
-
|
138
|
-
# Throws +:error+ with a message.
|
233
|
+
# Internal: Throw :error with a message.
|
139
234
|
#
|
140
|
-
#
|
235
|
+
# message - String message to include with the throw.
|
141
236
|
#
|
237
|
+
# Returns nothing.
|
142
238
|
def self.error(message)
|
143
239
|
throw(:error, message)
|
144
240
|
end
|
145
241
|
|
146
|
-
|
147
|
-
# Returns regex for a parser.
|
242
|
+
# Internal: Get a parser's regex.
|
148
243
|
#
|
149
|
-
#
|
244
|
+
# kind - Symbol name of the parser.
|
150
245
|
#
|
246
|
+
# Returns the Regexp.
|
151
247
|
def self.regex(kind)
|
152
248
|
parsers[kind]&.first
|
153
249
|
end
|
154
250
|
|
155
|
-
|
156
|
-
# Returns handler for a parser.
|
251
|
+
# Internal: Get a parser's handler.
|
157
252
|
#
|
158
|
-
#
|
253
|
+
# kind - Symbol name of the parser.
|
159
254
|
#
|
255
|
+
# Returns the Proc handler.
|
160
256
|
def self.handler(kind)
|
161
257
|
parsers[kind]&.last
|
162
258
|
end
|
163
259
|
|
164
|
-
|
165
|
-
# Iterates over each parser and yields its kind, regex, and handler.
|
260
|
+
# Internal: Raise an exception if a regex does not have the required named captures.
|
166
261
|
#
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
262
|
+
# name - Symbol name of the regex (used in the exception message).
|
263
|
+
# regex - Regexp to validate.
|
264
|
+
# required_captures - Array of String required named captures.
|
265
|
+
#
|
266
|
+
# Returns nothing.
|
267
|
+
# Raises RuntimeError if the regex does not have the required named captures.
|
268
|
+
def self.validate_regex!(name, regex, required_captures)
|
269
|
+
missing = (required_captures - regex.named_captures.keys)
|
270
|
+
|
271
|
+
return if missing.empty?
|
272
|
+
|
273
|
+
name = name.to_s.capitalize
|
274
|
+
plural = missing.size != 1
|
275
|
+
missing_str = missing.join(', ')
|
276
|
+
|
277
|
+
raise("#{name} regex is missing required named capture#{'s' if plural}: #{missing_str}")
|
171
278
|
end
|
172
279
|
end
|
173
280
|
end
|
@@ -4,6 +4,7 @@ require_relative('../asset')
|
|
4
4
|
require_relative('../delegate')
|
5
5
|
|
6
6
|
class Darkroom
|
7
|
+
# Delegate for handling HTML-specific asset processing.
|
7
8
|
class HTMLDelegate < Delegate
|
8
9
|
REFERENCE_REGEX = /
|
9
10
|
<(?<tag>a|area|audio|base|embed|iframe|img|input|link|script|source|track|video)\s+[^>]*
|
@@ -26,8 +27,8 @@ class Darkroom
|
|
26
27
|
if asset.content_type == 'text/javascript'
|
27
28
|
offset = match.begin(0)
|
28
29
|
|
29
|
-
"#{match[0][0..(match.begin(:attr) - 2 - offset)]}"\
|
30
|
-
"#{match[0][(match.end(:quoted) + match[:quote].size - offset)..(match.end(0) - offset)]}"\
|
30
|
+
"#{match[0][0..(match.begin(:attr) - 2 - offset)]}" \
|
31
|
+
"#{match[0][(match.end(:quoted) + match[:quote].size - offset)..(match.end(0) - offset)]}" \
|
31
32
|
"#{asset.content}"
|
32
33
|
else
|
33
34
|
error('Asset content type must be text/javascript')
|
@@ -46,7 +47,7 @@ class Darkroom
|
|
46
47
|
|
47
48
|
content = asset.content.dup
|
48
49
|
content.gsub!('#', '%23')
|
49
|
-
content.gsub!(quote, quote == '"' ?
|
50
|
+
content.gsub!(quote, quote == '"' ? '"' : ''')
|
50
51
|
|
51
52
|
content
|
52
53
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative('
|
4
|
-
require_relative('
|
3
|
+
require_relative('html_delegate')
|
4
|
+
require_relative('javascript_delegate')
|
5
5
|
|
6
6
|
class Darkroom
|
7
|
+
# Delegate for handling HTX-specific asset processing.
|
7
8
|
class HTXDelegate < HTMLDelegate
|
8
9
|
compile(lib: 'htx', delegate: JavaScriptDelegate) do |parse_data:, path:, own_content:|
|
9
10
|
module_supported = false
|
@@ -5,13 +5,14 @@ require_relative('../asset')
|
|
5
5
|
require_relative('../delegate')
|
6
6
|
|
7
7
|
class Darkroom
|
8
|
+
# Delegate for handling JavaScript-specific asset processing.
|
8
9
|
class JavaScriptDelegate < Delegate
|
9
10
|
IDENTIFIER_REGEX = /[_$a-zA-Z][_$a-zA-Z0-9]*/.freeze
|
10
11
|
COMMA_REGEX = /,/.freeze
|
11
12
|
QUOTED_REGEX = /
|
12
13
|
(?<quoted>
|
13
|
-
(?<quote>['"])(
|
14
|
-
(?<=[^\\])\\(
|
14
|
+
(?<quote>['"])(?:
|
15
|
+
(?<=[^\\])\\(?:\\\\)*\k<quote> |
|
15
16
|
(?!\k<quote>).
|
16
17
|
)*\k<quote>
|
17
18
|
)
|
@@ -131,14 +132,14 @@ class Darkroom
|
|
131
132
|
end while items.any? { |i| i.first == mod }
|
132
133
|
|
133
134
|
own_content.prepend(
|
134
|
-
"let #{items.map(&:first).join(', ')}; "\
|
135
|
-
"$import('#{import_path}', "\
|
135
|
+
"let #{items.map(&:first).join(', ')}; " \
|
136
|
+
"$import('#{import_path}', " \
|
136
137
|
"#{mod} => #{prefix}#{items.map { |(i, e)| "#{i} = #{mod}#{e}" }.join(', ')}#{suffix})\n"
|
137
138
|
)
|
138
139
|
end
|
139
140
|
|
140
141
|
own_content.prepend("['#{path}', $import => {\n\n")
|
141
|
-
own_content << <<~
|
142
|
+
own_content << <<~JS
|
142
143
|
|
143
144
|
return Object.seal({#{
|
144
145
|
if parse_data[:exports] && !parse_data[:exports].empty?
|
@@ -147,7 +148,7 @@ class Darkroom
|
|
147
148
|
}})
|
148
149
|
|
149
150
|
}],
|
150
|
-
|
151
|
+
JS
|
151
152
|
end
|
152
153
|
|
153
154
|
########################################################################################################
|
@@ -158,7 +159,7 @@ class Darkroom
|
|
158
159
|
next unless Darkroom.javascript_iife
|
159
160
|
|
160
161
|
(content.frozen? ? content.dup : content).prepend(
|
161
|
-
<<~
|
162
|
+
<<~JS
|
162
163
|
((...bundle) => {
|
163
164
|
const modules = {}
|
164
165
|
const setters = []
|
@@ -172,7 +173,7 @@ class Darkroom
|
|
172
173
|
setter(modules[name])
|
173
174
|
})(
|
174
175
|
|
175
|
-
|
176
|
+
JS
|
176
177
|
) << "\n)\n"
|
177
178
|
end
|
178
179
|
|
@@ -1,33 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Darkroom
|
4
|
-
##
|
5
4
|
# General error class used for errors encountered while processing an asset.
|
6
|
-
#
|
7
5
|
class AssetError < StandardError
|
8
6
|
attr_reader(:detail, :source_path, :source_line_num)
|
9
7
|
|
10
|
-
|
11
|
-
# Creates a new instance.
|
12
|
-
#
|
13
|
-
# [message] Description of the error.
|
14
|
-
# [detail] Additional detail about the error.
|
15
|
-
# [source_path] Path of the asset that contains the error.
|
16
|
-
# [source_line_num] Line number in the asset where the error is located.
|
8
|
+
# Public: Create a new instance.
|
17
9
|
#
|
10
|
+
# message - String description of the error.
|
11
|
+
# detail - String additional error detail.
|
12
|
+
# source_path - String path of the asset that contains the error.
|
13
|
+
# source_line_num - Integer line number in the asset file where the error was located.
|
18
14
|
def initialize(message, detail, source_path = nil, source_line_num = nil)
|
19
|
-
super(message)
|
15
|
+
super("#{"#{source_path}:#{source_line_num || '?'}: " if source_path}#{message}: #{detail}")
|
20
16
|
|
21
17
|
@detail = detail
|
22
18
|
@source_path = source_path
|
23
19
|
@source_line_num = source_line_num
|
24
20
|
end
|
25
|
-
|
26
|
-
##
|
27
|
-
# Returns a string representation of the error.
|
28
|
-
#
|
29
|
-
def to_s
|
30
|
-
"#{"#{@source_path}:#{@source_line_num || '?'}: " if @source_path}#{super}: #{@detail}"
|
31
|
-
end
|
32
21
|
end
|
33
22
|
end
|
@@ -3,18 +3,14 @@
|
|
3
3
|
require_relative('asset_error')
|
4
4
|
|
5
5
|
class Darkroom
|
6
|
-
##
|
7
6
|
# Error class used when an asset requested explicitly or specified as a dependency of another doesn't
|
8
7
|
# exist.
|
9
|
-
#
|
10
8
|
class AssetNotFoundError < AssetError
|
11
|
-
|
12
|
-
# Creates a new instance.
|
13
|
-
#
|
14
|
-
# [path] Path of asset that doesn't exist.
|
15
|
-
# [source_path] Path of the asset that contains the error.
|
16
|
-
# [source_line_num] Line number in the asset where the error is located.
|
9
|
+
# Public: Create a new instance.
|
17
10
|
#
|
11
|
+
# path - String path of asset that doesn't exist.
|
12
|
+
# source_path - String path of the asset that contains the error.
|
13
|
+
# source_line_num - Integer line number in the asset file where the error is located.
|
18
14
|
def initialize(path, source_path = nil, source_line_num = nil)
|
19
15
|
super('Asset not found', path, source_path, source_line_num)
|
20
16
|
end
|
@@ -3,17 +3,13 @@
|
|
3
3
|
require_relative('asset_error')
|
4
4
|
|
5
5
|
class Darkroom
|
6
|
-
##
|
7
6
|
# Error class used when an asset reference results in a circular reference chain.
|
8
|
-
#
|
9
7
|
class CircularReferenceError < AssetError
|
10
|
-
|
11
|
-
# Creates a new instance.
|
12
|
-
#
|
13
|
-
# [snippet] Snippet showing the reference.
|
14
|
-
# [source_path] Path of the asset that contains the error.
|
15
|
-
# [source_line_num] Line number in the asset where the error is located.
|
8
|
+
# Public: Create a new instance.
|
16
9
|
#
|
10
|
+
# snippet - String snippet showing the reference.
|
11
|
+
# source_path - String path of the asset that contains the error.
|
12
|
+
# source_line_num - Integer line number in the asset file where the error is located.
|
17
13
|
def initialize(snippet, source_path, source_line_num)
|
18
14
|
super('Reference would result in a circular reference chain', snippet, source_path, source_line_num)
|
19
15
|
end
|
@@ -1,30 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Darkroom
|
4
|
-
|
5
|
-
# Error class used when an asset exists under multiple load paths.
|
6
|
-
#
|
4
|
+
# Error class used when the same asset path exists under multiple load paths.
|
7
5
|
class DuplicateAssetError < StandardError
|
8
6
|
attr_reader(:path, :first_load_path, :second_load_path)
|
9
7
|
|
10
|
-
|
11
|
-
# Creates a new instance.
|
12
|
-
#
|
13
|
-
# [path] Path of the asset that exists under multiple load paths.
|
14
|
-
# [first_load_path] Load path where the asset was first found.
|
15
|
-
# [second_load_path] Load path where the asset was subsequently found.
|
8
|
+
# Public: Create a new instance.
|
16
9
|
#
|
10
|
+
# path - String path of the asset that exists under multiple load paths.
|
11
|
+
# first_load_path - String load path where the asset was first found.
|
12
|
+
# second_load_path - String load path where the asset was subsequently found.
|
17
13
|
def initialize(path, first_load_path, second_load_path)
|
14
|
+
super("Asset file exists in both #{first_load_path} and #{second_load_path}: #{path}")
|
15
|
+
|
18
16
|
@path = path
|
19
17
|
@first_load_path = first_load_path
|
20
18
|
@second_load_path = second_load_path
|
21
19
|
end
|
22
|
-
|
23
|
-
##
|
24
|
-
# Returns a string representation of the error.
|
25
|
-
#
|
26
|
-
def to_s
|
27
|
-
"Asset file exists in both #{@first_load_path} and #{@second_load_path}: #{@path}"
|
28
|
-
end
|
29
20
|
end
|
30
21
|
end
|
@@ -3,28 +3,19 @@
|
|
3
3
|
require_relative('../asset')
|
4
4
|
|
5
5
|
class Darkroom
|
6
|
-
##
|
7
6
|
# Error class used when an asset's path contains one or more invalid characters.
|
8
|
-
#
|
9
7
|
class InvalidPathError < StandardError
|
10
8
|
attr_reader(:path, :index)
|
11
9
|
|
12
|
-
|
13
|
-
# Creates a new instance.
|
14
|
-
#
|
15
|
-
# [path] Path of the asset with the invalid character(s).
|
16
|
-
# [index] Position of the first bad character in the path.
|
10
|
+
# Public: Create a new instance.
|
17
11
|
#
|
12
|
+
# path - Path of the asset with the invalid character(s).
|
13
|
+
# index - Position of the first bad character in the path.
|
18
14
|
def initialize(path, index)
|
15
|
+
super("Asset path contains one or more invalid characters (#{Asset::DISALLOWED_PATH_CHARS}): #{path}")
|
16
|
+
|
19
17
|
@path = path
|
20
18
|
@index = index
|
21
19
|
end
|
22
|
-
|
23
|
-
##
|
24
|
-
# Returns a string representation of the error.
|
25
|
-
#
|
26
|
-
def to_s
|
27
|
-
"Asset path contains one or more invalid characters (#{Asset::DISALLOWED_PATH_CHARS}): #{@path}"
|
28
|
-
end
|
29
20
|
end
|
30
21
|
end
|