klenod-build 0.0.15 → 0.0.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abf589452fadde26fe16d0bbc326e0161e8ed8a719ea516e12e286ef8e1609aa
4
- data.tar.gz: 9f54e971b5dc88cd07348be0d96e9885928db10c64b4228bfb64e350b202f669
3
+ metadata.gz: d24b06569546f0b32ba9aebee8e17b989b9cd67198714952404b818dbae7d425
4
+ data.tar.gz: c61a9de1db41a5258cf2f9ae742ab9256c69fa06df0ef799035db39df89630f2
5
5
  SHA512:
6
- metadata.gz: af84591cca45a914ffbf087f308eea54d264cb14a0e03d6e60732a806d5e4cf44b00d291679b1f3dfe1f6d39f58bda043ff6b1de625b9d904667d2db5f8a6c07
7
- data.tar.gz: 8f5fbdc8411f73fee7b7f6b86f803d7e04e588db97dc3d4d5019b7bf08cc63a1d73b05d82a97e74135fc2370be072b00524b7df3ac301c0ed2f4eb025c4352d7
6
+ metadata.gz: cb64e39cf3daedff82d30572bb92c136a3091118a843aa7e9180c40dd83e5e074be8a017867744fb4921a6a092eab366095a510639bacf8aba37a2859c013dd3
7
+ data.tar.gz: 9d9ad93cbfc302d0db9e4bddca0cb333929fe62480791bfadef0848bc09c4459fd6ed5145fa93f444ed077f1f7e63d172900a7065f81a6e0e24d7f0cf71c9eed
@@ -374,6 +374,7 @@ module Klenod
374
374
  transform = loaded_source.transform || transform_module_source(module_id, source)
375
375
  resolved_dependencies = resolve_transform_dependencies(module_id, transform)
376
376
  dependency_records = load_eager_dependency_records(resolved_dependencies)
377
+ assert_eager_import_names!(module_id, source, resolved_dependencies, dependency_records)
377
378
  transform = finalize_transform_result(module_id, transform, resolved_dependencies, dependency_records)
378
379
  assert_supported_transform!(module_id, source, transform)
379
380
  assert_generated_ruby_parses!(module_id, transform)
@@ -430,6 +431,7 @@ module Klenod
430
431
  transform = loaded_source.transform || transform_module_source(module_id, source)
431
432
  resolved_dependencies = resolve_transform_dependencies(module_id, transform)
432
433
  dependency_records = collect_eager_dependency_records(resolved_dependencies)
434
+ assert_eager_import_names!(module_id, source, resolved_dependencies, dependency_records)
433
435
  transform = finalize_transform_result(module_id, transform, resolved_dependencies, dependency_records)
434
436
  assert_supported_transform!(module_id, source, transform)
435
437
  assert_generated_ruby_parses!(module_id, transform)
