dry-system 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2a8be3e6a065030a843d21c8940d4869cfda202c1959c7094b601f8d266c499
4
- data.tar.gz: 1938faa66a1913ca2297d51ad0abd9a4f1f787426c4fe512103a3b9e2ada5394
3
+ metadata.gz: 691aea0bf618106d932309794bcf87afa5d84a3c423871342c2ceb39b45a6ce6
4
+ data.tar.gz: 1ac5655641e9ffd965e3f0b37a199367e7157074a14250745a49925bab0ec517
5
5
  SHA512:
6
- metadata.gz: 5766837f8f85f7d3ece0107d3f65f0f81501ec00088cf860e1d47ad7e18284c24ff02c6109d80559aa64473cadce187fd6840e81b9a96648b75718d3d571fcbf
7
- data.tar.gz: e26fd6ffb2d50c7b536a7ba7307ef348efcf6860f13487565975b17b34528fc876788705f655f0a3919b572eb26fc73b91cd2745156fb1d3acd6a737d3b0813c
6
+ metadata.gz: 589e77b1739b554528f13633f93bf61c39f4945067318f08afcc5be5bf0afbc53db137f54d0e1b2202aa45a5f2a3df697564cfc7f208cb3fa043d28b0f174706
7
+ data.tar.gz: 8271fb82fde50c7bfed6e52da6a58ea90a447ee7097562402cfd38d94823edb29bee835b0e462bc893ddb59ddb76f1d0fe0c9dab99d4cf14062f74082ab0ccdc
@@ -1,3 +1,15 @@
1
+ # 0.10.1 - 2018-07-05
2
+
3
+ ### Added
4
+
5
+ * Support for stopping bootable components with `Container.stop(component_name)` (GustavoCaso)
6
+
7
+ ### Fixed
8
+
9
+ * When using a non-finalized container, you can now resolve multiple different container objects registered using the same root key as a bootable component (timriley)
10
+
11
+ [Compare v0.10.0...v0.10.1](https://github.com/dry-rb/dry-system/compare/v0.10.0...v0.10.1)
12
+
1
13
  # 0.10.0 - 2018-06-07
2
14
 
3
15
  ### Added
@@ -17,10 +29,10 @@
17
29
 
18
30
  * A helpful error will be raised if an invalid setting value is provided (GustavoCaso)
19
31
  * When using setting plugin, will use default values from types (GustavoCaso)
20
- * Minimal supported ruby version was bump to `2.3` (flash-gordon)
32
+ * Minimal supported ruby version was bumped to `2.3` (flash-gordon)
21
33
  * `dry-struct` was updated to `~> 0.5` (flash-gordon)
22
34
 
23
- [Compare v0.9.2...master](https://github.com/dry-rb/dry-system/compare/v0.9.2...master)
35
+ [Compare v0.9.2...v0.10.0](https://github.com/dry-rb/dry-system/compare/v0.9.2...v0.10.0)
24
36
 
25
37
  # 0.9.2 - 2018-02-08
26
38
 
@@ -96,6 +96,15 @@ module Dry
96
96
  end
97
97
  end
98
98
 
99
+ # @api private
100
+ def stop(name_or_component)
101
+ call(name_or_component) do |component|
102
+ raise ComponentNotStartedError.new(name_or_component) unless booted.include?(component)
103
+ component.stop
104
+ yield if block_given?
105
+ end
106
+ end
107
+
99
108
  # @api private
100
109
  def call(name_or_component)
101
110
  with_component(name_or_component) do |component|
@@ -0,0 +1,664 @@
1
+ require 'pathname'
2
+
3
+ require 'dry-auto_inject'
4
+ require 'dry-configurable'
5
+ require 'dry-container'
6
+ require 'dry/inflector'
7
+
8
+ require 'dry/core/deprecations'
9
+
10
+ require 'dry/system'
11
+ require 'dry/system/errors'
12
+ require 'dry/system/loader'
13
+ require 'dry/system/booter'
14
+ require 'dry/system/auto_registrar'
15
+ require 'dry/system/manual_registrar'
16
+ require 'dry/system/importer'
17
+ require 'dry/system/component'
18
+ require 'dry/system/constants'
19
+ require 'dry/system/plugins'
20
+
21
+ module Dry
22
+ module System
23
+ # Abstract container class to inherit from
24
+ #
25
+ # Container class is treated as a global registry with all system components.
26
+ # Container can also import dependencies from other containers, which is
27
+ # useful in complex systems that are split into sub-systems.
28
+ #
29
+ # Container can be finalized, which triggers loading of all the defined
30
+ # components within a system, after finalization it becomes frozen. This
31
+ # typically happens in cases like booting a web application.
32
+ #
33
+ # Before finalization, Container can lazy-load components on demand. A
34
+ # component can be a simple class defined in a single file, or a complex
35
+ # component which has init/start/stop lifecycle, and it's defined in a boot
36
+ # file. Components which specify their dependencies using Import module can
37
+ # be safely required in complete isolation, and Container will resolve and
38
+ # load these dependencies automatically.
39
+ #
40
+ # Furthermore, Container supports auto-registering components based on
41
+ # dir/file naming conventions. This reduces a lot of boilerplate code as all
42
+ # you have to do is to put your classes under configured directories and
43
+ # their instances will be automatically registered within a container.
44
+ #
45
+ # Every container needs to be configured with following settings:
46
+ #
47
+ # * `:name` - a unique container identifier
48
+ # * `:root` - a system root directory (defaults to `pwd`)
49
+ # * `:system_dir` - directory name relative to root, where bootable components
50
+ # can be defined in `boot` dir this defaults to `system`
51
+ #
52
+ # @example
53
+ # class MyApp < Dry::System::Container
54
+ # configure do |config|
55
+ # config.name = :my_app
56
+ #
57
+ # # this will auto-register classes from 'lib/components'. ie if you add
58
+ # # `lib/components/repo.rb` which defines `Repo` class, then it's
59
+ # # instance will be automatically available as `MyApp['repo']`
60
+ # config.auto_register = %w(lib/components)
61
+ # end
62
+ #
63
+ # # this will configure $LOAD_PATH to include your `lib` dir
64
+ # load_paths!('lib')
65
+ # end
66
+ #
67
+ # @api public
68
+ class Container
69
+ extend Dry::Configurable
70
+ extend Dry::Container::Mixin
71
+ extend Dry::System::Plugins
72
+
73
+ setting :name
74
+ setting :default_namespace
75
+ setting(:root, Pathname.pwd.freeze) { |path| Pathname(path) }
76
+ setting :system_dir, 'system'.freeze
77
+ setting :registrations_dir, 'container'.freeze
78
+ setting :auto_register, []
79
+ setting :inflector, Dry::Inflector.new
80
+ setting :loader, Dry::System::Loader
81
+ setting :booter, Dry::System::Booter
82
+ setting :auto_registrar, Dry::System::AutoRegistrar
83
+ setting :manual_registrar, Dry::System::ManualRegistrar
84
+ setting :importer, Dry::System::Importer
85
+ setting(:components, {}, reader: true) { |v| v.dup }
86
+
87
+ class << self
88
+ extend Dry::Core::Deprecations['Dry::System::Container']
89
+
90
+ # Configures the container
91
+ #
92
+ # @example
93
+ # class MyApp < Dry::System::Container
94
+ # configure do |config|
95
+ # config.root = Pathname("/path/to/app")
96
+ # config.name = :my_app
97
+ # config.auto_register = %w(lib/apis lib/core)
98
+ # end
99
+ # end
100
+ #
101
+ # @return [self]
102
+ #
103
+ # @api public
104
+ def configure(&block)
105
+ super(&block)
106
+ load_paths!(config.system_dir)
107
+ hooks[:configure].each { |hook| instance_eval(&hook) }
108
+ self
109
+ end
110
+
111
+ # Registers another container for import
112
+ #
113
+ # @example
114
+ # # system/container.rb
115
+ # class Core < Dry::System::Container
116
+ # configure do |config|
117
+ # config.root = Pathname("/path/to/app")
118
+ # config.auto_register = %w(lib/apis lib/core)
119
+ # end
120
+ # end
121
+ #
122
+ # # apps/my_app/system/container.rb
123
+ # require 'system/container'
124
+ #
125
+ # class MyApp < Dry::System::Container
126
+ # configure do |config|
127
+ # config.root = Pathname("/path/to/app")
128
+ # config.auto_register = %w(lib/apis lib/core)
129
+ # end
130
+ #
131
+ # import core: Core
132
+ # end
133
+ #
134
+ # @param other [Hash, Dry::Container::Namespace]
135
+ #
136
+ # @api public
137
+ def import(other)
138
+ case other
139
+ when Hash then importer.register(other)
140
+ when Dry::Container::Namespace then super
141
+ else
142
+ raise ArgumentError, "+other+ must be a hash of names and systems, or a Dry::Container namespace"
143
+ end
144
+ end
145
+
146
+ # Registers finalization function for a bootable component
147
+ #
148
+ # By convention, boot files for components should be placed in
149
+ # `%{system_dir}/boot` and they will be loaded on demand when components
150
+ # are loaded in isolation, or during finalization process.
151
+ #
152
+ # @example
153
+ # # system/container.rb
154
+ # class MyApp < Dry::System::Container
155
+ # configure do |config|
156
+ # config.root = Pathname("/path/to/app")
157
+ # config.name = :core
158
+ # config.auto_register = %w(lib/apis lib/core)
159
+ # end
160
+ #
161
+ # # system/boot/db.rb
162
+ # #
163
+ # # Simple component registration
164
+ # MyApp.boot(:db) do |container|
165
+ # require 'db'
166
+ #
167
+ # container.register(:db, DB.new)
168
+ # end
169
+ #
170
+ # # system/boot/db.rb
171
+ # #
172
+ # # Component registration with lifecycle triggers
173
+ # MyApp.boot(:db) do |container|
174
+ # init do
175
+ # require 'db'
176
+ # DB.configure(ENV['DB_URL'])
177
+ # container.register(:db, DB.new)
178
+ # end
179
+ #
180
+ # start do
181
+ # db.establish_connection
182
+ # end
183
+ #
184
+ # stop do
185
+ # db.close_connection
186
+ # end
187
+ # end
188
+ #
189
+ # # system/boot/db.rb
190
+ # #
191
+ # # Component registration which uses another bootable component
192
+ # MyApp.boot(:db) do |container|
193
+ # use :logger
194
+ #
195
+ # start do
196
+ # require 'db'
197
+ # DB.configure(ENV['DB_URL'], logger: logger)
198
+ # container.register(:db, DB.new)
199
+ # end
200
+ # end
201
+ #
202
+ # # system/boot/db.rb
203
+ # #
204
+ # # Component registration under a namespace. This will register the
205
+ # # db object under `persistence.db` key
206
+ # MyApp.namespace(:persistence) do |persistence|
207
+ # require 'db'
208
+ # DB.configure(ENV['DB_URL'], logger: logger)
209
+ # persistence.register(:db, DB.new)
210
+ # end
211
+ #
212
+ # @param name [Symbol] a unique identifier for a bootable component
213
+ #
214
+ # @see Lifecycle
215
+ #
216
+ # @return [self]
217
+ #
218
+ # @api public
219
+ def boot(name, opts = {}, &block)
220
+ if components.key?(name)
221
+ raise DuplicatedComponentKeyError, "Bootable component #{name.inspect} was already registered"
222
+ end
223
+
224
+ component =
225
+ if opts[:from]
226
+ boot_external(name, opts, &block)
227
+ else
228
+ boot_local(name, opts, &block)
229
+ end
230
+ self
231
+
232
+ components[name] = component
233
+ end
234
+ deprecate :finalize, :boot
235
+
236
+ # @api private
237
+ def boot_external(identifier, from:, key: nil, namespace: nil, &block)
238
+ component = System.providers[from].component(
239
+ identifier, key: key, namespace: namespace, finalize: block, container: self
240
+ )
241
+
242
+ booter.register_component(component)
243
+
244
+ component
245
+ end
246
+
247
+ # @api private
248
+ def boot_local(identifier, namespace: nil, &block)
249
+ component = Components::Bootable.new(identifier, container: self, namespace: namespace, &block)
250
+
251
+ booter.register_component(component)
252
+
253
+ component
254
+ end
255
+
256
+ # Return if a container was finalized
257
+ #
258
+ # @return [TrueClass, FalseClass]
259
+ #
260
+ # @api public
261
+ def finalized?
262
+ @__finalized__.equal?(true)
263
+ end
264
+
265
+ # Finalizes the container
266
+ #
267
+ # This triggers importing components from other containers, booting
268
+ # registered components and auto-registering components. It should be
269
+ # called only in places where you want to finalize your system as a
270
+ # whole, ie when booting a web application
271
+ #
272
+ # @example
273
+ # # system/container.rb
274
+ # class MyApp < Dry::System::Container
275
+ # configure do |config|
276
+ # config.root = Pathname("/path/to/app")
277
+ # config.name = :my_app
278
+ # config.auto_register = %w(lib/apis lib/core)
279
+ # end
280
+ # end
281
+ #
282
+ # # You can put finalization file anywhere you want, ie system/boot.rb
283
+ # MyApp.finalize!
284
+ #
285
+ # # If you need last-moment adjustments just before the finalization
286
+ # # you can pass a block and do it there
287
+ # MyApp.finalize! do |container|
288
+ # # stuff that only needs to happen for finalization
289
+ # end
290
+ #
291
+ # @return [self] frozen container
292
+ #
293
+ # @api public
294
+ def finalize!(freeze: true, &block)
295
+ return self if finalized?
296
+
297
+ yield(self) if block
298
+
299
+ importer.finalize!
300
+ booter.finalize!
301
+ manual_registrar.finalize!
302
+ auto_registrar.finalize!
303
+
304
+ @__finalized__ = true
305
+
306
+ self.freeze if freeze
307
+ end
308
+
309
+ # Boots a specific component
310
+ #
311
+ # As a result, `init` and `start` lifecycle triggers are called
312
+ #
313
+ # @example
314
+ # MyApp.start(:persistence)
315
+ #
316
+ # @param name [Symbol] the name of a registered bootable component
317
+ #
318
+ # @return [self]
319
+ #
320
+ # @api public
321
+ def start(name)
322
+ booter.start(name)
323
+ self
324
+ end
325
+
326
+ # Boots a specific component but calls only `init` lifecycle trigger
327
+ #
328
+ # This way of booting is useful in places where a heavy dependency is
329
+ # needed but its started environment is not required
330
+ #
331
+ # @example
332
+ # MyApp.init(:persistence)
333
+ #
334
+ # @param [Symbol] name The name of a registered bootable component
335
+ #
336
+ # @return [self]
337
+ #
338
+ # @api public
339
+ def init(name)
340
+ booter.init(name)
341
+ self
342
+ end
343
+
344
+ # Stop a specific component but calls only `stop` lifecycle trigger
345
+ #
346
+ # @example
347
+ # MyApp.stop(:persistence)
348
+ #
349
+ # @param [Symbol] name The name of a registered bootable component
350
+ #
351
+ # @return [self]
352
+ #
353
+ # @api public
354
+ def stop(name)
355
+ booter.stop(name)
356
+ self
357
+ end
358
+
359
+ # Sets load paths relative to the container's root dir
360
+ #
361
+ # @example
362
+ # class MyApp < Dry::System::Container
363
+ # configure do |config|
364
+ # # ...
365
+ # end
366
+ #
367
+ # load_paths!('lib')
368
+ # end
369
+ #
370
+ # @param [Array<String>] dirs
371
+ #
372
+ # @return [self]
373
+ #
374
+ # @api public
375
+ def load_paths!(*dirs)
376
+ dirs.map(&root.method(:join)).each do |path|
377
+ next if load_paths.include?(path)
378
+ load_paths << path
379
+ $LOAD_PATH.unshift(path.to_s)
380
+ end
381
+ self
382
+ end
383
+
384
+ # @api public
385
+ def load_registrations!(name)
386
+ manual_registrar.(name)
387
+ self
388
+ end
389
+
390
+ # Auto-registers components from the provided directory
391
+ #
392
+ # Typically you want to configure auto_register directories, and it will
393
+ # work automatically. Use this method in cases where you want to have an
394
+ # explicit way where some components are auto-registered, or if you want
395
+ # to exclude some components from being auto-registered
396
+ #
397
+ # @example
398
+ # class MyApp < Dry::System::Container
399
+ # configure do |config|
400
+ # # ...
401
+ # end
402
+ #
403
+ # # with a dir
404
+ # auto_register!('lib/core')
405
+ #
406
+ # # with a dir and a custom registration block
407
+ # auto_register!('lib/core') do |config|
408
+ # config.instance do |component|
409
+ # # custom way of initializing a component
410
+ # end
411
+ #
412
+ # config.exclude do |component|
413
+ # # return true to exclude component from auto-registration
414
+ # end
415
+ # end
416
+ # end
417
+ #
418
+ # @param [String] dir The dir name relative to the root dir
419
+ #
420
+ # @yield AutoRegistrar::Configuration
421
+ # @see AutoRegistrar::Configuration
422
+ #
423
+ # @return [self]
424
+ #
425
+ # @api public
426
+ def auto_register!(dir, &block)
427
+ auto_registrar.(dir, &block)
428
+ self
429
+ end
430
+
431
+ # Builds injector for this container
432
+ #
433
+ # An injector is a useful mixin which injects dependencies into
434
+ # automatically defined constructor.
435
+ #
436
+ # @example
437
+ # # Define an injection mixin
438
+ # #
439
+ # # system/import.rb
440
+ # Import = MyApp.injector
441
+ #
442
+ # # Use it in your auto-registered classes
443
+ # #
444
+ # # lib/user_repo.rb
445
+ # require 'import'
446
+ #
447
+ # class UserRepo
448
+ # include Import['persistence.db']
449
+ # end
450
+ #
451
+ # MyApp['user_repo].db # instance under 'persistence.db' key
452
+ #
453
+ # @param options [Hash] injector options
454
+ #
455
+ # @api public
456
+ def injector(options = {})
457
+ Dry::AutoInject(self, options)
458
+ end
459
+
460
+ # Requires one or more files relative to the container's root
461
+ #
462
+ # @example
463
+ # # single file
464
+ # MyApp.require_from_root('lib/core')
465
+ #
466
+ # # glob
467
+ # MyApp.require_from_root('lib/**/*')
468
+ #
469
+ # @param paths [Array<String>] one or more paths, supports globs too
470
+ #
471
+ # @api public
472
+ def require_from_root(*paths)
473
+ paths.flat_map { |path|
474
+ path.to_s.include?('*') ? Dir[root.join(path)] : root.join(path)
475
+ }.each { |path|
476
+ require path.to_s
477
+ }
478
+ end
479
+
480
+ # Returns container's root path
481
+ #
482
+ # @example
483
+ # class MyApp < Dry::System::Container
484
+ # configure do |config|
485
+ # config.root = Pathname('/my/app')
486
+ # end
487
+ # end
488
+ #
489
+ # MyApp.root # returns '/my/app' pathname
490
+ #
491
+ # @return [Pathname]
492
+ #
493
+ # @api public
494
+ def root
495
+ config.root
496
+ end
497
+
498
+ # @api public
499
+ def resolve(key)
500
+ load_component(key) unless finalized?
501
+
502
+ super
503
+ end
504
+
505
+ # @api private
506
+ def load_paths
507
+ @load_paths ||= []
508
+ end
509
+
510
+ # @api private
511
+ def booter
512
+ @booter ||= config.booter.new(boot_path)
513
+ end
514
+
515
+ # @api private
516
+ def boot_path
517
+ root.join("#{config.system_dir}/boot")
518
+ end
519
+
520
+ # @api private
521
+ def auto_registrar
522
+ @auto_registrar ||= config.auto_registrar.new(self)
523
+ end
524
+
525
+ # @api private
526
+ def manual_registrar
527
+ @manual_registrar ||= config.manual_registrar.new(self)
528
+ end
529
+
530
+ # @api private
531
+ def importer
532
+ @importer ||= config.importer.new(self)
533
+ end
534
+
535
+ # @api private
536
+ def component(identifier, **options)
537
+ if (component = booter.components.detect { |c| c.identifier == identifier })
538
+ component
539
+ else
540
+ Component.new(
541
+ identifier,
542
+ loader: config.loader,
543
+ namespace: config.default_namespace,
544
+ separator: config.namespace_separator,
545
+ inflector: config.inflector,
546
+ **options,
547
+ )
548
+ end
549
+ end
550
+
551
+ # @api private
552
+ def require_component(component)
553
+ return if key?(component.identifier)
554
+
555
+ unless component.file_exists?(load_paths)
556
+ raise FileNotFoundError, component
557
+ end
558
+
559
+ require component.path
560
+
561
+ yield
562
+ end
563
+
564
+ # @api private
565
+ def load_component(key)
566
+ puts "load_component #{key}"
567
+ return self if key?(key)
568
+
569
+ component(key).tap do |component|
570
+ if component.boot?
571
+ booter.start(component)
572
+ else
573
+ root_key = component.root_key
574
+
575
+ puts "root key:"
576
+ p root_key
577
+
578
+ # byebug
579
+
580
+
581
+ # if (bootable_dep = component(root_key)).boot?
582
+ # booter.start(bootable_dep)
583
+
584
+ if importer.key?(root_key)
585
+ load_imported_component(component.namespaced(root_key))
586
+ else
587
+ # Feels like we don't even need this if load_local_component gets involved with booting?
588
+ booter.start(root_key) if booter.bootable?(root_key)
589
+
590
+
591
+ load_local_component(component)
592
+ end
593
+
594
+
595
+
596
+ # if booter.bootable?(root_key)
597
+ # booter.start(root_key)
598
+ # elsif importer.key?(root_key)
599
+ # load_imported_component(component.namespaced(root_key))
600
+ # else
601
+ # load_local_component(component)
602
+ # end
603
+ end
604
+ end
605
+
606
+ self
607
+ end
608
+
609
+ # @api private
610
+ def after(event, &block)
611
+ hooks[event] << block
612
+ end
613
+
614
+ # @api private
615
+ def hooks
616
+ @__hooks__ ||= Hash.new { |h, k| h[k] = [] }
617
+ end
618
+
619
+ # @api private
620
+ def inherited(klass)
621
+ new_hooks = Container.hooks.dup
622
+
623
+ hooks.each do |event, blocks|
624
+ new_hooks[event].concat(blocks)
625
+ new_hooks[event].concat(klass.hooks[event])
626
+ end
627
+
628
+ klass.instance_variable_set(:@__hooks__, new_hooks)
629
+ super
630
+ end
631
+
632
+ private
633
+
634
+ # @api private
635
+ def load_local_component(component, default_namespace_fallback = false)
636
+ # byebug
637
+
638
+ # if booter.bootable?(component)
639
+ # booter.boot_dependency(component) unless finalized?
640
+ # end
641
+
642
+ if component.file_exists?(load_paths)
643
+ require_component(component) do
644
+ register(component.identifier) { component.instance }
645
+ end
646
+ elsif !default_namespace_fallback
647
+ load_local_component(component.prepend(config.default_namespace), true)
648
+ elsif manual_registrar.file_exists?(component)
649
+ manual_registrar.(component)
650
+ else
651
+ raise ComponentLoadError, component
652
+ end
653
+ end
654
+
655
+ # @api private
656
+ def load_imported_component(component)
657
+ container = importer[component.namespace]
658
+ container.load_component(component.identifier)
659
+ importer.(component.namespace, container)
660
+ end
661
+ end
662
+ end
663
+ end
664
+ end
@@ -341,6 +341,21 @@ module Dry
341
341
  self
342
342
  end
343
343
 
344
+ # Stop a specific component but calls only `stop` lifecycle trigger
345
+ #
346
+ # @example
347
+ # MyApp.stop(:persistence)
348
+ #
349
+ # @param [Symbol] name The name of a registered bootable component
350
+ #
351
+ # @return [self]
352
+ #
353
+ # @api public
354
+ def stop(name)
355
+ booter.stop(name)
356
+ self
357
+ end
358
+
344
359
  # Sets load paths relative to the container's root dir
345
360
  #
346
361
  # @example
@@ -560,7 +575,9 @@ module Dry
560
575
  booter.start(bootable_dep)
561
576
  elsif importer.key?(root_key)
562
577
  load_imported_component(component.namespaced(root_key))
563
- else
578
+ end
579
+
580
+ if !key?(key)
564
581
  load_local_component(component)
565
582
  end
566
583
  end
@@ -58,5 +58,14 @@ module Dry
58
58
  super("component identifier #{name.inspect} must be a symbol")
59
59
  end
60
60
  end
61
+
62
+ # Error raised when trying to stop a component that hasn't started yet
63
+ #
64
+ # @api public
65
+ ComponentNotStartedError = Class.new(StandardError) do
66
+ def initialize(component_name)
67
+ super("component +#{component_name}+ has not been started")
68
+ end
69
+ end
61
70
  end
62
71
  end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module System
3
- VERSION = '0.10.0'.freeze
3
+ VERSION = '0.10.1'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-system
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2018-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -197,6 +197,7 @@ files:
197
197
  - lib/dry/system/components/bootable.rb
198
198
  - lib/dry/system/components/config.rb
199
199
  - lib/dry/system/constants.rb
200
+ - lib/dry/system/container.mod.rb
200
201
  - lib/dry/system/container.rb
201
202
  - lib/dry/system/errors.rb
202
203
  - lib/dry/system/importer.rb
@@ -240,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
241
  version: '0'
241
242
  requirements: []
242
243
  rubyforge_project:
243
- rubygems_version: 2.7.6
244
+ rubygems_version: 2.7.5
244
245
  signing_key:
245
246
  specification_version: 4
246
247
  summary: Organize your code into reusable components