bootinq 1.7 → 2.0

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: 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