@@ -462,7 +464,7 @@ module Klenod
462
464
  Runtime::Mod.new(
463
465
  module_id.to_s,
464
466
  record.transformed_source,
465
- imports: imports_for(record.resolved_dependencies, dependency_records),
467
+ imports: imports_for(module_id, record.source, record.resolved_dependencies, dependency_records),
466
468
  source_map: record.source_map,
467
469
  version: record.version,
468
470
  eval_path: eval_path_for(module_id),
@@ -659,7 +661,7 @@ module Klenod
659
661
  Runtime::Mod.new(
660
662
  module_id.to_s,
661
663
  transform.code,
662
- imports: imports_for(resolved_dependencies, dependency_records),
664
+ imports: imports_for(module_id, source, resolved_dependencies, dependency_records),
663
665
  source_map: transform.source_map,
664
666
  version: cached ? cached.version + 1 : 0,
665
667
  eval_path: eval_path_for(module_id),
@@ -690,7 +692,7 @@ module Klenod
690
692
  source_dir.join(module_id.path).to_s
691
693
  end
692
694
 
693
- def imports_for(resolved_dependencies, dependency_records)
695
+ def imports_for(module_id, source, resolved_dependencies, dependency_records)
694
696
  resolved_dependencies.to_h do |resolved_dependency|
695
697
  value =
696
698
  if resolved_dependency.dependency.eager
@@ -702,6 +704,7 @@ module Klenod
702
704
  evaluate_module(resolved_dependency.module_id)
703
705
  record = @records.fetch(resolved_dependency.module_id)
704
706
  raise_failed_module!(record)
707
+ assert_import_name!(module_id, source, resolved_dependency, record)
705
708
  import_value(resolved_dependency, record)
706
709
  end
707
710
  end
@@ -898,10 +901,9 @@ module Klenod
898
901
  @records.to_h do |module_id, record|
899
902
  imports =
900
903
  record.resolved_dependencies.to_h do |resolved_dependency|
901
- [
902
- resolved_dependency.dependency.id,
903
- runtime_import_spec(resolved_dependency, @records.fetch(resolved_dependency.module_id))
904
- ]
904
+ target = @records.fetch(resolved_dependency.module_id)
905
+ assert_import_name!(module_id, record.source, resolved_dependency, target)
906
+ [resolved_dependency.dependency.id, runtime_import_spec(resolved_dependency, target)]
905
907
  end
906
908
 
907
909
  [
@@ -990,6 +992,35 @@ module Klenod
990
992
  end
991
993
  end
992
994
 
995
+ # Lazy targets are not collected until bundle or call time, so only the
996
+ # eager imports can be checked while the importer is collected.
997
+ def assert_eager_import_names!(module_id, source, resolved_dependencies, dependency_records)
998
+ resolved_dependencies.each do |resolved_dependency|
999
+ next unless resolved_dependency.dependency.eager
1000
+
1001
+ record = dependency_records.fetch(resolved_dependency.dependency.id)
1002
+ assert_import_name!(module_id, source, resolved_dependency, record)
1003
+ end
1004
+ end
1005
+
1006
+ # A named import (`import("./x", :Bar)`) is checked against the constants
1007
+ # the target defines statically, recorded by the Ruby plugin as
1008
+ # metadata[:ruby_constants]. A missing Default is not an error: the
1009
+ # import then returns the Exports module.
1010
+ def assert_import_name!(module_id, source, resolved_dependency, record)
1011
+ name = resolved_dependency.dependency.metadata[:import_name]
1012
+ return unless name
1013
+
1014
+ constants = record.metadata[:ruby_constants]
1015
+ return if constants&.include?(name)
1016
+
1017
+ raise MissingExportError.new(
1018
+ MissingExportError::Report.new(resolved_dependency.dependency, record.id, name, constants),
1019
+ source: source,
1020
+ module_id: module_id
1021
+ )
1022
+ end
1023
+
993
1024
  def import_value(resolved_dependency, record)
994
1025
  raise_failed_module!(record)
995
1026
 
@@ -22,7 +22,7 @@ module Klenod
22
22
  return nil unless module_id.scheme == :virtual && module_id == CLASS_NAMES_MODULE_ID
23
23
 
24
24
  source = class_names_runtime_source
25
- LoadResult.new(source, nil, TransformResult.new(source, [], nil, [], [], {}))
25
+ LoadResult.new(source, nil, TransformResult.new(source, [], nil, [], [], {ruby_constants: [:Default]}))
26
26
  end
27
27
 
28
28
  def class_names_runtime_dependency(module_id)
@@ -12,7 +12,8 @@ module Klenod
12
12
  .create(
13
13
  specifier: HAML_HELPER_SPECIFIER,
14
14
  importer_id: module_id,
15
- kind: :haml_helper
15
+ kind: :haml_helper,
16
+ metadata: {import_name: :Default}
16
17
  )
17
18
  .with(id: "#{module_id}:haml_helper")
18
19
  end
@@ -549,6 +549,9 @@ module Klenod
549
549
  source_column_offset = source.lines.fetch(node.line, "").match(/\A\s*/).to_s.length
550
550
  text = import_rewriter.call(text, source_line_offset: node.line, source_column_offset: source_column_offset)
551
551
  end
552
+ unless builder.statements(text).node?
553
+ builder.ruby_parse_error(text, line_no: node.line + 1, context: "Could not parse Ruby filter")
554
+ end
552
555
  heredoc_body_lines = ruby_heredoc_body_lines(text)
553
556
  source = +""
554
557
  text.each_line.with_index(node.line + 1) do |line, line_no|
@@ -625,12 +628,15 @@ module Klenod
625
628
 
626
629
  def dynamic_attributes(node, builder:, props:)
627
630
  dynamic_attributes = node.value.fetch(:dynamic_attributes)
628
- sources = [dynamic_attributes.new, dynamic_attributes.old].compact
631
+ sources = [
632
+ [dynamic_attributes.new, true],
633
+ [dynamic_attributes.old, false]
634
+ ].reject { |source, _parenthesized| source.nil? }
629
635
  return {} if sources.empty?
630
636
 
631
637
  measure_compile(:haml_compile_dynamic_attributes) do
632
638
  dynamic = {}
633
- sources.each do |source|
639
+ sources.each do |source, parenthesized|
634
640
  source = builder.line_rewritten_source(source, node.line)
635
641
  simple = simple_dynamic_attributes(source, builder: builder) unless @event_handler
636
642
  if simple
@@ -655,7 +661,7 @@ module Klenod
655
661
  end
656
662
 
657
663
  key = attribute_key(assoc.key, builder: builder)
658
- value = event_handler_value(key, assoc.value, builder: builder) || attribute_value(assoc, builder: builder)
664
+ value = event_handler_value(key, assoc.value, parenthesized: parenthesized, builder: builder) || attribute_value(assoc, builder: builder)
659
665
  dynamic[key] = value
660
666
  props[key] = value
661
667
  end
@@ -784,14 +790,19 @@ module Klenod
784
790
  builder.ruby_parse_error(source, line_no: assoc.key.location&.start_line, context: "Could not parse Haml dynamic attributes")
785
791
  end
786
792
 
787
- def event_handler_value(key, value, builder:)
788
- return unless @event_handler && key.to_s.match?(/\Aon[a-z]/)
793
+ def event_handler_value(key, value, parenthesized:, builder:)
794
+ normalized_key = key.to_s.tr("-", "_")
795
+ return unless normalized_key.match?(/\Aon(?:[a-z]|_[a-z])/)
789
796
  return unless value
790
797
 
791
798
  method_name = builder.fragment(value).source
792
799
  return unless method_name.match?(/\A[a-zA-Z_]\w*[!?=]?\z/)
793
800
 
794
- builder.expression("#{@event_handler}.callback(self, :#{method_name})")
801
+ if @event_handler
802
+ builder.expression("#{@event_handler}.callback(self, :#{method_name})")
803
+ elsif parenthesized
804
+ builder.symbol(method_name)
805
+ end
795
806
  end
796
807
 
797
808
  def omitted_attribute_value_name(node)
@@ -97,7 +97,9 @@ module Klenod
97
97
 
98
98
  return nil unless module_id.scheme == :virtual && module_id == HAML_HELPER_MODULE_ID
99
99
 
100
- LoadResult.new(haml_helper_source, nil, TransformResult.new(haml_helper_source, [], nil, [], [], {}))
100
+ # Loaded with a ready transform, so the Ruby plugin never scans it: declare
101
+ # the Default export it defines.
102
+ LoadResult.new(haml_helper_source, nil, TransformResult.new(haml_helper_source, [], nil, [], [], {ruby_constants: [:Default]}))
101
103
  end
102
104
 
103
105
  def transform(module_id, code, context)
@@ -136,7 +138,7 @@ module Klenod
136
138
  specifier: "/markdown-components",
137
139
  importer_id: module_id,
138
140
  kind: :markdown_components,
139
- metadata: {optional: true}
141
+ metadata: {optional: true, import_name: :Default}
140
142
  )
141
143
  .with(id: "#{module_id}:markdown_components")
142
144
  dependencies << markdown_components_dependency
@@ -205,11 +207,11 @@ module Klenod
205
207
  styles_source: styles_source,
206
208
  translations_source: translations_source,
207
209
  i18n_source: i18n_source_for(builder),
208
- haml_helper_source: haml_helper_dependency && builder.constant_assignment("HamlHelper", "#{builder.import_call(haml_helper_dependency.id).source}::Default"),
210
+ haml_helper_source: haml_helper_dependency && builder.constant_assignment("HamlHelper", builder.import_call(haml_helper_dependency.id).source),
209
211
  styleable: !style_dependencies.empty?,
210
212
  profiler: context.profiler,
211
213
  import_rewriter: import_rewriter,
212
- markdown_components_source: markdown_components_dependency ? "__klenod_import__(#{markdown_components_dependency.id.inspect})::Default" : "{}",
214
+ markdown_components_source: markdown_components_dependency ? "__klenod_import__(#{markdown_components_dependency.id.inspect})" : "{}",
213
215
  variables: @variables,
214
216
  event_handler: @event_handler,
215
217
  cache_static_subtrees: @cache_static_subtrees
@@ -246,19 +248,26 @@ module Klenod
246
248
  def import_value(resolved_dependency, record, context)
247
249
  styles_import = class_names_runtime_import_value(resolved_dependency, record, context)
248
250
  return styles_import if styles_import
249
- return nil unless record.id.extname == ".haml"
251
+ return nil unless default_export?(record)
250
252
 
251
- context.mods.fetch(record.id).const_get(:Exports)::Default
253
+ context.mods.fetch(record.id).const_get(:Exports).const_get(:Default, false)
252
254
  end
253
255
 
254
256
  def runtime_import_value(resolved_dependency, record, _context)
255
257
  styles_import = class_names_runtime_runtime_import_value(resolved_dependency, record)
256
258
  return styles_import if styles_import
257
- return Runtime::DefaultImport.new(:Default) if record.id.extname == ".haml"
259
+ return Runtime::DefaultImport.new(:Default) if default_export?(record)
258
260
 
259
261
  super
260
262
  end
261
263
 
264
+ # Components and the helper module both export Default. The helper is
265
+ # unwrapped here as well as by the Ruby plugin, so a context built
266
+ # without the Ruby plugin still renders.
267
+ def default_export?(record)
268
+ record.id.extname == ".haml" || record.id == HAML_HELPER_MODULE_ID
269
+ end
270
+
262
271
  def invalidate_module_ids(paths, context)
263
272
  paths
264
273
  .filter_map { |path| companion_owner_module_id(path, context) }
@@ -22,7 +22,7 @@ module Klenod
22
22
 
23
23
  def compile(source, interpolate: false)
24
24
  source = protect_escaped_interpolation(source) if interpolate
25
- document = Kramdown::Document.new(source, input: "GFM")
25
+ document = Kramdown::Document.new(source, input: "GFM", hard_wrap: false)
26
26
  compile_children(document.root.children, interpolate: interpolate)
27
27
  end
28
28
 
@@ -168,13 +168,13 @@ module Klenod
168
168
  specifier: "/markdown-components",
169
169
  importer_id: module_id,
170
170
  kind: :markdown_components,
171
- metadata: {optional: true}
171
+ metadata: {optional: true, import_name: :Default}
172
172
  )
173
173
  .with(id: dependency_id(module_id))
174
174
  end
175
175
 
176
176
  def components_source_for(dependency)
177
- dependency ? "__klenod_import__(#{dependency.id.inspect})::Default" : "{}"
177
+ dependency ? "__klenod_import__(#{dependency.id.inspect})" : "{}"
178
178
  end
179
179
 
180
180
  def dependency_id(module_id)
@@ -53,7 +53,7 @@ module Klenod
53
53
  def transform(module_id, code, context)
54
54
  return TransformResult.identity(code) unless module_id.extname == ".rb"
55
55
 
56
- assert_parses!(module_id, code)
56
+ program = parse!(module_id, code)
57
57
 
58
58
  result =
59
59
  begin
@@ -68,21 +68,77 @@ module Klenod
68
68
  rescue SyntaxTree::Parser::ParseError => error
69
69
  raise ParseError.new(error, source: code, module_id: module_id)
70
70
  end
71
- TransformResult.new(result.code, result.dependencies, nil, [], result.watched_patterns, {})
71
+ TransformResult.new(
72
+ result.code,
73
+ result.dependencies,
74
+ nil,
75
+ [],
76
+ result.watched_patterns,
77
+ {ruby_constants: top_level_constants(program)}
78
+ )
79
+ end
80
+
81
+ # The value an importer receives: the requested constant, or Default
82
+ # when the module defines one. Nil keeps the Exports module.
83
+ def import_value(resolved_dependency, record, context)
84
+ name = import_constant_name(resolved_dependency, record)
85
+ return nil unless name
86
+
87
+ context.mods.fetch(record.id).const_get(:Exports).const_get(name, false)
88
+ end
89
+
90
+ def runtime_import_value(resolved_dependency, record, _context)
91
+ name = import_constant_name(resolved_dependency, record)
92
+ return nil unless name
93
+
94
+ Runtime::DefaultImport.new(name)
72
95
  end
73
96
 
74
97
  private
75
98
 
76
99
  # The rewriter only parses a file that contains an import it cannot
77
- # rewrite literally, so without this check most syntax errors would
100
+ # rewrite literally, so without this parse most syntax errors would
78
101
  # not surface until the module was evaluated -- and a production build
79
102
  # never evaluates application modules, so the bundle would ship
80
- # broken. Prism is the parser CRuby itself uses, and validating costs
81
- # well under a tenth of a millisecond per file.
82
- def assert_parses!(module_id, code)
83
- return if Prism.parse_success?(code)
103
+ # broken. Prism is the parser CRuby itself uses, and parsing costs
104
+ # well under a millisecond per file. The same tree tells us which
105
+ # constants the module exports.
106
+ def parse!(module_id, code)
107
+ result = Prism.parse(code)
108
+ raise ParseError.new(result, source: code, module_id: module_id) if result.failure?
109
+
110
+ result.value
111
+ end
112
+
113
+ # The constants a module defines at its top level, meaning directly
114
+ # on its Exports module. Only static definitions count: `const_set`,
115
+ # constants inside `if` or `begin`, `A::B = 1`, and `class ::A` are
116
+ # not exports.
117
+ def top_level_constants(program)
118
+ program.statements.body.flat_map { |node| defined_constant_names(node) }.uniq
119
+ end
120
+
121
+ def defined_constant_names(node)
122
+ case node
123
+ when Prism::ConstantWriteNode
124
+ [node.name]
125
+ when Prism::ClassNode, Prism::ModuleNode
126
+ node.constant_path.is_a?(Prism::ConstantReadNode) ? [node.constant_path.name] : []
127
+ when Prism::MultiWriteNode
128
+ [*node.lefts, *node.rights].grep(Prism::ConstantTargetNode).map(&:name)
129
+ else
130
+ []
131
+ end
132
+ end
133
+
134
+ # Records without a constant list were not transformed by this plugin
135
+ # and keep whatever value other plugins or the graph supply.
136
+ def import_constant_name(resolved_dependency, record)
137
+ constants = record.metadata[:ruby_constants]
138
+ return nil unless constants
84
139
 
85
- raise ParseError.new(Prism.parse(code), source: code, module_id: module_id)
140
+ name = resolved_dependency.dependency.metadata.fetch(:import_name, :Default)
141
+ constants.include?(name) ? name : nil
86
142
  end
87
143
  end
88
144
  end
@@ -11,7 +11,7 @@ module Klenod
11
11
  module Build
12
12
  class RubyImportRewriter
13
13
  ImportCall =
14
- Data.define(:specifier, :location, :dynamic, :method_name, :eager_override) do
14
+ Data.define(:specifier, :location, :dynamic, :method_name, :eager_override, :import_name) do
15
15
  def eager
16
16
  eager_override.nil? ? RubyImportRewriter::IMPORT_METHODS.fetch(method_name).fetch(:eager) : eager_override
17
17
  end
@@ -213,21 +213,33 @@ module Klenod
213
213
 
214
214
  first = unwrap_paren(parts.first)
215
215
  string_parts = first&.instance_variable_get(:@parts)
216
- literal =
217
- (parts.length == 1) &&
216
+ literal_specifier =
218
217
  first&.class&.name == "SyntaxTree::StringLiteral" &&
219
218
  string_parts&.length == 1 &&
220
219
  string_parts.first.instance_of?(::SyntaxTree::TStringContent)
220
+ import_name = (parts.length == 2) ? constant_symbol_value(parts.fetch(1)) : nil
221
+ literal = literal_specifier && (parts.length == 1 || !import_name.nil?)
221
222
 
222
223
  ImportCall.new(
223
224
  literal ? string_parts.first.value : nil,
224
225
  node.instance_variable_get(:@location),
225
226
  !literal,
226
227
  node.instance_variable_get(:@message).value,
227
- nil
228
+ nil,
229
+ literal ? import_name : nil
228
230
  )
229
231
  end
230
232
 
233
+ # The optional second argument of `import`: a symbol literal spelled like
234
+ # a constant, such as `:Bar`. Anything else (`:bar`, `:"Bar"`, a string,
235
+ # a variable) is reported as a dynamic import.
236
+ def constant_symbol_value(node)
237
+ return unless node.instance_of?(::SyntaxTree::SymbolLiteral)
238
+
239
+ value = node.instance_variable_get(:@value)
240
+ value.instance_of?(::SyntaxTree::Const) ? value.value.to_sym : nil
241
+ end
242
+
231
243
  def build_import_glob_from_parts(node, parts)
232
244
  first = unwrap_paren(parts.first)
233
245
  string_parts = first&.instance_variable_get(:@parts)
@@ -250,7 +262,8 @@ module Klenod
250
262
  node.instance_variable_get(:@location),
251
263
  !literal || !valid_options,
252
264
  node.instance_variable_get(:@message).value,
253
- eager
265
+ eager,
266
+ nil
254
267
  )
