bootinq 1.7 → 2.0

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: ab4d92e0581dec34e3b8c35ab842953fc6c488a7ff7a79aab4e155e0ec04b598
4
- data.tar.gz: 8d1b03413cb95941d3c34fa33e5167ae717a1152fb824f9fc4ca4c95232e3374
3
+ metadata.gz: e1652380ae399a299061b4faa8b2372fec798e02ce9f1fc9b3ab3b1a035d779e
4
+ data.tar.gz: d2339a8385fad5b4aaca89a5c2992f0adf4c5205bb650a05eb2b92e52daa349f
5
5
  SHA512:
6
- metadata.gz: 957af1a041fb5230543b149ae7bb3fa14b455e0070232c60afe617c6dfce34712d3d9ea118aad38d2fd824ef253cb6af38a1e4a115d9f5862a2680ce4d2a48e2
7
- data.tar.gz: 3dcecd28f93e44b34e7401fb6c4702754f57cac19706996a74fdbc306a9251d0fd7f8360afcd07470d37627461af4ecf1ea45e03f626b52543123d1991453d72
6
+ metadata.gz: a08526e07966f344034a18f42d032a996ab5fc97db980b3a356a3b0b4173b6e6d98ecc345a6ab80d77ec7f9e30aca2641e75b029553a3c3d45bfbceaf1ab5c8d
7
+ data.tar.gz: 850ee258bc77e6889b7a3ee5969f4befdf1ff217cb5eb1f5e70af1a3bce7b0c6c0191d2c0a87a7e5ce3d6d8f42611a3480f19bde7b7b002695133d39413eca60
data/.yardopts ADDED
@@ -0,0 +1,8 @@
1
+ --db .yardoc \
2
+ --markup-provider commonmarker \
3
+ --markup markdown \
4
+ --no-single-db \
5
+ --no-cache \
6
+ --no-document \
7
+ --embed-mixins \
8
+ --hide-void-return
data/Gemfile CHANGED
@@ -26,6 +26,8 @@ end
26
26
  group :development do
27
27
  # You don't need these, but I use them
28
28
  gem "awesome_print"
29
+ gem "commonmarker", require: false
30
+ gem "yard"
29
31
  end
30
32
 
