bootinq 1.0.1 → 1.4.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
- 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