klenod-build 0.0.3 → 0.0.4

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: a3c7b7667bd38de08f8f31ebb2aecf97bcbde81d8e189dae356ac64651dd340b
4
- data.tar.gz: 55d2493b7d0047d97f9fb26766f7f6a1ed07867e1b1024c04d92dac3e04088e7
3
+ metadata.gz: 560774e128fafb845afbff51f556e3eb30d3a1b7d280b9fbdc7ac36b48c4b741
4
+ data.tar.gz: 559ce8134726f2fa31084811a9dcda01987a957c073370f5ac0595c8d7a3f703
5
5
  SHA512:
6
- metadata.gz: ce9d72bdc5127d334c72baa154e6d16997081c3e3a7f016074ec41088a16007b4c35c93d4bfb96a220fd950539b0e3496d7b3c9b33439c6777d5760cad2e2715
7
- data.tar.gz: 156d7564ff2e42c7831585790e906598510f5b27c74de16378f06870e792baa91f15101abe932212b6669a7a368d5b852c9f1be2cdeae5cc75ffa2f951eff46f
6
+ metadata.gz: 77cb936bd77e35262827d9903124f1b37cec73bb11db28c1a5e497d02a20d9283e989a46524c2f674b7c0f49734632e3da02b324a4988dbccbe3fe244e591921
7
+ data.tar.gz: eccc054b80b674a4f304fb6ec2abbdaf3bdf244576dc0f9bfd7b0d23b7b35ac77f5a47a061ad013cd9743295606b7ca3526a50e8f2dff48cc86ba13d4dac6fc2
@@ -161,6 +161,7 @@ module Klenod
161
161
  end
162
162
 
163
163
  class DynamicImportError < Error; end
164
+ class TestImportError < ResolveError; end
164
165
  class UnsupportedFileError < Error; end
165
166
 
166
167
  class ImportCycleError < Error
@@ -30,6 +30,7 @@ module Klenod
30
30
  DEFAULT_FACTORY = ComponentDefaults::DEFAULT_FACTORY
31
31
  DEFAULT_COMPONENT_CHILDREN = :eager
32
32
  COMPONENT_CHILDREN_MODES = %i[eager lazy].freeze
33
+ I18N_OPTIONS = %i[class constant].freeze
33
34
  HAML_HELPER_SPECIFIER = "virtual:klenod/haml_helper"
34
35
  HAML_HELPER_MODULE_ID = ModuleId.new("#{HAML_HELPER_SPECIFIER}.rb", nil)
35
36
  STATIC_CLASS_SOURCE_PATTERN = /^[ \t]*(?:%[-:\w]+)?(?:#[\w-]+)?\.[\w-]|[({][^)}\n]*\bclass\s*=/m
@@ -47,6 +48,7 @@ module Klenod
47
48
  DEFAULT_FACTORY = HamlPlugin::DEFAULT_FACTORY
48
49
  DEFAULT_COMPONENT_CHILDREN = HamlPlugin::DEFAULT_COMPONENT_CHILDREN
49
50
  COMPONENT_CHILDREN_MODES = HamlPlugin::COMPONENT_CHILDREN_MODES
51
+ I18N_OPTIONS = HamlPlugin::I18N_OPTIONS
50
52
  HAML_HELPER_SPECIFIER = HamlPlugin::HAML_HELPER_SPECIFIER
51
53
  HAML_HELPER_MODULE_ID = HamlPlugin::HAML_HELPER_MODULE_ID
52
54
  STATIC_CLASS_SOURCE_PATTERN = HamlPlugin::STATIC_CLASS_SOURCE_PATTERN
@@ -64,15 +66,14 @@ module Klenod
64
66
  factory: DEFAULT_FACTORY,
65
67
  component_children: DEFAULT_COMPONENT_CHILDREN,
66
68
  variables: nil,
67
- i18n_class: nil,
68
- i18n_constant: nil,
69
+ i18n: nil,
69
70
  cache_static_subtrees: false
70
71
  )