31
33
  group :shared_boot do
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bootinq
4
+ # When just required, hooks {Bootinq#enable_component} method to
5
+ # generate fast inline wrapping methods.
6
+ #
7
+ # @see Mixins#enable_component
8
+ #
9
+ # @example Usage
10
+ # require 'bootinq'
11
+ # require 'bootinq/mixins'
12
+ module Mixins
13
+ # @api private
14
+ module ComputeNameMethod
15
+ DASH = '_'
16
+
17
+ private_constant :DASH
18
+
19
+ def compute_name(component_name)
20
+ component_name.to_s.split(DASH).
21
+ each(&:capitalize!).
22
+ join << @name_suffix
23
+ end
24
+ end
25
+
26
+ private_constant :ComputeNameMethod
27
+
28
+ # @api private
29
+ class Enabled < ::Module
30
+ @name_suffix = 'EnabledMixin'
31
+ extend ComputeNameMethod
32
+
33
+ def initialize(module_name, component_name)
34
+ module_eval <<~RUBY, __FILE__, __LINE__ + 1
35
+ # Yields the block due to component is enabled
36
+ # @yield [void]
37
+ def on_#{component_name}(*)
38
+ yield
39
+ end
40
+
41
+ # Does nothing due to component is enabled
42
+ # @return [void]
43
+ def not_#{component_name}(*)
44
+ end
45
+ RUBY
46
+ end
47
+ end
48
+
49
+ private_constant :Enabled
50
+
51
+ # @api private
52
+ class Disabled < ::Module
53
+ @name_suffix = 'DisabledMixin'
54
+ extend ComputeNameMethod
55
+
56
+ def initialize(module_name, component_name)
57
+ define_method(:name, module_name.method(:itself))
58
+
59
+ module_eval <<~RUBY, __FILE__, __LINE__ + 1
60
+ # Does nothing due to component is disabled
61
+ # @return [void]
62
+ def on_#{component_name}(*)
63
+ end
64
+
65
+ # Yields the block due to component is disabled
66
+ # @yield [void]
67
+ def not_#{component_name}(*)
68
+ yield
69
+ end
70
+ RUBY
71
+ end
72
+ end
73
+
74
+ private_constant :Disabled
75
+
76
+ Builder = -> (component_name, enabled) do
77
+ klass = enabled ? Enabled : Disabled
78
+ module_name = klass.compute_name(component_name).freeze
79
+
80
+ if Bootinq.const_defined?(module_name)
81
+ Bootinq.const_get(module_name)
82
+ else
83
+ Bootinq.const_set(module_name, klass.new(module_name, component_name))
84
+ end
85
+ end
86
+
87
+ private_constant :Builder
88
+
89
+ # Generates {Enabled} or {Disabled} mixin and sets it to a constant once,
90
+ # bypassing if it has been already defined.
91
+ # @yield [component_name, enabled]
92
+ # @return [void]
93
+ def enable_component(name, **opts)
94
+ super(name, **opts) do |component_name, enabled|
95
+ Bootinq.extend Builder[component_name, enabled]
96
+ yield(component_name, enabled) if block_given?
97
+ end
98
+ end
99
+ end
100
+
101
+ prepend Mixins
102
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails'
4
+
5
+ class Bootinq
6
+ # Require `bootinq/railtie` in the `before_configuration` block of your
7
+ # application definition to allow load component-scoped config paths
8
+ # only when the named component is enabled:
9
+ #
10
+ # - `config/routes.rb` → `config/routes.component.rb`
11
+ # - `config/locales` → `config/locales.component`
12
+ # - `config/initializers` → `config/initializers.component`
13
+ #
14
+ # It doesn't affect on the default paths without suffix.
15
+ #
16
+ # @example
17
+ # # config/application.rb
18
+ # module Example
19
+ # class Application < Rails::Application
20
+ # config.before_configuration do
21
+ # require 'bootinq/railtie'
22
+ # end
23
+ # end
24
+ # end
25
+ class Railtie < ::Rails::Railtie
26
+ initializer 'bootinq.add_locales', before: :add_locales do |app|
27
+ Bootinq.components.each do |component|
28
+ app.paths["config/locales"] << "config/locales.#{component.name}"
29
+ end
30
+ end
31
+
32
+ initializer 'bootinq.load_config_initializers', before: :load_config_initializers do |app|
33
+ Bootinq.components.each do |component|
34
+ app.paths["config/initializers"] << "config/initializers.#{component.name}"
35
+ end
36
+ end
37
+
38
+ initializer 'bootinq.add_routing_paths', before: :add_routing_paths do |app|
39
+ Bootinq.components.each do |component|
40
+ app.paths["config/routes.rb"] << "config/routes.#{component.name}.rb"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Bootinq
4
- VERSION = "1.7"
4
+ VERSION = "2.0"
5
5
  end
data/lib/bootinq.rb CHANGED
@@ -6,25 +6,21 @@ require "forwardable"
6
6
  require "bootinq/component"
7
7
  require "bootinq/switch"
8
8
 
9
- # = Bootinq
9
+ # # Bootinq
10
10
  #
11
- # == Installation
11
+ # ## Installation
12
12
  #
13
- # === Ruby on Rails
13
+ # ### Ruby on Rails
14
14
  #
15
- # 1. Insert <tt>require "bootinq"</tt> in the top of <tt>config/application.rb</tt>
15
+ # 1. insert `require "bootinq"` on top of `config/application.rb`;
16
+ # 2. find and replace `Bundler.require(*Rails.groups)` with `Bootinq.require`
16
17
  #
17
- # 2. Find <tt>Bundler.require(*Rails.groups)</tt> line below and replace it
18
- # with the <tt>Bootinq.require</tt>.
18
+ # ### Other frameworks
19
19
  #
20
- # === Other
21
- #
22
- # 1. Locate <tt>Bundler.require(...)</tt> in your app and insert <tt>require "bootinq"</tt> above.
23
- #
24
- # 2. Replace located <tt>Bundler.require(...)</tt> line with the <tt>Bootinq.require(...)</tt>.
25
- #
26
- # For example, if you are using Grape:
20
+ # 1. locate `Bundler.require(…)` in your app and insert `require "bootinq"` above it;
21
+ # 2. replace previosly located `Bundler.require(…)` line with the `Bootinq.require(…)`.
27
22
  #
