Accepting request 1085263 from devel:languages:ruby

- cleanup irp code
  - unify error handling using the exit_with_error function
  - ensure we add generated files
  - checkin the newly created package

- move new tools into a subpackage ruby-packaging-helpers to avoid
  dependency to /usr/bin/ruby

- Add 2 new utilities
  - irp aka initialize ruby package
    does exactly what the name says. does all the work to
    initialize a new ruby package
  - bundler-dumpdeps: script to generate BR/Requires based on a
    Gemfile.

OBS-URL: https://build.opensuse.org/request/show/1085263
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/ruby-common?expand=0&rev=24
This commit is contained in:
Dominique Leuenberger 2023-05-08 15:23:46 +00:00 committed by Git OBS Bridge
commit 4a6e1e0f2a
4 changed files with 272 additions and 1 deletions

89
bundler-dumpdeps Normal file
View File

@ -0,0 +1,89 @@
#!/usr/bin/ruby
# vim: set sw=2 sts=2 et tw=80 :
require 'bundler'
require 'optparse'
require 'optparse/time'
require 'logger'
class BundlerDumpRpmDeps
def initialize
@requires_text = "BuildRequires: "
parse_options
process_bundler
end
def process_bundler
#
# TODO: have a commaldine option to specify those.
# e.g. in mastodon you also want to skip the no_docker and heroku group
#
bad_groups = [:test, :development]
bd=Bundler::Dsl.evaluate('Gemfile', 'Gemfile.lock', {})
bd.dependencies.each do |dep|
next if (dep.groups - bad_groups).empty?
# this skips local deps
next if dep.source and not(dep.source.path.nil?)
dep.requirement.requirements.each do |req|
req_str = rpmify(dep.name, *req)
puts "#{@requires_text}%{rubygem #{dep.name}#{req_str}}"
end
end
end
def parse_options
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: bundlerdumpdeps [options]"
opts.separator ""
opts.separator "Specific options:"
opts.on('-b', "Buildtime Requires (default)") do
@requires_text = "BuildRequires: "
end
opts.on('-r', "Runtime Requires") do |args|
@requires_text = "Requires: "
end
end
opt_parser.parse!(ARGV)
end
def expand_pessimistic(version)
splitted = version.to_s.split('.')
sub_version = nil
if splitted.length > 1
end_index = splitted.length-1
end_index = 3 if end_index > 3
sub_version = splitted.slice(0,end_index).join('.')
else
sub_version = splitted[0]
end
":#{sub_version} >= #{version}"
end
# (python3-prometheus_client >= 0.4.0 with python3-prometheus_client < 0.9.0)
def rpmify(dep_name, op, version)
case op
when '~>'
return expand_pessimistic(version)
when '>='
if version != Gem::Version.new(0)
return " #{op} #{version}"
end
when '!='
return " > #{version}"
when '='
return " #{op} #{version}"
when '<'
return " #{op} #{version}"
when '<='
return " =< #{version}"
else
STDERR.puts "Unknown operator '#{op}' called with version '#{version}'"
exit 1
end
end
end
BundlerDumpRpmDeps.new

137
irp.rb Normal file
View File

@ -0,0 +1,137 @@
#!/usr/bin/ruby
# based on my old shell function:
# irp () {
# name="$1"
# suffix="${3:+-$3}"
# versioninfo="${2:+-v $2}"
# r="rubygem-$name$suffix"
# test -d $r && return 1
# mkdir $r
# pushd $r
# cp ../gem2rpm.yml .
# if [ -n "$suffix" ]
# then
# echo ":version_suffix: '$suffix'" >> gem2rpm.yml
# fi
# touch ${r}.spec
# osc vc -m "initial package"
# gem fetch --platform=ruby ${2:+-v $2} $name
# gem2rpm --config gem2rpm.yml -o *spec *gem
# osc add $PWD
# ob-tw && osc ci -m "initial package"
# popd
# }
require 'optparse'
require 'optparse/time'
require 'logger'
require 'fileutils'
class InitializeRubyPackage
def initialize()
@log = Logger.new(STDERR)
@log.level = Logger::INFO
@log.info("Welcome to IRP aka initialize ruby package")
@gem_name, @version_info, @version_suffix = nil
@build_repository = 'openSUSE_Tumbleweed'
@build_results = '../rpms'
parse_options
check_for_existing
smash_and_grab
end
def smash_and_grab
initial_message="initial package"
@log.info("Now starting real work")
FileUtils.mkdir(@package_name)
Dir.chdir(@package_name)
gem2rpm_yml = "../gem2rpm.yml"
if File.exist? gem2rpm_yml
@log.info("Found gem2rpm.yml default file. Copying...")
fc = File.read(gem2rpm_yml)
unless @version_suffix.nil?
@log.info("Appending version suffix setting.")
fc += ":version_suffix: '-#{@version_suffix}'"
end
File.write("gem2rpm.yml", fc)
end
@log.debug("Creating empty spec file for g2r")
FileUtils.touch("#{@package_name}.spec")
@log.debug("Creating initial changes file entry")
exec_with_fail(["osc", "vc", "-m", initial_message])
gem_fetch_cmdline = ["gem", "fetch", "--platform=ruby"]
unless @version_info.nil?
gem_fetch_cmdline << '-v'
gem_fetch_cmdline << @version_info
end
gem_fetch_cmdline << @gem_name
exec_with_fail(gem_fetch_cmdline)
exec_with_fail(["g2r"])
exec_with_fail(["osc", "add", Dir.pwd])
exec_with_fail(["osc", "ar"])
exec_with_fail(["osc", "build", "-p", @build_results, '-k', @build_results, @build_repository])
exec_with_fail(["osc", "ci", "-m", initial_message])
end
def exit_with_error(error_code, error_message)
@log.error(error_message)
exit(error_code)
end
def exec_with_fail(cmdline)
unless(system(*cmdline))
exit_with_error(4, "Executing '#{cmdline.join(' ')}' failed.")
end
end
def check_for_existing
@log.info("Checking for existing #{@package_name}")
if File.directory?(@package_name)
exit_with_error(3, "Package #{@package_name} already exists")
end
end
def parse_options
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: irp [options] [gem name]"
opts.separator ""
opts.separator "Specific options:"
opts.on('-v [version specifier]', 'see gem fetch -v for the parameters') do |version_info|
@version_info = version_info
end
opts.on('-s [package suffix]', 'suffix for the package name') do |suffix|
@version_suffix = suffix
end
opts.on('-b [build repository]', "repository to use for the test build - default #{@build_repository}") do |repo|
@build_repository = repo
end
opts.on('-p [rpms directory]', "directory for built rpms and preferred rpms. default is #{@build_results}") do |args|
@build_results = args
end
end
rest = opt_parser.parse!(ARGV)
if rest.size == 0
exit_with_error(1, "Missing package name")
end
if rest.size > 1
exit_with_error(2, "Too many parameters: #{rest}")
end
@gem_name = rest.first
@package_name = "rubygem-#{@gem_name}"
unless @version_suffix.nil?
@package_name += "-#{@version_suffix}"
end
end
end
InitializeRubyPackage.new()