255
268
  end
256
269
 
@@ -304,20 +317,29 @@ module Klenod
304
317
  end
305
318
 
306
319
  def raise_dynamic_import!(call)
307
- expected = (call.method_name == "import_glob") ? "import_glob(\"...\")" : "import(\"...\")"
320
+ expected =
321
+ if call.method_name == "import_glob"
322
+ "import_glob(\"...\")"
323
+ else
324
+ "#{call.method_name}(\"...\") or #{call.method_name}(\"...\", :Constant)"
325
+ end
308
326
  raise DynamicImportError, "Only literal #{expected} calls are supported in #{@module_id}"
309
327
  end
310
328
 
311
329
  def build_dependency(call, dependency_index)
312
- Dependency
313
- .create(
314
- specifier: call.specifier,
315
- importer_id: @module_id,
316
- kind: @kind,
317
- loc: source_location(call.location)
318
- )
319
- .with(eager: call.eager)
320
- .with(id: "#{@module_id}:dependency:#{dependency_index}")
330
+ dependency =
331
+ Dependency
332
+ .create(
333
+ specifier: call.specifier,
334
+ importer_id: @module_id,
335
+ kind: @kind,
336
+ loc: source_location(call.location)
337
+ )
338
+ .with(eager: call.eager)
339
+ .with(id: "#{@module_id}:dependency:#{dependency_index}")
340
+ return dependency unless call.import_name
341
+
342
+ dependency.with(metadata: {import_name: call.import_name}.freeze)
321
343
  end