23
+ # @example Grape
28
24
  # # config/application.rb
29
25
  #
30
26
  # require 'boot'
@@ -32,10 +28,8 @@ require "bootinq/switch"
32
28
  #
33
29
  # # Bundler.require :default, ENV['RACK_ENV']
34
30
  # Bootinq.require :default, ENV['RACK_ENV'], verbose: true
35
- # ...
36
- #
37
- # == Example <tt>config/bootinq.yml</tt>:
38
31
  #
32
+ # @example config/bootinq.yml
39
33
  # env_key: BOOTINQ
40
34
  # default: a
41
35
  #
@@ -49,7 +43,6 @@ require "bootinq/switch"
49
43
  # deps:
50
44
  # shared:
51
45
  # in: af
52
- #
53
46
  class Bootinq
54
47
  include Singleton
55
48
 
@@ -75,51 +68,96 @@ class Bootinq
75
68
 
76
69
  private_constant :FilterNegValue
77
70
 
78
- # :call-seq:
79
- # Bootinq.require(*groups, verbose: false, &block)
80
- #
81
- # Invokes the <tt>Bootinq.init</tt> method with the given verbose key argument & block,
82
- # and, finally, makes Bundler to require the given groups.
83
- def self.require(*groups, verbose: false, &block) # :yields: Bootinq.instance
84
- init(verbose: verbose, &block)
71
+ # Invokes the {init} method with the given options and block,
72
+ # then calls {Bundler.require} with the enabled groups.
73
+ # @see init
74
+ # @see Bundler.require
75
+ # @param groups [Array<Symbol>]
76
+ # @param options [Hash]
77
+ # initialization options
78
+ # @option options [Boolean] verbose
79
+ # track inquired components
80
+ # @option options [Proc] on_ready
81
+ # optional ready callback proc
82
+ # @return [void]
83
+ def self.require(*groups, **options, &on_ready)
84
+ init(**options, &on_ready)
85
85
  Bundler.require(*instance.groups(*groups))
86
86
  end
87
87
 
88
- # :call-seq:
89
- # Bootinq.setup(*groups, verbose: false, &block)
90
- #
91
- # Invokes the <tt>Bootinq.init</tt> method with the given verbose key argument & block,
92
- # and, finally, makes Bundler to setup the given groups.
93
- def self.setup(*groups, verbose: false, &block) # :yields: Bootinq.instance
94
- init(verbose: verbose, &block)
88
+ # Invokes the {init} method with the given options and block,
89
+ # then calls {Bundler.require} with the enabled groups.
90
+ # @see init
91
+ # @see Bundler.setup
92
+ # @param groups [Array<Symbol>]
93
+ # @param options [Hash]
94
+ # initialization options
95
+ # @option options [Boolean] verbose
96
+ # track inquired components
97
+ # @option options [Proc] on_ready
98
+ # optional ready callback proc
99
+ # @yield [instance]
100
+ # @return [void]
101
+ def self.setup(*groups, **options, &on_ready) # :yields: Bootinq.instance
102
+ init(**options, &on_ready)
95
103
  Bundler.setup(*instance.groups(*groups))
96
104
  end
97
105
 
98
- # :call-seq:
99
- # Bootinq.init(verbose: false, &block) -> true or false
100
- #
101
- # Initializes itself. Sets the BOOTINQ_PATH enviroment variable if it is missing.
102
- # To track inquired components use <tt>verbose: true</tt> key argument.
103
- # Optionally yields block within the own instance's binding.
104
- def self.init(verbose: false, &block) # :yields: Bootinq.instance
106
+ # Sets `BOOTINQ_PATH` enviroment variable if it is missing & initializes itself
107
+ # @overload init(verbose: false, on_ready:)
108
+ # @overload init(verbose: false, &on_ready)
109
+ # @param verbose [Boolean]
110
+ # track inquired components
111
+ # @param on_ready [Proc]
112
+ # optional ready callback proc
113
+ # @return [instance]
114
+ def self.init(verbose: false, on_ready: nil, &block)
105
115
  ENV['BOOTINQ_PATH'] ||= File.expand_path('../bootinq.yml', caller_locations(2, 1)[0].path)
