bootinq 1.0.1 → 1.4.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
- SHA1:
3
- metadata.gz: e3f02fce19c9b509420de6322555b1f3a8fe7c2a
4
- data.tar.gz: 1a269f11b486f95c33d6df89948281cb74d6e2f6
2
+ SHA256:
3
+ metadata.gz: c08400508d67149e4ea7d4eeda4f33a25a5a9dd68f4ed40b79ac517f5d028ce5
4
+ data.tar.gz: c1af627b8eb2282a3fccec5c90f83d44382bdb9ffea7f81de4df95a13af747c0
5
5
  SHA512:
6
- metadata.gz: efc41497347123f8025457ad4af3e2037df51387f56248ece3bcdacfb0443eae8f12428203a4dda3a8e3d1d19a8ef21e32687eafdb01475486dc00c02a06f808
7
- data.tar.gz: 274f3d80999d1acacf21ceeafea979fd67a138ed617959effa234b860331599109e71c3cd5c964c11c93c4d4fead1dafec65521326e76a9a3344199b69e1e651
6
+ metadata.gz: da561be83aff97f64a9b41084ae19a5dc0f9c4692a0e944c1c9bf2f41d16538d37fe4d35de515c01c63c5c795abccc7c54a8d6c4cb2d9964762b4d84d880c5c7
7
+ data.tar.gz: 87152bc5af6852f2b1347bab91b9a8c5f68e929266fecf214a5fe66f545a6ef3517603904ce344fdb177ae95c10d03e30ac507cabcb7aa1863718ec42c343f0f
data/Gemfile CHANGED
@@ -10,7 +10,7 @@ gemspec
10
10
  # Git. Remember to move these dependencies to your gemspec before releasing
11
11
  # your gem to rubygems.org.
12
12
 
13
- gem 'rails', '~> 4.2'
13
+ gem 'rails', '>= 5.0'
14
14
  gem 'sqlite3'
15
15
 
16
16
  # To use a debugger
data/README.md CHANGED
@@ -15,9 +15,9 @@ And then execute:
15
15
  $ bundle
16
16
 
17
17
 
18
- ## Usage
18
+ ## Get started
19
19
 
20
- There are few steps to setup partial gem booting in a Rails application using Bootinq:
20
+ There are few steps to setup partial gem booting using Bootinq in any ruby application:
21
21
 
22
22
  ### 1. Declare loadable parts
23
23
 
@@ -60,7 +60,9 @@ group :console_boot do
60
60
  end
61
61
  ```
62
62
 
63
- ### 3. Change config/application.rb
63
+ ## Ruby on Rails
64
+
65
+ ### 3. Swap Bundle.require to Bootinq.require
64
66
 
65
67
  Insert `require "bootinq"` to the top of `config/application.rb` file and replace `Bundler.require(*Rails.groups)` with the `Bootinq.require`:
66
68
 
@@ -74,11 +76,10 @@ require 'rails/all'
74
76
  require 'bootinq'
75
77
 
76
78
  # With no additional gem groups:
77
- Bootinq.require
79
+ Bootinq.require(verbose: true)
78
80
  # otherwise, set them like in <tt>Bundle.require(*Rails.groups(*groups))</tt>:
79
81
  # Bootinq.require(:assets => %w(development test))
80
82
 
81
- puts "* Bootinq: loading components #{Bootinq.components * ', '}"
82
83
  ```
83
84
 
84
85
  #### Separate load rails components with Bootinq
@@ -131,6 +132,24 @@ api: env BOOTINQ=a MAX_THREADS=128 bundle exec puma -w 4
131
132
  admin: env BOOTINQ=z bundle exec puma
132
133
  ```
133
134
 
135
+ ## Usage with other frameworks
136
+
137
+ 3. Locate `Bundler.require(...)` in your app and insert `require "bootinq"` above it.
138
+
139
+ 4. Replace located `Bundler.require(...)` line with the `Bootinq.require(...)`.
140
+
141
+ For example, if you are using Grape:
142
+
143
+ ```ruby
144
+ # config/application.rb
145
+
146
+ require 'boot'
147
+ require 'bootinq'
148
+
149
+ # Bundler.require :default, ENV['RACK_ENV']
150
+ Bootinq.require :default, ENV['RACK_ENV'], verbose: true
151
+
152
+
134
153
  ## Development