71
72
  @component_base_class = component_base_class
72
73
  @factory = factory
73
74
  @component_children = validate_component_children(component_children)
74
75
  @variables = validate_variables(variables)
75
- @i18n_class, @i18n_constant = validate_i18n_options(i18n_class, i18n_constant)
76
+ @i18n_class, @i18n_constant = validate_i18n_options(i18n)
76
77
  @cache_static_subtrees = cache_static_subtrees
77
78
  @transformer = Transformer.new
78
79
  end
@@ -296,15 +297,23 @@ module Klenod
296
297
  raise ArgumentError, "variables[#{kind.inspect}] must be a Ruby expression"
297
298
  end
298
299
 
299
- def validate_i18n_options(i18n_class, i18n_constant)
300
- return [nil, nil] if i18n_class.nil? && i18n_constant.nil?
301
- raise ArgumentError, "i18n_class must be configured when i18n_constant is configured" if i18n_class.nil?
300
+ def validate_i18n_options(i18n)
301
+ return [nil, nil] if i18n.nil?
302
+ raise ArgumentError, "i18n must be a Hash" unless i18n.is_a?(Hash)
302
303
 
303
- i18n_constant = (i18n_constant || "I18n").to_s
304
- raise ArgumentError, "i18n_constant must be a Ruby constant name" unless i18n_constant.match?(/\A[A-Z]\w*\z/)
304
+ unknown_options = i18n.keys - I18N_OPTIONS
305
+ unless unknown_options.empty?
306
+ raise ArgumentError, "i18n contains unknown options: #{unknown_options.map(&:inspect).join(", ")}"
307
+ end
308
+
309
+ i18n_class = i18n[:class]
310
+ raise ArgumentError, "i18n[:class] must be configured" if i18n_class.nil?
311
+
312
+ i18n_constant = (i18n[:constant] || "I18n").to_s
313
+ raise ArgumentError, "i18n[:constant] must be a Ruby constant name" unless i18n_constant.match?(/\A[A-Z]\w*\z/)
305
314
 
306
315
  [
307
- Transformer::ConstPath.parse(i18n_class, name: "i18n_class").to_s,
316
+ Transformer::ConstPath.parse(i18n_class, name: "i18n[:class]").to_s,
308
317
  i18n_constant
309
318
  ]
310
319
  end
@@ -191,6 +191,8 @@ module Klenod
191
191
  super(src:, width:, height:, content_type:, aspect_ratio:, variants: variants.dup.freeze)
192
192
  end
193
193
 
194
+ alias to_s src
195
+
194
196
  def srcset
195
197
  return nil if variants.empty?
196
198
 
@@ -205,7 +207,9 @@ module Klenod
205
207
  end
206
208
  end
207
209
 
208
- ImageVariant = Data.define(:src, :width, :height, :content_type, :aspect_ratio, :format, :descriptor, :quality)
210
+ ImageVariant = Data.define(:src, :width, :height, :content_type, :aspect_ratio, :format, :descriptor, :quality) do
211
+ alias to_s src
212
+ end
209
213
  RUBY
210
214
  end
211
215
 
@@ -94,7 +94,9 @@ module Klenod
94
94
 
95
95
  def svg_runtime_source
96
96
  <<~RUBY
97
- SvgMetadata = Data.define(:src, :width, :height, :content_type, :aspect_ratio)
97
+ SvgMetadata = Data.define(:src, :width, :height, :content_type, :aspect_ratio) do
98
+ alias to_s src
99
+ end
98
100
  RUBY
99
101
  end