106
116
 
107
117
  instance
108
- instance.instance_variable_set(:@_on_ready, block.to_proc) if block_given?
118
+ on_ready = block.to_proc if on_ready.nil? && block_given?
119
+ instance.instance_variable_set(:@_on_ready, on_ready.to_proc) if on_ready
120
+
109
121
  puts "Bootinq: loading components #{instance.components.join(', ')}" if verbose
122
+
110
123
  instance.ready!
111
124
  end
112
125
 
113
- # Reads config from the given or default path, deserializes it and returns as a hash.
126
+ # Reads config
127
+ # @param path [String]
128
+ # path to yaml config (default: ENV['BOOTINQ_PATH'])
129
+ # @return [Hash]
130
+ # deserializes yaml config
114
131
  def self.deserialized_config(path: nil)
115
132
  bootinq_yaml = File.read(path || ENV.fetch('BOOTINQ_PATH'))
116
- YAML.safe_load(bootinq_yaml, [Symbol])
133
+ psych_safe_load(bootinq_yaml, [Symbol])
134
+ end
135
+
136
+ # @api private
137
+ if RUBY_VERSION >= '3.1.0'
138
+ def self.psych_safe_load(path, permitted_classes)
139
+ YAML.safe_load(path, permitted_classes: permitted_classes)
140
+ end
141
+ else
142
+ def self.psych_safe_load(*args)
143
+ YAML.safe_load(*args)
144
+ end
117
145
  end
118
146
 
147
+ private_class_method :psych_safe_load
148
+
149
+ # @!attribute flags [r]
150
+ # @return [Array<String>]
151
+
119
152
  attr_reader :flags
153
+
154
+ # @!attribute components [r]
155
+ # @return [Array<String>]
156
+
120
157
  attr_reader :components
121
158
 
122
- def initialize # :no-doc:
159
+ # @return [self]
160
+ def initialize
123
161
  config = self.class.deserialized_config
124
162
  config.merge!(DEFAULT) { |_, l, r| l.nil? ? r : l }
125
163
 
@@ -135,172 +173,235 @@ class Bootinq
135
173
  config['mount'].each { |flag, name| enable_component(name, flag: flag.to_s, as: Mountable) }
136
174
  end
137
175
 
138
- def ready? # :no-doc:
176
+ # @return [Boolean]
177
+ def ready?
139
178
  !!@ready
140
179
  end
141
180
 
142
- # :call-seq:
143
- # Bootinq.ready! -> nil or self
144
- #
145
- # At the first call marks Bootinq as ready and returns the instance,
146
- # otherwise returns nil.
181
+ # Once-only set {Bootinq} to ready state firing the `@_on_ready` callback.
182
+ # @return [self] on the first call
183
+ # @return [void] after
147
184
  def ready!
148
185
  return if ready?
149
186
  @ready = true
150
187
  if defined?(@_on_ready)
151
- instance_exec(&@_on_ready)
188
+ Bootinq.class_exec(&@_on_ready)
152
189
  remove_instance_variable :@_on_ready
153
190
  end
154
191
  freeze
155
192
  end
156
193
 
157
- # :call-seq:
158
- # Bootinq.enable_component(name, flag: [, as: Component])
159
- #
194
+ # Enables the given component if it is required by flag or
195
+ # when another enabled component depends it.
196
+ # @param name [String]
197
+ # of the component
198
+ # @param flag [String]
199
+ # the component's assigned char flag
200
+ # @param as [Class]
201
+ # the component's constructor class
202
+ # @yield [name, is_enabled]
203
+ # @return [void]
160
204
  def enable_component(name, flag:, as: Component)
161
205
  if is_dependency?(name) || @_value.include?(flag)
162
206
  @flags << flag
163
207
  @components << as.new(name)
208
+ yield(name, true) if block_given?
209
+ else
210
+ yield(name, false) if block_given?
164
211
  end
212
+
213
+ nil
165
214
  end
166
215
 
