stibium-bundled 0.0.3 → 0.0.4

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: 63124b549081f71ec8962a7ce60a2d7309cc8a288123744c378e3a504460328d
4
- data.tar.gz: 3002be752eca5c11fb5102d1a3db9374c9cd89535507f27f92154a304a13414b
3
+ metadata.gz: 540a8ad588f6dbeb56f350aa54908bd240c2ec1f321d3885bfa1e5884cf45491
4
+ data.tar.gz: edfeef841ad795136cf3a6c41ea711f00f6029d160d46fb63197daed1cfb36e3
5
5
  SHA512:
6
- metadata.gz: 4503ed903e66d57c352ba2377d127b20485dbf24d761a32571f1775b4c86b864be1142e15ee8ec883909b6fb9b19a18ee204e78ccf13ba0d7eb65b2cfcc9ec91
7
- data.tar.gz: c8c6f97330f328d35c902b4818a90d68dabf53178fc46e3df1fab2acfd077f9a741ce3d8a82ef3f953cd6fff67c4306e66e68973165f92cad3582ea7dcad5f5b
6
+ metadata.gz: c7839c5a74b6e12312fcf17729d3cf315e9242898d718c59f6501dae93bc34fd1da9cc8b1afe9ec1add479d4bd84115121931ead5a630c18caf54a99cac2d1f6
7
+ data.tar.gz: f27014af349f61a57484ed1f4d1d4fb1083c9ef84a0950b7e017f01d0ff82db75c547be623a71e2852fe9d604cc2c538e15d6a1a34ea29a6e5326bc3bada52f3
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ``stibium-bundled`` [![Gem Version](https://badge.fury.io/rb/stibium-bundled.svg)][rubygems:stibium-bundled]
1
+ # ``stibium-bundled`` [![Gem Version](https://badge.fury.io/rb/stibium-bundled.svg)][rubygems:stibium-bundled] [![Maintainability](https://api.codeclimate.com/v1/badges/7121242b44c7a3cc4f61/maintainability)](https://codeclimate.com/github/SwagDevOps/stibium-bundled/maintainability)
2
2
 
3
3
  This gem is intended to mimic Bundler's behavior and conform to [bundler configuration options][bundler:config].
4
4
 
@@ -62,6 +62,49 @@ module AwesomeGem
62
62
  end
63
63
  ```
64
64
 
65
+ if ``stibium-bundled`` is not system wide installed, it can be necessary to
66
+ locate it:
67
+
68
+ ```ruby
69
+ # file: lib/awesome_gem.rb
70
+
71
+ module AwesomeGem
72
+ Pathname.new("#{__dir__}/..").expand_path.tap do |basedir|
73
+ begin
74
+ require 'stibium/bundled'
75
+ rescue LoadError
76
+ basedir.join('{**/,}bundle', RUBY_ENGINE, RUBY_VERSION, '{bundler,}/gems/*/stibium-bundled.gemspec').tap do |s|
77
+ Pathname.glob(s).first&.dirname.tap { |gem_dir| require gem_dir.join('lib/stibium/bundled') }
78
+ end
79
+ end
80
+
81
+ include(::Stibium::Bundled).bundled_from(basedir, setup: true) do |bundle|
82
+ if bundle.locked? and bundle.installed? and Object.const_defined?(:Gem)
83
+ require 'fabulous/feature' if bundle.specifications.keep_if { |s| s.name == 'fabulous' }.any?
84
+ end
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ ## Benchmarks
91
+
92
+ Using ``Stibium::Bundled`` setup leads to minor overhead compared to direct require for ``bundler/setup``,
93
+ on the other hand ``Stibium::Bundled`` setup is compatible with standalone's bundler setup without code change.
94
+ And ``bundle exec`` is known to be [slow][stackoverflow/running-scripts-with-bundle-exec-is-slow].
95
+
96
+ Install [hypefine][sharkdp/hyperfine] and run benchmarks:
97
+
98
+ ```shell
99
+ rake bench runs=20
100
+ ```
101
+
102
+ | Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
103
+ |:---|---:|---:|---:|---:|
104
+ | `bundler/setup` | 205.7 ± 7.1 | 200.1 | 232.5 | 1.00 ± 0.05 |
105
+ | `bundled` | 205.7 ± 6.2 | 196.8 | 222.4 | 1.00 |
106
+ | `bundle exec` | 559.4 ± 13.0 | 543.2 | 587.8 | 2.72 ± 0.10 |
107
+
65
108
  ## Install
66
109
 
67
110
  ```sh
@@ -76,3 +119,5 @@ bundle install --standalone
76
119
  [bundler:config]: https://bundler.io/v2.2/bundle_config.html
77
120
  [bundler:setup]: https://bundler.io/v1.5/bundler_setup.html
78
121
  [man:install#options]: https://bundler.io/man/bundle-install.1.html#OPTIONS
122
+ [sharkdp/hyperfine]: https://github.com/sharkdp/hyperfine
123
+ [stackoverflow/running-scripts-with-bundle-exec-is-slow]: https://stackoverflow.com/questions/13894966/running-scripts-with-bundle-exec-is-slow
@@ -69,12 +69,10 @@ module Stibium::Bundled
69
69
  # @see Stibium::Bundled::Bundle#setup
70
70
  def bundled_from(basedir, setup: false, env: ENV.to_h, ruby_config: {})
71
71
  # @type [Stibium::Bundled::Bundle] bundle
72
- Stibium::Bundled.call(self, basedir: basedir, env: env, ruby_config: ruby_config).bundled.tap do |bundle|
73
- unless bundle.nil?
74
- bundle.__send__(:setup, **(setup.is_a?(Array) ? { guards: setup } : {})) if setup
72
+ Stibium::Bundled.call(self, basedir: basedir, env: env, ruby_config: ruby_config).bundled&.tap do |bundle|
73
+ bundle.__send__(:setup, **{ guards: setup.is_a?(Array) ? setup : nil }.compact) if setup
75
74
 
76
- yield(bundle) if block_given?
77
- end
75
+ yield(bundle) if block_given?
78
76
  end
79
77
  end
80
78
 
@@ -85,18 +83,29 @@ module Stibium::Bundled
85
83
  # @param ruby_config [Hash{Symbol => Object}]
86
84
  #
87
85
  # @return [Class, Module] given ``Class`` or ``Module``
88
- def call(target, basedir:, env: ENV.to_h, ruby_config: {})
86
+ def call(target, basedir:, env: ENV.to_h, ruby_config: nil)
89
87
  target.tap do |t|
90
88
  t.singleton_class.tap do |sc|
91
89
  sc.singleton_class.__send__(:include, self)
92
90
  sc.define_method(:bundled?) { !bundled.nil? }
93
91
  sc.define_method(:bundled) do
94
- # @type [Bundle] bundle
95
- Bundle.new(basedir, env: env, ruby_config: ruby_config)
96
- .yield_self { |bundle| bundle.bundled? ? bundle : nil }
92
+ Stibium::Bundled.__send__(:bundler).call(basedir, env: env, ruby_config: ruby_config)
97
93
  end
98
94
  end
99
95
  end
100
96
  end
97
+
98
+ protected
99
+
100
+ # @api private
101
+ #
102
+ # @return [Proc]
103
+ def bundler
104
+ lambda do |basedir, env:, ruby_config: nil|
105
+ Bundle.new(basedir, env: env, ruby_config: ruby_config).yield_self do |bundle|
106
+ bundle.bundled? ? bundle : nil
107
+ end
108
+ end
109
+ end
101
110
  end
102
111
  end
@@ -67,7 +67,7 @@ class Stibium::Bundled::Bundle
67
67
  #
68
68
  # @return [Array<Gem::Specification>]
69
69
  def specifications
70
- directory.specifications.map { |file| instance_eval(file.read, file.to_path) }
70
+ directory.specifications.map { |file| instance_eval(file.read, file.to_path) }.sort_by(&:name)
71
71
  end
72
72
 
73
73
  # Denote install seems to be happened (since specifications are present).
@@ -110,7 +110,7 @@ class Stibium::Bundled::Bundle
110
110
  #
111
111
  # @return [Boolean]
112
112
  def standalone?
113
- !!bundler_setup
113
+ bundler_setup.yield_self { |fp| fp.file? and fp.readable? }
114
114
  end
115
115
 
116
116
  protected
@@ -119,14 +119,14 @@ class Stibium::Bundled::Bundle
119
119
  #
120
120
  # @return [self]
121
121
  #
122
- # @raise [Errno::ENOENT]
122
+ # @raise [Errno::ENOENT, LoadError]
123
123
  def standalone!(&fallback)
124
- self.tap do
125
- # noinspection RubyResolve
126
- bundler_setup.tap { |fp| require(fp.realpath) unless fp.nil? }
127
- rescue Errno::ENOENT => e
128
- fallback ? fallback.call(self) : raise(e)
129
- end
124
+ # noinspection RubyResolve
125
+ require(bundler_setup.realpath)
126
+ rescue Errno::ENOENT, LoadError => e
127
+ fallback ? fallback.call(self) : raise(e)
128
+ ensure
129
+ self
130
130
  end
131
131
 
132
132
  # Load standalone setup if present, else fallback to <code>bundler/setup</code>.
@@ -146,12 +146,12 @@ class Stibium::Bundled::Bundle
146
146
  # @see https://github.com/ruby/ruby/blob/0e40cc9b194a5e46024d32b85a61e651372a65cb/lib/bundler/setup.rb
147
147
  # @see https://github.com/ruby/ruby/blob/69ed64949b0c02d4b195809fa104ff23dd100093/lib/bundler.rb#L11
148
148
  # @see https://github.com/ruby/ruby/blob/69ed64949b0c02d4b195809fa104ff23dd100093/lib/bundler/rubygems_integration.rb
149
- def setup(guards: [:locked, :installed])
150
- self.standalone! do
151
- guards.map { |s| self.public_send('%s?' % s.to_s.gsub(/\?$/, '')) }.tap do |results|
152
- require 'bundler/setup' if results.uniq == [true]
149
+ def setup(guards: [:bundled, :installed])
150
+ self.tap do
151
+ unless guards.map { |s| self.public_send('%s?' % s.to_s.gsub(/\?$/, '')) }.include?(false)
152
+ standalone! { require 'bundler/setup' }
153
153
  end
154
- end.yield_self { self }
154
+ end
155
155
  end
156
156
 
157
157
  # Standalone setup file.
@@ -166,12 +166,10 @@ class Stibium::Bundled::Bundle
166
166
  # @see #standalone!
167
167
  # @see https://bundler.io/v2.2/man/bundle-install.1.html#OPTIONS
168
168
  #
169
- # @return [Pathname, nil]
169
+ # @return [Pathname]
170
170
  def bundler_setup
171
171
  Pathname.new(config.fetch('BUNDLE_PATH')).yield_self do |bundle_path|
172
- (bundle_path.absolute? ? bundle_path : path.join(bundle_path)).join('bundler/setup.rb').yield_self do |file|
173
- (file.file? and file.readable?) ? file : nil # rubocop:disable Style/TernaryParentheses
174
- end
172
+ (bundle_path.absolute? ? bundle_path : path.join(bundle_path)).join('bundler/setup.rb')
175
173
  end
176
174
  end
177
175
  end
@@ -27,6 +27,11 @@ require_relative '../bundle'
27
27
  # @see .defaults
28
28
  class Stibium::Bundled::Bundle::Config < ::Hash
29
29
  autoload(:Pathname, 'pathname')
30
+ autoload(:YAML, 'yaml')
31
+
32
+ {
33
+ Reader: 'reader',
34
+ }.each { |k, v| autoload(k, "#{__dir__}/config/#{v}") }
30
35
 
31
36
  # @param basedir [String, Pathname]
32
37
  # @param env [Hash{String => String}]
@@ -63,9 +68,6 @@ class Stibium::Bundled::Bundle::Config < ::Hash
63
68
  end
64
69
 
65
70
  class << self
66
- autoload(:Pathname, 'pathname')
67
- autoload(:YAML, 'yaml')
68
-
69
71
  # Default config values (as seen from an empty environment).
70
72
  #
71
73
  # ```shell
@@ -114,9 +116,7 @@ class Stibium::Bundled::Bundle::Config < ::Hash
114
116
  env['HOME'].yield_self do |home_path|
115
117
  return {} if home_path.nil?
116
118
 
117
- Pathname.new(home_path).expand_path.join('.bundle/config').yield_self do |file|
118
- self.read(file, env: env)
119
- end
119
+ Pathname.new(home_path).expand_path.join('.bundle/config').yield_self { |file| self.read(file, env: env) }
120
120
  end
121
121
  end
122
122
 
@@ -143,12 +143,7 @@ class Stibium::Bundled::Bundle::Config < ::Hash
143
143
  #
144
144
  # @return [Hash{String => Object}]
145
145
  def read(file, env: ENV.to_h)
146
- return {} if env(source: env).key?('BUNDLE_IGNORE_CONFIG')
147
-
148
- return {} unless file.file? and file.readable?
149
-
150
- (file.read.yield_self { |content| YAML.safe_load(content) })
151
- .transform_values { |v| v.is_a?(String) ? YAML.safe_load(v) : v }
146
+ Reader.new(env: env).read(file)
152
147
  end
153
148
  end
154
149
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2020-2021 Dimitri Arrigoni <dimitri@arrigoni.me>
4
+ # License GPLv3+: GNU GPL version 3 or later
5
+ # <http://www.gnu.org/licenses/gpl.html>.
6
+ # This is free software: you are free to change and redistribute it.
7
+ # There is NO WARRANTY, to the extent permitted by law.
8
+
9
+ require_relative '../config'
10
+
11
+ # Config file reader.
12
+ class Stibium::Bundled::Bundle::Config::Reader
13
+ autoload(:YAML, 'yaml')
14
+
15
+ # @return [Hash{String => String}]
16
+ attr_reader :env
17
+
18
+ def initialize(env: ENV.to_h)
19
+ self.tap do
20
+ @env = env.dup.map { |k, v| [k.freeze, v.freeze] }.to_h.freeze
21
+ end.freeze
22
+ end
23
+
24
+ # @return [Boolean]
25
+ def ignore_config?
26
+ env.key?('BUNDLE_IGNORE_CONFIG')
27
+ end
28
+
29
+ # Read given config file.
30
+ #
31
+ # @param file [Pathname]
32
+ #
33
+ # @return [Hash{String => Object}]
34
+ def read(file)
35
+ scrutinize(file).transform_values { |v| v.is_a?(String) ? YAML.safe_load(v) : v }
36
+ end
37
+
38
+ protected
39
+
40
+ # @api private
41
+ #
42
+ # @param file [Pathname]
43
+ #
44
+ # @return [Hash{String => Object}]
45
+ def scrutinize(file)
46
+ return {} if ignore_config?
47
+
48
+ return {} unless file.file? and file.readable?
49
+
50
+ file.read.yield_self { |content| YAML.safe_load(content) }
51
+ end
52
+ end
@@ -35,11 +35,14 @@ class Stibium::Bundled::Bundle::Directory
35
35
 
36
36
  # @return [Array<Pathname>]
37
37
  def specifications
38
- [ruby_config.fetch(:engine), ruby_config.fetch(:version), 'specifications', '*.gemspec'].yield_self do |parts|
38
+ [
39
+ [ruby_config.fetch(:engine), ruby_config.fetch(:version), 'specifications', '*.gemspec'],
40
+ [ruby_config.fetch(:engine), ruby_config.fetch(:version), 'bundler', 'gems', '*/*.gemspec'],
41
+ ].map do |parts|
39
42
  self.path.join(*parts).yield_self do |s|
40
43
  Dir.glob(s).sort.map { |fp| Pathname.new(fp) }.keep_if(&:file?)
41
44
  end
42
- end
45
+ end.flatten.sort
43
46
  end
44
47
 
45
48
  protected
@@ -7,8 +7,24 @@
7
7
  # There is NO WARRANTY, to the extent permitted by law.
8
8
 
9
9
  require_relative '../bundled'
10
- require 'kamaze/version'
11
10
 
12
11
  Stibium::Bundled.instance_eval do
13
- self.const_set(:VERSION, Kamaze::Version.new.freeze)
12
+ autoload(:YAML, 'yaml')
13
+ autoload(:Pathname, 'pathname')
14
+
15
+ Pathname.new(__dir__).join('version.yml').tap do |file|
16
+ YAML.safe_load(file.read).yield_self do |v|
17
+ %w[major minor patch].map { |key| v.fetch(key) }.join('.')
18
+ end.tap do |version|
19
+ lambda do
20
+ require 'kamaze/version'
21
+ rescue LoadError
22
+ # :nocov:
23
+ version
24
+ # :nocov:
25
+ else
26
+ Kamaze::Version.new.freeze
27
+ end.tap { |func| self.const_set(:VERSION, func.call) }
28
+ end
29
+ end
14
30
  end
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  major: 0
3
3
  minor: 0
4
- patch: 3
4
+ patch: 4
5
5
  authors: ['Dimitri Arrigoni']
6
6
  email: 'dimitri@arrigoni.me'
7
- date: '2021-01-22'
7
+ date: '2021-02-07'
8
8
  summary: 'Denote bundle state'
9
- description: 'Denote bundle state, based on conventions.'
9
+ description: 'Denote bundle state and (optionally) load bundler/setup according to the configuration.'
10
10
  homepage: 'https://github.com/SwagDevOps/stibium-bundled'
11
11
  licenses: ['GPL-3.0']
12
12
  license_header: |
metadata CHANGED
@@ -1,30 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stibium-bundled
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Arrigoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-22 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: kamaze-version
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
- description: Denote bundle state, based on conventions.
11
+ date: 2021-02-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Denote bundle state and (optionally) load bundler/setup according to
14
+ the configuration.
28
15
  email: dimitri@arrigoni.me
29
16
  executables: []
30
17
  extensions: []
@@ -36,6 +23,7 @@ files:
36
23
  - lib/stibium/bundled.rb
37
24
  - lib/stibium/bundled/bundle.rb
38
25
  - lib/stibium/bundled/bundle/config.rb
26
+ - lib/stibium/bundled/bundle/config/reader.rb
39
27
  - lib/stibium/bundled/bundle/directory.rb
40
28
  - lib/stibium/bundled/version.rb
41
29
  - lib/stibium/bundled/version.yml