ruby/SOURCES/rpm_test_helper.rb

167 lines
4.8 KiB
Ruby

require 'tmpdir'
require 'tempfile'
require 'fileutils'
# Available in Ruby upstream sources under tool/lib/envutil.rb
# Required for finding and setting up the built ruby binary.
require 'envutil'
module RPMTestHelper
def setup
@tmpdir = Dir.mktmpdir
@tempfiles = []
end
def teardown
@tempfiles.each do |file|
file.close
file.unlink
end
FileUtils.rmtree(@tmpdir)
end
GENERATOR_SCRIPT = ENV['GENERATOR_SCRIPT'].clone.freeze
if GENERATOR_SCRIPT.nil? || GENERATOR_SCRIPT == ''
raise "GENERATOR_SCRIPT is not specified." \
"Specify the ENV variable with absolute path to the generator."
end
Dependency = Struct.new('Dependency', :name, :requirements) do
def to_rpm_str
"rubygem(#{self.name})"
end
end
def make_gemspec(gem_info)
file = Tempfile.new('req_gemspec', @tmpdir)
# Fake gemspec with enough to pass most checks
# Rubygems uses to validate the format.
gemspec_contents = <<~EOF
# -*- encoding: utf-8 -*-
# stub: #{gem_info.name} #{gem_info.version} ruby lib
Gem::Specification.new do |s|
s.name = "#{gem_info.name}".freeze
s.version = "#{gem_info.version}"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["John Doe".freeze]
s.bindir = "bin".freeze
s.date = "2023-12-15"
s.description = "Fake gemspec helper for testing Rubygem Generators".freeze
s.email = ["example@example.com".freeze]
s.files = ["LICENSE.txt".freeze, "lib/#{gem_info.name}.rb".freeze, "#{gem_info.name}.gemspec".freeze]
s.homepage = "https://pkgs.fedoraproject.org/rpms/ruby".freeze
s.licenses = ["MIT".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0".freeze)
s.rubygems_version = "3.3.5".freeze
s.summary = "Fake gemspec for testing Rubygem Generators".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
end
if s.respond_to? :add_runtime_dependency then
#{gem_info.gemspec_runtime_dep_str}
else
#{gem_info.gemspec_dep_str}
end
end
EOF
file.write gemspec_contents
file.rewind
@tempfiles << file
file
end
# Caller is expected to close subprocess stdin via #close_write
# in order to let subprocess proceed if the process is reading
# from STDIN in a loop.
def rb_subprocess(*args)
args = [GENERATOR_SCRIPT] if args.empty?
ruby = EnvUtil.rubybin
f = IO.popen([ruby] + args, 'r+') #, external_encoding: external_encoding)
yield(f)
ensure
f.close unless !f || f.closed?
end
def run_generator_single_file(gem_info)
lines = []
gemspec_f = make_gemspec(gem_info)
rb_subprocess do |io|
io.write gemspec_f.path
io.close_write
lines = io.readlines
end
lines
end
def helper_rubygems_dependency
"ruby(rubygems)"
end
class GemInfo
attr_accessor :name, :version, :dependencies
def initialize(name: 'foo', version: '1.2.3', dependencies: [])
@name = name
@version = version
@dependencies = dependencies
end
def dependencies=(other)
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Expected array of `Dependency' elements" \
unless other.is_a?(Array) && other.all? { |elem| elem.respond_to?(:name) && elem.respond_to?(:requirements) }
@dependencies = other
end
def to_rpm_str
"rubygem(#{self.name})"
end
def gemspec_dep_str
return '' if self.dependencies.nil? || self.dependencies.empty?
@dependencies.inject("") do |memo, dep|
memo += if dep.requirements && !dep.requirements.empty?
%Q|s.add_dependency(%q<#{dep.name}>.freeze, #{handle_dep_requirements(dep.requirements)})|
else
%Q|s.add_dependency(%q<#{dep.name}>.freeze)|
end
memo += "\n"
end
end
def gemspec_runtime_dep_str
return '' if self.dependencies.nil? || self.dependencies.empty?
@dependencies.inject("") do |memo, dep|
memo += if dep.requirements && !dep.requirements.empty?
%Q|s.add_runtime_dependency(%q<#{dep.name}>.freeze, #{handle_dep_requirements(dep.requirements)})|
else
%Q|s.add_runtime_dependency(%q<#{dep.name}>.freeze)|
end
memo += "\n"
end
end
private
def handle_dep_requirements(reqs)
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Reqs must be an array." \
unless reqs.is_a? Array
raise ArgumentError, "#{self.class.name}##{__method__.to_s}: Reqs must not be empty for this method." \
if reqs.empty?
'[ "' + reqs.join('", "') + '" ]'
end
end
end