167
- # :call-seq:
168
- # Bootinq.enabled?(name) -> true or false
169
- #
170
- # Checks if a component with the given name (i.e. the same gem group)
171
- # is enabled
216
+ # Checks if a component with the given name (i.e. the same gem group) is enabled
217
+ # @return [Boolean]
172
218
  def enabled?(name)
173
- ALL.include?(name) || components.include?(name)
219
+ ALL.include?(name) || @components.include?(name)
174
220
  end
175
221
 
176
- # :call-seq:
177
- # Bootinq.component(name) -> Bootinq::Component
178
- # Bootinq[name] -> Bootinq::Component
179
- #
180
- # Returns a <tt>Bootinq::Component</tt> object by its name
222
+ # @param name [String, Symbol]
223
+ # @return [Bootinq::Component]
181
224
  def component(name)
182
- components[components.index(name)]
225
+ @components[@components.index(name)]
183
226
  end
184
227
 
185
- alias :[] :component
228
+ alias_method :[], :component
186
229
 
187
- # :call-seq:
188
- # Bootinq.each_mountable { |part| block } -> Array
189
- # Bootinq.each_mountable -> Enumerator
190
- #
191
- # Calls the given block once for each enabled mountable component
192
- # passing that part as a parameter. Returns the array of all mountable components.
193
- #
194
- # If no block is given, an Enumerator is returned.
195
- def each_mountable(&block) # :yields: part
196
- components.select(&:mountable?).each(&block)
230
+ # Checks if a component with the given name (i.e. the same gem group) is disabled
231
+ # @return [Boolean]
232
+ def disabled?(name)
233
+ !@components.include?(name)
197
234
  end
198
235
 
199
- # :call-seq:
200
- # Bootinq.groups(*groups)
201
- #
202
- # Merges enabled Bootinq's groups with the given groups and, if loaded with Rails,
203
- # passes them to <tt>Rails.groups</tt> method, otherwise just returns the merged list
204
- # to use with <tt>Bundler.require</tt>.
236
+ # Enumerates enabled mountable components
237
+ # @overload each_mountable()
238
+ # @overload each_mountable(&block)
239
+ # @yield [component]
240
+ # @return [Enumerator]
241
+ def each_mountable
242
+ return enum_for(:each_mountable) unless block_given?
243
+
244
+ @components.each do |component|
245
+ yield(component) if component.mountable?
246
+ end
247
+ end
248
+
249
+ # Merges groups of enabled components with the given ones.
250
+ # When loaded with Rails, it passes them to {Rails.groups} method,
251
+ # otherwise just returns the merged list to use it with {Bundler.require}.
252
+ # @param groups [Array<String, Symbol>]
253
+ # @return [Array<String, Symbol>] merged groups
205
254
  def groups(*groups)
206
- groups.unshift(*components.map(&:group))
207
- if defined?(Rails)
208
- Rails.groups(*groups)
209
- else
210
- groups
255
+ @components.each do |component|
256
+ next if groups.include?(component.group)
257
+ groups.unshift(component.group)
211
258
  end
259
+
260
+ defined?(Rails) ? Rails.groups(*groups) : groups
212
261
  end
213
262
 
214
- # :call-seq:
215
- # Bootinq.on(name) { block } -> true or false
216
- # Bootinq.on(any: [names]) { block } -> true or false
217
- # Bootinq.on(all: [names]) { block } -> true or false
218
- #
219
- # Takes a component's name or single-key options hash as an argument and
220
- # yields a given block if the target components are enabled.
221
- #
222
- # See examples for a usage.
263
+ # @overload on(name)
264
+ # @yield [void] (if component is enabled)
265
+ # @param name [Symbol] single component's name
223
266
  #
224
- # ==== Example:
267
+ # @overload on(any:)
268
+ # @see on_any
269
+ # @yield [void] (if _any_ matching component is enabled)
270
+ # @param any [Array<Symbol>] list of components' names
225
271
  #
226
- # Bootinq.on :frontend do
227
- # # make frontend thing...
228
- # end
272
+ # @overload on(all:)
273
+ # @see on_all
274
+ # @yield [void] (if _all_ matching components are enabled)
275
+ # @param all [Array<Symbol>] list of components' names
229
276
  #
230
- # Bootinq.on any: %i(frontend backend) do
231
- # # do something when frontend or backend is enabled
232
- # end
277
+ # @return [Boolean] matching status
233
278
  #
