167 lines
4.8 KiB
Ruby
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
|