Sha256: fa6b076ff1e572f161ac9a7e58796e3e2a3f277d40459b0d51bd417b9475c477

Contents?: true

Size: 1.61 KB

Versions: 1

Compression:

Stored size: 1.61 KB

Contents

# frozen_string_literal: true
require 'open-uri'
require 'json'

module MatchingBundle
  class << self
    def find_or_install_matching_version(gemfile_content)
      requirements = bundler_requirements(gemfile_content)
      return if requirements.empty?

      if version = find_matching_local_bundler_version(requirements)
        warn "Found bundler #{version}"
        return version
      end

      return unless version = find_matching_remote_bundler_version(requirements)

      warn "Installing bundler #{version}"
      abort unless system "gem", "install", "bundler", "-v", version
      version
    end

    private

    def find_matching_remote_bundler_version(requirements)
      json = open('https://rubygems.org/api/v1/versions/bundler.json').read
      versions = JSON.load(json).map { |v| v["number"] }
      find_satisfied(requirements, versions)
    end

    def find_matching_local_bundler_version(requirements)
      find_satisfied(requirements, installed_bundler_versions)
    end

    def find_satisfied(requirements, versions)
      requirement = Gem::Requirement.new(*requirements)
      versions.reverse.find do |version|
        requirement.satisfied_by? Gem::Version.new(version)
      end
    end

    def installed_bundler_versions
      Gem::Specification.
        find_all { |s| s.name == 'bundler' }.
        map { |spec| spec.version.to_s }
    end

    def bundler_requirements(gemfile_content)
      gemfile_content.
        split("DEPENDENCIES").last.to_s.
        split("Current Bundler version").first.to_s.
        scan(/^\s*bundler \((.*)\)/).flatten.
        flat_map { |r| r.split(", ") }
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
matching_bundle-0.3.1 lib/matching_bundle.rb