135
154
 
136
155
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.10"
23
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
24
  end
@@ -1,17 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
  require "singleton"
3
5
  require "forwardable"
4
6
  require "bootinq/component"
7
+ require "bootinq/switch"
5
8
 
6
9
  # = Bootinq
7
10
  #
8
11
  # == Installation
9
12
  #
13
+ # === Ruby on Rails
14
+ #
10
15
  # 1. Insert <tt>require "bootinq"</tt> in the top of <tt>config/application.rb</tt>
11
16
  #
12
17
  # 2. Find <tt>Bundler.require(*Rails.groups)</tt> line below and replace it
13
18
  # with the <tt>Bootinq.require</tt>.
14
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:
27
+ #
28
+ # # config/application.rb
29
+ #
30
+ # require 'boot'
31
+ # require 'bootinq'
32
+ #
33
+ # # Bundler.require :default, ENV['RACK_ENV']
34
+ # Bootinq.require :default, ENV['RACK_ENV'], verbose: true
35
+ # ...
36
+ #
15
37
  # == Example <tt>config/bootinq.yml</tt>:
16
38
  #
17
39
  # env_key: BOOTINQ
@@ -24,7 +46,6 @@ require "bootinq/component"
24
46
  # a: :api
25
47
  # f: :engine
26
48
  class Bootinq
27
- extend SingleForwardable
28
49
  include Singleton
29
50
 
30
51
  DEFAULT = {
@@ -34,62 +55,152 @@ class Bootinq
34
55
  "mount" => {}
35
56
  }.freeze
36
57
 
