This gem is intended to mimic Bundler's behavior and conform to bundler configuration options.
stibium-bundled
detects gems.rb
and gems.locked
(or Gemfile
and Gemfile.lock
)
and bundler/setup
(for standalone installation).
standalone
makes a bundle that can work without depending on Bundler (or Rubygems) at runtime. Bundler generates
a bundler/setup.rb
file to replace Bundler's own setup in the manner required.
Configuration settings are loaded in this order:
- Local config (
.bundle/config
or"$BUNDLE_APP_CONFIG/config
) - Environment variables (
ENV
) - Global config (
~/.bundle/config
) - Default config
# file: lib/awesome_gem.rb
require 'stibium/bundled'
module AwesomeGem
include(Stibium::Bundled)
self.bundled_from("#{__dir__}/..", setup: true)
end
or more concise:
# file: lib/awesome_gem.rb
require 'stibium/bundled'
module AwesomeGem
include(Stibium::Bundled).bundled_from("#{__dir__}/..", setup: true)
end
or load a gem depending on status:
# file: lib/awesome_gem.rb
require 'stibium/bundled'
module AwesomeGem
include(Stibium::Bundled).bundled_from("#{__dir__}/..", setup: true) do |bundle|
if Object.const_defined?(:Gem) and bundle.locked? and bundle.installed?
'foo-bar'.tap do |gem_name|
unless bundle.specifications.keep_if { |spec| spec.name == gem_name }.empty?
require gem_name.gsub('-', '/')
end
end
end
end
end
if stibium-bundled
is not system wide installed, it can be necessary to
locate it:
# file: lib/awesome_gem.rb
autoload(:Pathname, 'pathname')
autoload(:RbConfig, 'rbconfig')
module AwesomeGem
Pathname.new("#{__dir__}/..").expand_path.yield_self do |basedir|
begin
require 'stibium/bundled'
rescue LoadError
[
[RUBY_ENGINE, RbConfig::CONFIG.fetch('ruby_version'), 'bundler/gems/*/stibium-bundled.gemspec'],
[RUBY_ENGINE, RbConfig::CONFIG.fetch('ruby_version'), 'gems/stibium-bundled-*/lib/'],
].map { |parts| basedir.join(*['{**/,}bundle'].concat(parts)) }.yield_self do |patterns|
Pathname.glob(patterns).first&.dirname.tap { |gem_dir| require gem_dir.join('lib/stibium/bundled') }
end
end
include(::Stibium::Bundled).bundled_from(basedir, setup: true) do |bundle|
if bundle.locked? and bundle.installed? and Object.const_defined?(:Gem)
require 'fabulous/feature' if bundle.specifications.keep_if { |s| s.name == 'fabulous' }.any?
end
end
end
end
Using Stibium::Bundled
setup leads to minor overhead compared to direct require for bundler/setup
,
on the other hand Stibium::Bundled
setup is compatible with standalone's bundler setup without code change.
And bundle exec
is known to be slow.
Install hypefine and run benchmarks:
rake bench runs=20
Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
---|---|---|---|---|
bundler/setup |
205.7 ± 7.1 | 200.1 | 232.5 | 1.00 ± 0.05 |
bundled |
205.7 ± 6.2 | 196.8 | 222.4 | 1.00 |
bundle exec |
559.4 ± 13.0 | 543.2 | 587.8 | 2.72 ± 0.10 |
bundle config set --local clean 'true'
bundle config set --local path 'vendor/bundle'
bundle install --standalone