322
344
 
323
345
  def expand_glob_import(call, dependency_index)
@@ -110,6 +110,43 @@ module Klenod
110
110
  end
111
111
  end
112
112
 
113
+ # A named import (`import("./x", :Bar)`) of a constant the target module
114
+ # does not define at its top level.
115
+ #
116
+ # The check uses the constants the Ruby plugin recorded statically, so a
117
+ # typo fails while collecting, with an excerpt of the import, instead of
118
+ # surfacing as a NameError from inside module evaluation -- or, worse, at
119
+ # runtime, since a production build never evaluates application modules.
120
+ class MissingExportError < SourceError
121
+ Report = Data.define(:dependency, :target_id, :name, :constants)
122
+
123
+ def kind
124
+ "Missing export"
125
+ end
126
+
127
+ private
128
+
129
+ def location(report)
130
+ Location.new(
131
+ line: report.dependency.loc&.line,
132
+ column: report.dependency.loc&.column,
133
+ detail: "#{report.target_id} does not define #{report.name}",
134
+ hints: [hint_for(report)]
135
+ )
136
+ end
137
+
138
+ def hint_for(report)
139
+ case report.constants
140
+ when nil
141
+ "Named imports need a Ruby module; #{report.target_id} is not one"
142
+ when []
143
+ "#{report.target_id} defines no top-level constants; import it without a name to get its Exports module"
144
+ else
145
+ "It defines #{report.constants.join(", ")}"
146
+ end
147
+ end
148
+ end
149
+
113
150
  # Ruby generated from another format that does not parse.
114
151
  #
115
152
  # This is a bug in the plugin that generated it rather than in anything the
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Klenod
4
4
  module Build
5
- VERSION = "0.0.15"
5
+ VERSION = "0.0.17"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: klenod-build
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrés Alin
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.0.15
18
+ version: 0.0.17
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.0.15
25
+ version: 0.0.17
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: async
28
28
  requirement: !ruby/object:Gem::Requirement