class TargetBundle

Attributes

dir[R]
gemfile[R]

Public Class Methods

bundler_version_or_higher(version) click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 4
def self.bundler_version_or_higher(version)
  version_greater_than_or_equal_to_other(Bundler::VERSION, version)
end
default_gemfile() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 12
def self.default_gemfile
  # TODO: Make gems.rb default in Bundler 2.0.
  'Gemfile'
end
new(dir: Dir.pwd, gemfile: TargetBundle.default_gemfile) click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 17
def initialize(dir: Dir.pwd, gemfile: TargetBundle.default_gemfile)
  @dir = dir
  @gemfile = gemfile
end
version_greater_than_or_equal_to_other(a, b) click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 8
def self.version_greater_than_or_equal_to_other(a, b)
  Gem::Version.new(a) >= Gem::Version.new(b)
end

Public Instance Methods

build_ruby_bin(current_ruby_bin, target_ruby_version) click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 62
def build_ruby_bin(current_ruby_bin, target_ruby_version)
  current_ruby_bin.split(File::SEPARATOR).reverse.map do |segment|
    if segment =~ /\d+\.\d+\.\d+/
      segment.gsub(/(\d+\.\d+\.\d+)-*(p\d+)*/, target_ruby_version)
    else
      segment
    end
  end.reverse.join(File::SEPARATOR)
end
gem_home() click to toggle source

Have to run a separate process in the other Ruby, because Gem.default_dir depends on RbConfig::CONFIG which is all special data derived from the active runtime. It could perhaps be redone here, but I'd rather not copy that code in here at the moment.

At one point during development, this would execute Bundler::Settings#path, which in most cases would just fall through to Gem.default_dir … but would give preference to GEM_HOME env variable, which could be in a different Ruby, and that won't work.

# File lib/bundler/patch/target_bundle.rb, line 89
def gem_home
  result = shell_command "#{ruby_bin_exe} -C#{@dir} -e 'puts Gem.default_dir'"
  path = result[:stdout].chomp
  expanded_path = Pathname.new(path).expand_path(@dir).to_s
  puts expanded_path if ENV['BP_DEBUG']
  expanded_path
end
install_bundler_patch_in_target() click to toggle source

To properly update another bundle, bundler-patch does need to live in the same Ruby version because of its dependencies (it's not a self-contained gem), and it can't both act on another bundle location AND find its own dependencies in a separate bundle location.

One known issue: older RubyGems in older Rubies don't install bundler-patch bin in the right directory. Upgrading RubyGems fixes this.

# File lib/bundler/patch/target_bundle.rb, line 103
def install_bundler_patch_in_target
  # TODO: reconsider --conservative flag. Had problems with it in place on Travis, but I think I want it.
  # cmd = "#{ruby_bin}#{File::SEPARATOR}gem install -V --install-dir #{gem_home} --conservative --no-document --prerelease bundler-patch"
  cmd = "#{ruby_bin}#{File::SEPARATOR}gem install -V --install-dir #{gem_home} --no-document --prerelease bundler-patch"
  shell_command cmd
end
ruby_bin(current_ruby_bin=RbConfig::CONFIG['bindir'], target_ruby_version=self.ruby_version) click to toggle source

This is hairy here. All the possible variants will make this mucky, but … can prolly get close enough in many circumstances.

# File lib/bundler/patch/target_bundle.rb, line 48
def ruby_bin(current_ruby_bin=RbConfig::CONFIG['bindir'], target_ruby_version=self.ruby_version)
  [
    target_ruby_version,
    target_ruby_version.gsub(/-p\d+/, ''),
    "ruby-#{target_ruby_version}",
    "ruby-#{target_ruby_version.gsub(/-p\d+/, '')}"
  ].map do |ruby_ver|
    build_ruby_bin(current_ruby_bin, ruby_ver)
  end.detect do |ruby_ver|
    print "Looking for #{ruby_ver}... " if ENV['BP_DEBUG']
    File.exist?(ruby_ver).tap { |exist| puts(exist ? 'found' : 'not found') if ENV['BP_DEBUG'] }
  end
end
ruby_bin_exe() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 72
def ruby_bin_exe
  ruby_install_name = RbConfig::CONFIG['ruby_install_name']
  exe_ext = RbConfig::CONFIG['EXEEXT']
  File.join(ruby_bin, "#{ruby_install_name}#{exe_ext}")
end
ruby_version() click to toggle source

First, the version of Ruby itself:

  1. Look in the Gemfile/lockfile for ruby version

  2. Look for a .ruby-version file

  3. (An additional flag so user can specify?)

Second, look bin path presuming version is in current path.

# File lib/bundler/patch/target_bundle.rb, line 28
def ruby_version
  result = if TargetBundle.bundler_version_or_higher('1.12.0') && File.exist?(lockfile_name)
             lockfile_parser = Bundler::LockfileParser.new(Bundler.read_file(lockfile_name))
             lockfile_parser.ruby_version
           end

  result ||= if File.exist?(ruby_version_filename)
               File.read(File.join(@dir, '.ruby-version')).chomp
             elsif File.exist?(gemfile_name)
               Bundler::Definition.build(gemfile_name, lockfile_name, nil).ruby_version
             end

  result ||= RbConfig::CONFIG['RUBY_PROGRAM_VERSION']

  version, patch_level = result.to_s.scan(/(\d+\.\d+\.\d+)(p\d+)*/).first
  patch_level ? "#{version}-#{patch_level}" : version
end
target_ruby_is_different?() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 78
def target_ruby_is_different?
  !(ruby_bin == RbConfig::CONFIG['bindir'])
end

Private Instance Methods

gemfile_name() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 116
def gemfile_name
  File.join(@dir, @gemfile)
end
lockfile_name() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 120
def lockfile_name
  "#{gemfile_name}.lock"
end
ruby_version_filename() click to toggle source
# File lib/bundler/patch/target_bundle.rb, line 112
def ruby_version_filename
  File.join(@dir, '.ruby-version')
end