234
- # Bootinq.on all: %i(frontend backend) do
235
- # # do something when frontend and backend are enabled
236
- # end
237
- def on(name = nil, any: nil, all: nil) # :yields:
238
- if ALL.include?(name)
279
+ # @example single
280
+ # Bootinq.on(:frontend) { puts 'frontend' }
281
+ # @example any
282
+ # Bootinq.on(any: %i[frontend backend]) { puts 'frontend or backend' }
283
+ # @example all
284
+ # Bootinq.on(all: %i[frontend backend]) { puts 'both' }
285
+ def on(name = nil, any: nil, all: nil)
286
+ if name && ALL.include?(name)
239
287
  yield
240
288
  return true
241
289
  end
242
290
 
243
- if name.nil? && any.nil? && all.nil?
244
- raise ArgumentError, "wrong arguments (given 0, expected 1)"
245
- elsif (any && all) || (name && (any || all))
246
- raise ArgumentError, "expected single argument or one of keywords: `all' or `any'"
247
- end
248
-
249
291
  is_matched =
250
292
  name ? enabled?(name) :
251
293
  any ? on_any(*any) :
252
294
  all ? on_all(*all) : false
295
+
253
296
  yield if is_matched
297
+
254
298
  is_matched
255
299
  end
256
300
 
257
- # :call-seq:
258
- # Bootinq.on_all(*names) { block } -> true or false
259
- #
260
- # Takes a list of component names and yields a given block (optionally)
261
- # if all of them are enabled. Returns boolean matching status.
301
+ # @yield [void]
302
+ # if _all_ matching components are enabled
303
+ # @param parts [Array<String, Symbol>]
304
+ # list of components' names
305
+ # @return [Boolean]
306
+ # matching status
262
307
  def on_all(*parts) # :yields:
263
- is_matched = parts.all? { |part| enabled?(part) }
308
+ is_matched = parts.reduce(true) { |m, part| m && enabled?(part) }
264
309
  yield if is_matched && block_given?
265
310
  is_matched
266
311
  end
267
312
 
268
- # :call-seq:
269
- # Bootinq.on_all(*names) { block } -> true or false
270
- #
271
- # Takes a list of component names and yields a given block (optionally)
272
- # if any of them are enabled. Returns boolean matching status.
313
+ # @yield [void]
314
+ # if _any_ matching component is enabled
315
+ # @param parts [Array<String, Symbol>]
316
+ # list of components' names
317
+ # @return [Boolean]
318
+ # matching status
273
319
  def on_any(*parts) # :yields:
274
- is_matched = parts.any? { |part| enabled?(part) }
320
+ is_matched = parts.reduce(false) { |m, part| m || enabled?(part) }
275
321
  yield if is_matched && block_given?
276
322
  is_matched
277
323
  end
278
324
 
279
- # :call-seq:
280
- # Bootinq.switch(*parts) { block } -> nil
325
+ # @overload not(name)
326
+ # @yield [void] (if component is disabled)
327
+ # @param name [Symbol] single component's name
281
328
  #
282
- # Collector method.
329
+ # @overload not(any:)
330
+ # @see not_any
331
+ # @yield [void] (if _any_ matching component is disabled)
332
+ # @param any [Array<Symbol>] list of components' names
283
333
  #
284
- # Example:
334
+ # @overload not(all:)
335
+ # @see not_all
336
+ # @yield [void] (if _all_ matching components are disabled)
337
+ # @param all [Array<Symbol>] list of components' names
285
338
  #
