Class: Warbler::Traits::Bundler

Inherits:
Object
  • Object
show all
Includes:
BundlerHelper, PathmapHelper, Warbler::Trait
Defined in:
lib/warbler/traits/bundler.rb

Overview

The Bundler trait uses Bundler to determine gem dependencies to be added to the project.

Constant Summary collapse

BUNDLE_CONFIG_DEFAULTS =

Bundler settings enforced in the packed application via a generated .bundle/config, the highest-precedence documented configuration level:

{
  # BUNDLE_VERSION: disable bundler's "auto-switch" to Gemfile.lock's BUNDLED WITH bundler version
  #   (bundler restarts the process to do so, which cannot work inside a servlet container or self-contained executable jar)
  'BUNDLE_VERSION' => 'system',
  # BUNDLE_FROZEN: fail fast with a descriptive error on Gemfile vs Gemfile.lock drift instead of attempting
  #   a runtime re-resolution
  'BUNDLE_FROZEN' => 'true',
  # BUNDLE_PATH__SYSTEM (path.system): pin bundler to the "system" gems - which are the packed gems, via
  #   GEM_HOME/GEM_PATH from *init.rb* - immune to a BUNDLE_PATH/BUNDLE_DEPLOYMENT leaking in from the host's
  #   environment or ~/.bundle/config
  'BUNDLE_PATH__SYSTEM' => 'true',
  # BUNDLE_AUTO_INSTALL: never install gems at boot time, even if the host's environment or global config enables it
  'BUNDLE_AUTO_INSTALL' => 'false'
}.freeze

Instance Attribute Summary

Attributes included from Warbler::Trait

#config

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BundlerHelper

to_spec

Methods included from PathmapHelper

#apply_pathmaps

Methods included from Warbler::Trait

#add_init_load_path, #add_main_rb, included, #initialize, #jruby_jars, #update_gem_path

Class Method Details

.detect?Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/warbler/traits/bundler.rb', line 34

def self.detect?
  File.exist?(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
end

.requirementsObject



38
39
40
# File 'lib/warbler/traits/bundler.rb', line 38

def self.requirements
  [ Traits::War, Traits::Jar ]
end

Instance Method Details

#add_bundler_files(jar) ⇒ Object

Add Bundler Gemfiles, .bundle/config and git repositories to the archive.



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/warbler/traits/bundler.rb', line 96

def add_bundler_files(jar)
  gemfile  = relative_from_pwd(config.bundler[:gemfile])
  lockfile = relative_from_pwd(config.bundler[:lockfile])
  bundle_config = File.join('.bundle', 'config')

  jar.files[apply_pathmaps(config, gemfile, :application)] = config.bundler[:gemfile].to_s
  jar.files[apply_pathmaps(config, lockfile, :application)] = config.bundler[:lockfile].to_s if File.exist?(lockfile)
  # NOTE: in-memory content must be an IO - jar creation treats plain Strings as source file paths
  jar.files[apply_pathmaps(config, bundle_config, :application)] = StringIO.new(bundle_config_contents)

  add_bundler_git_specs(config.bundler[:git_specs], jar) if config.bundler[:git_specs]
end

#add_bundler_gemsObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/warbler/traits/bundler.rb', line 51

def add_bundler_gems; require 'bundler'
  # config.gems.clear allow to add `config.gems` on top of those bundled
  config.gem_dependencies = false # Bundler takes care of these
  config.bundler = {} if config.bundler == true

  warn_on_bundler_version_mismatch

  bundler_specs.each do |spec|
    spec = to_spec(spec)

    case spec.source
    when ::Bundler::Source::Git
      config.bundler[:git_specs] ||= []
      config.bundler[:git_specs] << spec
    when ::Bundler::Source::Path
      unless bundler_source_is_warbled_gem_itself?(spec.source)
        if spec.source.path&.relative?
          # pack the gem at its relative *[APP_ROOT]/gem/path* location - at runtime bundler resolves the path
          # source relative to the packed Gemfile.
          # Deliberately NOT also added to config.gems: bundler never materializes path gems from the gem
          # repository; doing so would cause duplication.
          config.includes += FileList[File.join(spec.source.path, '**/*')]
        else
          warn("Bundler `path' components are not fully supported.\n" +
               "The `#{spec.full_name}' component was not bundled.\n" +
               "Your application may fail to boot!")
        end
      end
    else
      config.gems << spec unless spec.respond_to?(:default_gem?) && spec.default_gem?
    end
  end
  config.bundler[:gemfile]  = ::Bundler.default_gemfile
  config.bundler[:gemfile_path] = apply_pathmaps(config, relative_from_pwd(::Bundler.default_gemfile), :application)
  config.bundler[:lockfile] = ::Bundler.default_lockfile
  path = ::Bundler.settings[:path]
  config.excludes += [path, "#{path}/**/*"] if path
  config.init_contents << "#{config.warbler_templates}/bundler.erb"
end

#after_configureObject



47
48
49
# File 'lib/warbler/traits/bundler.rb', line 47

def after_configure
  add_bundler_gems if config.bundler
end

#before_configureObject



42
43
44
45
# File 'lib/warbler/traits/bundler.rb', line 42

def before_configure
  config.bundler ||= true
  config.bundle_without = ['development', 'test', 'assets']
end

#update_archive(jar) ⇒ Object



91
92
93
# File 'lib/warbler/traits/bundler.rb', line 91

def update_archive(jar)
  add_bundler_files(jar) if config.bundler
end