37
- # The helper method to bootstrap the Bootinq.
38
- # Sets the BOOTINQ_PATH enviroment variable, yields optional block in
39
- # the own instance's binding and, finally, requires selected bundler groups.
40
- def self.require(*groups, verbose: false, &block) # :yields:
41
- ENV['BOOTINQ_PATH'] ||= File.expand_path('../bootinq.yml', caller_locations(1..1)[0].path)
42
-
43
- puts "Bootinq: loading components #{instance.components.join(', ')}" if verbose
44
-
45
- instance.instance_exec(&block) if block_given?
58
+ class << self
59
+ protected def delegated(sym) # :no-doc:
60
+ location = caller_locations(1, 1).first
61
+ file, line = location.path, location.lineno
62
+ definiton = %(def self.#{sym}(*args, &block); instance.#{sym}(*args, &block); end)
63
+ class_eval definiton, file, line
64
+ end
65
+ end
46
66
 
67
+ # :call-seq:
68
+ # Bootinq.require(*groups, verbose: false, &block)
69
+ #
70
+ # Invokes the <tt>Bootinq.init</tt> method with the given verbose key argument & block,
71
+ # and, finally, makes Bundler to require the given groups.
72
+ def self.require(*groups, verbose: false, &block) # :yields: Bootinq.instance
73
+ init(verbose: verbose, &block)
47
74
  Bundler.require(*instance.groups(*groups))
48
75
  end
49
76
 
50
- private_class_method def self.new # :nodoc:
51
- super.freeze
77
+ # :call-seq:
78
+ # Bootinq.setup(*groups, verbose: false, &block)
79
+ #
80
+ # Invokes the <tt>Bootinq.init</tt> method with the given verbose key argument & block,
81
+ # and, finally, makes Bundler to setup the given groups.
82
+ def self.setup(*groups, verbose: false, &block) # :yields: Bootinq.instance
83
+ init(verbose: verbose, &block)
84
+ Bundler.setup(*instance.groups(*groups))
85
+ end
86
+
87
+ # :call-seq:
88
+ # Bootinq.init(verbose: false, &block) -> true or false
89
+ #
90
+ # Initializes itself. Sets the BOOTINQ_PATH enviroment variable if it is missing.
91
+ # To track inquired components use <tt>verbose: true</tt> key argument.
92
+ # Optionally yields block within the own instance's binding.
93
+ def self.init(verbose: false, &block) # :yields: Bootinq.instance
94
+ ENV['BOOTINQ_PATH'] ||= File.expand_path('../bootinq.yml', caller_locations(1..1)[0].path)
95
+
96
+ instance
97
+ instance.instance_variable_set(:@_on_ready, block.to_proc) if block_given?
98
+ puts "Bootinq: loading components #{instance.components.join(', ')}" if verbose
99
+ instance.ready!
52
100
  end
53
101
 
102
+ attr_reader :flags
103
+ attr_reader :components
54
104
 
55
- attr_reader :flags, :components
105
+ delegated :flags
106
+ delegated :components
56
107
 
57
- def initialize
58
- config = YAML.safe_load(File.read(ENV.fetch('BOOTINQ_PATH')), [Symbol]).
59
- merge!(DEFAULT) { |_,l,r| l.nil? ? r : l }
108
+ def initialize # :no-doc:
109
+ config_path = ENV.fetch('BOOTINQ_PATH')
110
+ config = YAML.safe_load(File.read(config_path), [Symbol])
111
+ config.merge!(DEFAULT) { |_, l, r| l.nil? ? r : l }
60
112
 
61
113
  @_value = ENV.fetch(config['env_key']) { config['default'] }
62
- @_neg = @_value.start_with?("-", "^")
114
+ @_neg = @_value.start_with?(?-, ?^)
63
115
  @flags = []
64
116
  @components = []
65
117
 
66
- config['parts'].each { |flag, name| enable_component(flag) { Component.new(name) } }
67
- config['mount'].each { |flag, name| enable_component(flag) { Mountable.new(name) } }
118
+ config['parts'].each { |flag, name| enable_component(name, flag: flag) }
119
+ config['mount'].each { |flag, name| enable_component(name, flag: flag, as: Mountable) }
120
+ end
121
+
122
+ delegated def ready? # :no-doc:
123
+ !!@ready
124
+ end
125
+
126
+ # :call-seq:
127
+ # Bootinq.ready! -> nil or self
128
+ #
129
+ # At the first call marks Bootinq as ready and returns the instance,
130
+ # otherwise returns nil.
131
+ delegated def ready!
132
+ return if ready?
133
+ @ready = true
134
+ if defined?(@_on_ready)
135
+ instance_exec(&@_on_ready)
136
+ remove_instance_variable :@_on_ready
137
+ end
138
+ self
139
+ end
140
+
141
+ # :call-seq:
142
+ # Bootinq.enable_component(name, flag: [, as: Component])
143
+ #
144
+ delegated def enable_component(name, flag:, as: Component)
145
+ if @_neg ^ @_value.include?(flag)
146
+ @flags << flag
147
+ @components << as.new(name)
148
+ end
68
149
  end
69
150
 
70
- # Checks if a given gem (i.e. a gem group) is enabled
71
- def enabled?(gem_name)
72
- components.include?(gem_name)
151
+ # :call-seq:
152
+ # Bootinq.enabled?(name) -> true or false
153
+ #
154
+ # Checks if a component with the given name (i.e. the same gem group)
155
+ # is enabled
156
+ delegated def enabled?(name)
157
+ components.include?(name)
73
158
  end
74
159
 
160
+ # :call-seq:
161
+ # Bootinq.component(name) -> Bootinq::Component
162
+ # Bootinq[name] -> Bootinq::Component
163
+ #
75
164
  # Returns a <tt>Bootinq::Component</tt> object by its name
76
- def component(key)
77
- components[components.index(key)]
165
+ delegated def component(name)
166
+ components[components.index(name)]
78
167
  end
79
168
 
80
169
  alias :[] :component
170
+ delegated :[]
81
171
 
82
- # Enums each mountable component
83
- def each_mountable # :yields:
84
- return to_enum(__method__) unless block_given?
85
- components.each { |part| yield(part) if part.mountable? }
172
+ # :call-seq:
173
+ # Bootinq.each_mountable { |part| block } -> Array
174
+ # Bootinq.each_mountable -> Enumerator
175
+ #
176
+ # Calls the given block once for each enabled mountable component
177
+ # passing that part as a parameter. Returns the array of all mountable components.
178
+ #
179
+ # If no block is given, an Enumerator is returned.
180
+ delegated def each_mountable(&block) # :yields: part
181
+ components.select(&:mountable?).each(&block)
86
182
  end
87
183
 
88
- # Invokes <tt>Rails.groups</tt> method within enabled Bootinq's groups
89
- def groups(*list)
90
- Rails.groups(*components.map(&:group), *list)
184
+ # :call-seq:
185
+ # Bootinq.groups(*groups)
186
+ #
187
+ # Merges enabled Bootinq's groups with the given groups and, if loaded with Rails,
188
+ # passes them to <tt>Rails.groups</tt> method, otherwise just returns the merged list
189
+ # to use with <tt>Bundler.require</tt>.
190
+ delegated def groups(*groups)
191
+ groups.unshift(*components.map(&:group))
192
+ if defined?(Rails)
193
+ Rails.groups(*groups)
194
+ else
195
+ groups
196
+ end
91
197
  end
92
198
 
199
+ # :call-seq:
200
+ # Bootinq.on(name) { block } -> true or false
201
+ # Bootinq.on(any: [names]) { block } -> true or false
202
+ # Bootinq.on(all: [names]) { block } -> true or false
203
+ #
93
204
  # Takes a component's name or single-key options hash as an argument and
94
205
  # yields a given block if the target components are enabled.
95
206
  #
@@ -108,21 +219,61 @@ class Bootinq
108
219
  # Bootinq.on all: %i(frontend backend) do
109
220
  # # do something when frontend and backend are enabled
110
221
  # end
111
- def on(name = nil, any: nil, all: nil) # :yields:
112
- if (any && all) || (name && (any || all))
113
- raise ArgumentError, "expected single argument or one of keywords: `all' or `any'"
114
- elsif name
115
- yield if enabled?(name)
116
- elsif any
117
- yield if any.any? { |part| enabled?(part) }
118
- elsif all
119
- yield if all.all? { |part| enabled?(part) }
120
- else
222
+ delegated def on(name = nil, any: nil, all: nil) # :yields:
223
+ if name.nil? && any.nil? && all.nil?
121
224
  raise ArgumentError, "wrong arguments (given 0, expected 1)"
225
+ elsif (any && all) || (name && (any || all))
226
+ raise ArgumentError, "expected single argument or one of keywords: `all' or `any'"
122
227
  end
228
+
229
+ is_matched =
230
+ name ? enabled?(name) :
231
+ any ? on_any(*any) :
232
+ all ? on_all(*all) : false
233
+ yield if is_matched
234
+ is_matched
123
235
  end
124
236
 
125
- def freeze # :no-doc:
237
+ # :call-seq:
238
+ # Bootinq.on_all(*names) { block } -> true or false
239
+ #
240
+ # Takes a list of component names and yields a given block (optionally)
241
+ # if all of them are enabled. Returns boolean matching status.
242
+ delegated def on_all(*parts) # :yields:
243
+ is_matched = parts.all? { |p| enabled?(p) }
244
+ yield if is_matched && block_given?
245
+ is_matched
246
+ end
247
+
248
+ # :call-seq:
249
+ # Bootinq.on_all(*names) { block } -> true or false
250
+ #
251
+ # Takes a list of component names and yields a given block (optionally)
252
+ # if any of them are enabled. Returns boolean matching status.
253
+ delegated def on_any(*parts) # :yields:
254
+ is_matched = parts.any? { |p| enabled?(p) }
255
+ yield if is_matched && block_given?
256
+ is_matched
257
+ end
258
+
259
+ # :call-seq:
260
+ # Bottinq.switch(*parts) { block } -> nil
261
+ #
262
+ # Collector method.
263
+ #
264
+ # Example:
265
+ #
266
+ # Bootinq.switch do |part|
267
+ # part.frontend { … }
268
+ # part.backend { … }
269
+ # end
270
+ delegated def switch # :yields: Bootinq::Switch.new
271
+ yield(Switch.new)
272
+ nil
273
+ end
274
+
275
+ # Freezes every instance variables and the instance itself.
276
+ def freeze
126
277
  @_value.freeze
127
278
  @_neg.freeze
128
279
  @flags.freeze
@@ -130,12 +281,9 @@ class Bootinq
130
281
  super
131
282
  end
132
283
 
133
- def_delegators "instance", *instance_methods(false)
134
-
135
- private def enable_component(flag) # :yields:
136
- if @_neg ^ @_value.include?(flag)
137
- @flags << flag
138
- @components << yield
139
- end
284
+ def self.new
285
+ super.freeze
140
286
  end
287
+
288
+ private_class_method :new
141
289
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Bootinq
2
4
  class Component
3
5
  attr_reader :intern, :id2name, :group
@@ -18,6 +20,17 @@ class Bootinq
18
20
  false
19
21
  end
20
22
 
23
+ def module_name
24
+ @id2name.camelcase.to_sym
25
+ end
26
+
27
+ def engine
28
+ end
29
+
30
+ def kind_of?(klass)
31
+ super || @intern.kind_of?(klass)
32
+ end
33
+
21
34
  def == other
22
35
  case other
23
36
  when String then other == @id2name
@@ -26,26 +39,44 @@ class Bootinq
26
39
  end
27
40
  end
28
41
 
29
- def inspect
30
- @intern.inspect
42
+ def ===(other)
43
+ case other
44
+ when String then other === @id2name
45
+ when Symbol then other === @intern
46
+ else super
47
+ end
31
48
  end
32
49
 
33
- def engine
50
+ def casecmp(other)
51
+ case other
52
+ when String then @id2name.casecmp(other)
53
+ when Symbol then @intern.casecmp(other)
54
+ when self.class then casecmp(other.to_s)
55
+ end
34
56
  end
35
57
 
36
- def module_name
37
- @id2name.camelcase.to_sym
58
+ def casecmp?(other)
59
+ case other
60
+ when String then @id2name.casecmp?(other)
61
+ when Symbol then @intern.casecmp?(other)
62
+ when self.class then casecmp?(other.to_s)
63
+ end
38
64
  end
39
65
 
40
- def respond_to_missing?(method_name, include_all=false)
41
- @intern.respond_to?(method_name, include_all)
42
- end
66
+ %i(inspect to_proc __id__ hash).
67
+ each { |sym| class_eval %(def #{sym}; @intern.#{sym}; end), __FILE__, __LINE__ + 1 }
43
68
 
44
- private
69
+ %i(encoding empty? length).
70
+ each { |sym| class_eval %(def #{sym}; @id2name.#{sym}; end), __FILE__, __LINE__ + 1 }
45
71
 
46
- def method_missing(method_name, *args, &blk)
47
- @intern.respond_to?(method_name) ? @intern.public_send(method_name, *args, &blk) : super
48
- end
72
+ %i(match match? =~ []).
73
+ each { |sym| class_eval %(def #{sym}(*args); @id2name.#{sym}(*args); end), __FILE__, __LINE__ + 1 }
74
+
75
+ %i(upcase downcase capitalize swapcase succ next).
76
+ each { |sym| class_eval %(def #{sym}; self.class.new(@intern.#{sym}); end), __FILE__, __LINE__ + 1 }
77
+
78
+ alias :slice :[]
79
+ alias :size :length
49
80
  end
50
81
 
51
82
  class Mountable < Component
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Bootinq
4
+ class Switch < ::BasicObject # :no-doc:
5
+ undef_method :==
6
+ undef_method :equal?
7
+
8
+ def raise(*args) # :no-doc:
9
+ ::Object.send(:raise, *args)
10
+ end
11
+
12
+ def method_missing(name, *)
13
+ if ::Bootinq.enabled?(name)
14
+ yield()
15
+ else
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Bootinq
2
- VERSION = "1.0.1"
4
+ VERSION = "1.4.0"
3
5
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootinq
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-07-02 00:00:00.000000000 Z
11
+ date: 2020-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.10'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.10'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  description: Allows to select which bundle groups to boot in the current rails process
42
42
  email:
43
43
  - anton.estum@gmail.com
@@ -58,8 +58,8 @@ files:
58
58
  - lib/bootinq.rb
59
59
  - lib/bootinq.yml
60
60
  - lib/bootinq/component.rb
61
+ - lib/bootinq/switch.rb
61
62
  - lib/bootinq/version.rb
62
- - lib/tasks/bootinq_tasks.rake
63
63
  homepage: https://github.com/estum/bootinq
64
64
  licenses:
65
65
  - MIT
@@ -79,10 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
79
  - !ruby/object:Gem::Version
80
80
  version: '0'
81
81
  requirements: []
82
- rubyforge_project:
83
- rubygems_version: 2.6.6
82
+ rubygems_version: 3.0.3
84
83
  signing_key:
85
84
  specification_version: 4
86
85
  summary: Rails Boot Inquirer
87
86
  test_files: []
88
- has_rdoc:
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :bootinq do
3
- # # Task goes here
4
- # end