339
+ # @return [Boolean] matching status
340
+ #
341
+ # @example single
342
+ # Bootinq.not(:frontend) { puts 'not frontend' }
343
+ # @example any
344
+ # Bootinq.not(any: %i[frontend backend]) { puts 'neither frontend nor backend' }
345
+ # @example all
346
+ # Bootinq.on(all: %i[frontend backend]) { puts 'both disabled' }
347
+ def not(name = nil, any: nil, all: nil)
348
+ is_matched =
349
+ name ? disabled?(name) :
350
+ any ? not_any(*any) :
351
+ all ? not_all(*all) : false
352
+
353
+ yield if is_matched
354
+
355
+ is_matched
356
+ end
357
+
358
+ # @yield [void]
359
+ # if _all_ matching components are disabled
360
+ # @param parts [Array<String, Symbol>]
361
+ # list of components' names
362
+ # @return [Boolean]
363
+ # matching status
364
+ def not_all(*parts) # :yields:
365
+ is_matched = parts.reduce(true) { |m, part| m && disabled?(part) }
366
+ yield if is_matched && block_given?
367
+ is_matched
368
+ end
369
+
370
+ # @yield [void]
371
+ # if _any_ matching component is disabled
372
+ # @param parts [Array<String, Symbol>]
373
+ # list of components' names
374
+ # @return [Boolean]
375
+ # matching status
376
+ def not_any(*parts) # :yields:
377
+ is_matched = parts.reduce(false) { |m, part| m || disabled?(part) }
378
+ yield if is_matched && block_given?
379
+ is_matched
380
+ end
381
+
382
+ # Collector method.
383
+ # @example
286
384
  # Bootinq.switch do |part|
287
385
  # part.frontend { … }
288
386
  # part.backend { … }
289
387
  # end
290
- def switch # :yields: Bootinq::Switch.new
388
+ # @yield [switch]
389
+ # @see Bootinq::Switch
390
+ # @return [void]
391
+ def switch
291
392
  yield(Switch.new)
292
393
  nil
293
394
  end
294
395
 
295
- # :call-seq:
296
- # is_dependency?(part_name) -> true or false
297
- #
298
- # Checks if the named component is a dependency of the enabled one.
396
+ # Checks if the named component is dependent by another enabled one.
397
+ # @param name [String, Symbol]
398
+ # @return [Boolean]
299
399
  def is_dependency?(name)
300
- @_deps.key?(name) && @_value.count(@_deps[name]['in'].to_s) > 0
400
+ @_deps.key?(name.to_s) &&
401
+ @_value.count(@_deps.dig(name.to_s, 'in').to_s) > 0
301
402
  end
302
403
 
303
- # Freezes every instance variables and the instance itself.
404
+ # @api private
304
405
  def freeze
305
406
  @_value.freeze
306
407
  @_neg
@@ -311,20 +412,22 @@ class Bootinq
311
412
 
312
413
  extend SingleForwardable
313
414
 
314
- delegate %I[
315
- component
316
- components
317
- each_mountable
318
- enabled?
319
- enable_component
320
- flags
321
- groups
322
- on
323
- on_all
324
- on_any
325
- ready!
326
- ready?
327
- switch
328
- []
329
- ] => :instance
415
+ def_delegator :instance, :component
416
+ def_delegator :instance, :components
417
+ def_delegator :instance, :each_mountable
418
+ def_delegator :instance, :enabled?
419
+ def_delegator :instance, :enable_component
420
+ def_delegator :instance, :disabled?
421
+ def_delegator :instance, :flags
422
+ def_delegator :instance, :groups
423
+ def_delegator :instance, :on
424
+ def_delegator :instance, :on_all
425
+ def_delegator :instance, :on_any
426
+ def_delegator :instance, :not
427
+ def_delegator :instance, :not_all
428
+ def_delegator :instance, :not_any
429
+ def_delegator :instance, :ready!
430
+ def_delegator :instance, :ready?
431
+ def_delegator :instance, :switch
432
+ def_delegator :instance, :[]
330
433
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootinq
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.7'
4
+ version: '2.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-12 00:00:00.000000000 Z
11
+ date: 2022-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -48,6 +48,7 @@ files:
48
48
  - ".gitignore"
49
49
  - ".rspec"
50
50
  - ".travis.yml"
51
+ - ".yardopts"
51
52
  - Gemfile
52
53
  - LICENSE.txt
53
54
  - README.md
@@ -58,6 +59,8 @@ files:
58
59
  - lib/bootinq.rb
59
60
  - lib/bootinq.yml
60
61
  - lib/bootinq/component.rb
62
+ - lib/bootinq/mixins.rb
63
+ - lib/bootinq/railtie.rb
61
64
  - lib/bootinq/switch.rb
62
65
  - lib/bootinq/version.rb
63
66
  homepage: https://github.com/estum/bootinq