Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gem_helper.rb - comments, fixup Gem::Version vs Gem::Requirement. Fixes #233 #234

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 26 additions & 27 deletions src/testup/gem_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,61 @@
#-------------------------------------------------------------------------------

module TestUp

module GemHelper

# Requires a gem, and installs it as needed.
#
# If a version is specified, a matching gem of `version` or higher will be
# activated if it is already installed. The exact version will be installed otherwise.
#
# If no version is specified, the most recent version will be installed.
#
# @param [String] gem_name
# @param [String] filename
# @param [Gem::Requirement] version
def self.require(gem_name, filename, version: Gem::Requirement.default)
# @param [String, nil] version
def self.require(gem_name, filename, version: nil)
Kernel.require 'rubygems'

# restrict to major value of `version`
requirement = version ? "~> #{version[/\A\d+\.\d+/]}" : ">= 0"

begin
gem gem_name, ">=#{version}"
gem gem_name, requirement
rescue Gem::LoadError
puts "Installing Gem: #{gem_name} (Please wait...)"
begin
self.install(gem_name, version)
rescue Gem::LoadError # rubocop:disable Lint/HandleExceptions
# Needed because of Ruby 2.2. Ruby 2.0 did not need this. Seems like
# a bug. This pattern is probably not that common, to be
# programmatically installing gems.
rescue Gem::LoadError
end
gem gem_name, ">=#{version}"
gem gem_name, requirement
end
Kernel.require filename
end

# @return [String]
def self.local_copy
File.join(__dir__, 'gems')
end

# @return [Array<String>]
def self.local_gems
pattern = File.join(self.local_copy, '*.gem')
Dir.glob(pattern).to_a
end

# @param [String] gem_name
# @param [Gem::Requirement, String] gem_version
# @return [String, nil]
# @param [String, nil] gem_version
# @return [String, nil] the full path to the gem file
def self.find_local_copy(gem_name, gem_version)
self.local_gems.find { |gem_file|
basename = File.basename(gem_file)
name, version = basename.match(/^(.+)-([^-]+)\.gem$/).captures
Dir["#{__dir__}/gems/*.gem"].find { |gem_file|
basename = File.basename(gem_file, '.gem')
name, _, version = basename.rpartition '-'
gem_name.casecmp(name).zero? && gem_version.to_s.casecmp(version).zero?
}
end

# @param [String] gem_name
# @param [Gem::Requirement] version
def self.install(gem_name, version = Gem::Requirement.default)
# @param [String] version
def self.install(gem_name, version = nil)
local_path = self.find_local_copy(gem_name, version)
if local_path
puts '> Installing from local copy...'
puts "> #{local_path}"
Gem.install(local_path, nil, {domain: :local})
puts "> Installed #{gem_name}-#{version}"
else
puts '> Installing from Ruby Gems...'
puts '> Installing from rubygems.org...'
version ||= Gem::Requirement.default
Gem.install(gem_name, version)
end
end
Expand Down
Loading