View File

@ -1,3 +1,27 @@
-------------------------------------------------------------------
Sun May 7 00:35:06 UTC 2023 - Marcus Rueckert <mrueckert@suse.de>
- cleanup irp code
- unify error handling using the exit_with_error function
- ensure we add generated files
- checkin the newly created package
-------------------------------------------------------------------
Tue Mar 21 22:42:33 UTC 2023 - Marcus Rueckert <mrueckert@suse.de>
- move new tools into a subpackage ruby-packaging-helpers to avoid
dependency to /usr/bin/ruby
-------------------------------------------------------------------
Tue Mar 21 18:35:40 UTC 2023 - Marcus Rueckert <mrueckert@suse.de>
- Add 2 new utilities
- irp aka initialize ruby package
does exactly what the name says. does all the work to
initialize a new ruby package
- bundler-dumpdeps: script to generate BR/Requires based on a
Gemfile.
-------------------------------------------------------------------
Thu Feb 9 16:50:32 UTC 2023 - Marcus Rueckert <mrueckert@suse.de>

View File

@ -1,7 +1,7 @@
#
# spec file for package ruby-common
#
# Copyright (c) 2022 SUSE LLC
# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -47,6 +47,8 @@ Source14: gemfile.rb
Source15: rails.macros
Source16: g2r
Source17: rubygems_bundled.attr
Source18: irp.rb
Source19: bundler-dumpdeps
Summary: Collection of scripts and macros for ruby packaging
License: MIT
Group: Development/Languages/Ruby
@ -82,6 +84,18 @@ automatic rpm provides and requires and macros that gem2rpm uses.
Rails packaging support files.
%package -n ruby-packaging-helpers
Requires: %{name} = %{version}-%{release}
Summary: Ruby packaging helpers
Group: Development/Languages/Ruby
%description -n ruby-packaging-helpers
This package is needed for (generated) ruby gems. It provides hooks for
automatic rpm provides and requires and macros that gem2rpm uses.
Some helper tools for packaging rubygems and rails apps.
%prep
%build
@ -105,6 +119,8 @@ install -D -m 0644 %{S:13} %{buildroot}/usr/lib/rpm/fileattrs/gemfile.attr
install -D -m 0755 %{S:14} %{buildroot}/usr/lib/rpm/gemfile.rb
install -D -m 0644 %{S:15} %{buildroot}%{_rpmmacrodir}/macros.rails
install -D -m 0755 %{S:16} %{buildroot}%{_bindir}/g2r
install -D -m 0755 %{S:18} %{buildroot}%{_bindir}/irp
install -D -m 0755 %{S:19} %{buildroot}%{_bindir}/bundler-dumpdeps
install -D -m 0644 %{S:17} %{buildroot}/usr/lib/rpm/fileattrs/rubygems_bundled.attr
%files
@ -124,6 +140,11 @@ install -D -m 0644 %{S:17} %{buildroot}/usr/lib/rpm/fileattrs/rubygems_bundled.a
%{_bindir}/ruby-find-versioned
%{_bindir}/g2r
%files -n ruby-packaging-helpers
%defattr(-,root,root)
%{_bindir}/irp
%{_bindir}/bundler-dumpdeps
%files rails
%defattr(-,root,root)
%{_rpmmacrodir}/macros.rails