100
102
 
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../errors"
4
+ require_relative "../module_id"
5
+ require_relative "../plugin"
6
+
7
+ module Klenod
8
+ module Build
9
+ module Plugins
10
+ module TestPlugin
11
+ def self.new(...)
12
+ Plugin.new(...)
13
+ end
14
+
15
+ class Plugin < Klenod::Build::Plugin
16
+ DEFAULT_PATTERN = "**/*.test.rb"
17
+
18
+ def initialize(pattern: DEFAULT_PATTERN)
19
+ @pattern = pattern.to_s
20
+ end
21
+
22
+ attr_reader :pattern
23
+
24
+ def discover(source_dir:)
25
+ root = Pathname.new(source_dir).expand_path
26
+
27
+ root
28
+ .glob(pattern)
29
+ .select(&:file?)
30
+ .map { |path| ModuleId.new(path.relative_path_from(root).to_s.tr("\\", "/"), nil) }
31
+ .sort_by(&:to_s)
32
+ end
33
+
34
+ def test_module_id?(module_id)
35
+ module_id.scheme == :app && File.fnmatch?(pattern, module_id.relative_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
36
+ end
37
+
38
+ def finalize(module_id, result, resolved_dependencies, _dependency_records, _context)
39
+ imported_test = resolved_dependencies.find { |dependency| test_module_id?(dependency.module_id) }
40
+ return result unless imported_test
41
+
42
+ error = TestImportError.new("Test file #{imported_test.module_id.path.inspect} cannot be imported")
43
+ raise error.with_resolution_context(dependency: imported_test.dependency, importer_id: module_id)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -17,6 +17,7 @@ module Klenod
17
17
  autoload :TomlPlugin, File.expand_path("plugins/data_plugin", __dir__)
18
18
  autoload :TextPlugin, File.expand_path("plugins/data_plugin", __dir__)
19
19
  autoload :RouterPlugin, File.expand_path("plugins/router_plugin", __dir__)
20
+ autoload :TestPlugin, File.expand_path("plugins/test_plugin", __dir__)
20
21
  end
21
22
  end
22
23
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Klenod
4
+ module Build
5
+ TestSelection = Data.define(:test_paths, :removed_test_paths) do
6
+ def empty?
7
+ test_paths.empty? && removed_test_paths.empty?
8
+ end
9
+ end
10
+
11
+ class TestSuite
12
+ def initialize(context:, plugin:)
13
+ @context = context
14
+ @plugin = plugin
15
+ @dependency_ids = {}
16
+ @failed_test_ids = Set.new
17
+ end
18
+
19
+ def collect
20
+ test_ids = discover
21
+ test_ids.each { |test_id| index(test_id) }
22
+ selection(test_ids)
23
+ end
24
+
25
+ def update(event)
26
+ previous_test_ids = @dependency_ids.keys.to_set
27
+ current_test_ids = discover.to_set
28
+ removed_test_ids = previous_test_ids - current_test_ids
29
+ added_test_ids = current_test_ids - previous_test_ids
30
+ affected_module_ids = update_module_ids(event)
31
+ affected_test_ids =
32
+ @dependency_ids.filter_map do |test_id, dependency_ids|
33
+ test_id if current_test_ids.include?(test_id) && dependency_ids.intersect?(affected_module_ids)
34
+ end
35
+
36
+ test_ids = (added_test_ids + affected_test_ids + @failed_test_ids).select { |test_id| current_test_ids.include?(test_id) }
37
+ removed_test_ids.each { |test_id| remove(test_id) }
38
+ test_ids.each { |test_id| index(test_id) }
39
+
40
+ selection(test_ids, removed_test_ids)
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :context, :plugin
46
+
47
+ def discover
48
+ plugin.discover(source_dir: context.graph.source_dir)
49
+ end
50
+
51
+ def index(test_id)
52
+ dependency_ids = Set[test_id]
53
+ @dependency_ids[test_id] = dependency_ids
54
+ collect_dependencies(test_id, dependency_ids)
55
+ @failed_test_ids.delete(test_id)
56
+ rescue
57
+ @failed_test_ids << test_id
58
+ end
59
+
60
+ def collect_dependencies(module_id, dependency_ids)
61
+ record = context.graph.records[module_id] || context.graph.collect_module(module_id)
62
+
63
+ record.resolved_dependencies.each do |dependency|
64
+ dependency_id = dependency.module_id
65
+ next unless dependency_ids.add?(dependency_id)
66
+
67
+ collect_dependencies(dependency_id, dependency_ids)
68
+ end
69
+ end
70
+
71
+ def remove(test_id)
72
+ @dependency_ids.delete(test_id)
73
+ @failed_test_ids.delete(test_id)
74
+ end
75
+
76
+ def update_module_ids(event)
77
+ result = event.result
78
+ Set.new(
79
+ result.changed_module_ids +
80
+ result.removed_module_ids +
81
+ result.reloaded_module_ids +
82
+ result.reevaluated_module_ids
83
+ )
84
+ end
85
+
86
+ def selection(test_ids, removed_test_ids = [])
87
+ TestSelection.new(
88
+ test_ids.map(&:relative_path).sort.freeze,
89
+ removed_test_ids.map(&:relative_path).sort.freeze
90
+ )
91
+ end
92
+ end
93
+ end
94
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Klenod
4
4
  module Build
5
- VERSION = "0.0.3"
5
+ VERSION = "0.0.4"
6
6
  end
7
7
  end
@@ -53,10 +53,11 @@ module Klenod
53
53
  end
54
54
  end
55
55
 
56
- def initialize(source_dir:, context:, debounce_interval: 0.1)
56
+ def initialize(source_dir:, context:, debounce_interval: 0.1, ignore: nil)
57
57
  @source_dir = source_dir
58
58
  @context = context
59
59
  @debounce_interval = debounce_interval
60
+ @ignore = ignore
60
61
  @graph_version = 0
61
62
  @pending_changes = PendingChanges.new
62
63
  @pending_mutex = Mutex.new
@@ -68,7 +69,7 @@ module Klenod
68
69
  def start
69
70
  @worker_thread = Thread.new { process_pending_updates }
70
71
  @listener =
71
- Listen.to(@source_dir) do |modified, added, removed|
72
+ Listen.to(@source_dir, ignore: @ignore) do |modified, added, removed|
72
73
  enqueue_update(modified + added, removed)
73
74
  end
74
75
  @listener.start
data/lib/klenod/build.rb CHANGED
@@ -9,6 +9,8 @@ module Klenod
9
9
 
10
10
  module Build
11
11
  autoload :Graphviz, "klenod/build/graphviz"
12
+ autoload :TestSelection, "klenod/build/test_suite"
13
+ autoload :TestSuite, "klenod/build/test_suite"
12
14
  autoload :UpdateEvent, "klenod/build/watcher"
13
15
  autoload :Watcher, "klenod/build/watcher"
14
16
  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.3
4
+ version: 0.0.4
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.3
18
+ version: 0.0.4
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.3
25
+ version: 0.0.4
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: async
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +272,7 @@ files:
272
272
  - lib/klenod/build/plugins/router_plugin.rb
273
273
  - lib/klenod/build/plugins/ruby_plugin.rb
274
274
  - lib/klenod/build/plugins/svg_plugin.rb
275
+ - lib/klenod/build/plugins/test_plugin.rb
275
276
  - lib/klenod/build/profiler.rb
276
277
  - lib/klenod/build/resolution_error_formatter.rb
277
278
  - lib/klenod/build/resolver.rb
@@ -280,6 +281,7 @@ files:
280
281
  - lib/klenod/build/source_map/editor.rb
281
282
  - lib/klenod/build/source_map/map.rb
282
283
  - lib/klenod/build/source_map/vlq.rb
284
+ - lib/klenod/build/test_suite.rb
283
285
  - lib/klenod/build/transform_result.rb
284
286
  - lib/klenod/build/version.rb
285
287
  - lib/klenod/build/watched_pattern.rb