From 603fd8a12c3a0ea6619366c287412b194caabb3e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Thu, 2 Jan 2020 22:14:25 +0900 Subject: [PATCH] - move ruby macros and rpm-rubyprov package here, epoch 1 for upgrading --- attr.ruby | 2 + gem_helper.rb | 197 ++++++++++++++++++++++++++++++++++++++++++ macros.ruby | 46 ++++++++++ rpm-build-macros.spec | 38 +++++++- rubygems.rb | 128 +++++++++++++++++++++++++++ 5 files changed, 409 insertions(+), 2 deletions(-) create mode 100644 attr.ruby create mode 100755 gem_helper.rb create mode 100644 macros.ruby create mode 100755 rubygems.rb diff --git a/attr.ruby b/attr.ruby new file mode 100644 index 0000000..fff3530 --- /dev/null +++ b/attr.ruby @@ -0,0 +1,2 @@ +%__ruby_provides %{_rpmconfigdir}/rubygems.rb --provides +%__ruby_requires %{_rpmconfigdir}/rubygems.rb --requires diff --git a/gem_helper.rb b/gem_helper.rb new file mode 100755 index 0000000..6457a7a --- /dev/null +++ b/gem_helper.rb @@ -0,0 +1,197 @@ +#!/usr/bin/ruby +#-- +# Copyright 2010 Per Øyvind Karlsen +# This program is free software. It may be redistributed and/or modified under +# the terms of the LGPL version 2.1 (or later). +#++ + +require 'optparse' +require 'rubygems' + +# Write the .gemspec specification (in Ruby) +def writespec(spec) + file_name = spec.full_name.untaint + '.gemspec' + File.open(file_name, "w") do |file| + file.puts spec.to_ruby_for_cache + end + print "Wrote: %s\n" % file_name +end + +# make gemspec self-contained +if ARGV[0] == "spec-dump" + spec = eval(File.read(ARGV[1])) + writespec(spec) + exit(0) +end + +if ARGV[0] == "build" or ARGV[0] == "install" or ARGV[0] == "spec" + require 'yaml' + require 'zlib' + + filter = nil + opts = nil + keepcache = false + fixperms = false + gemdir = nil + dry_run = false + files = [] + argv = ARGV[1..-1] + # Push this into some environment variables as the modified classes doesn't + # seem to be able to access our global variables.. + ENV['GEM_MODE'] = ARGV[0] + if ARGV[0] == "build" + opts = OptionParser.new("#{$0} <--filter PATTERN>") + opts.on("-f", "--filter PATTERN", "Filter pattern to use for gem files") do |val| + filter = val + end + opts.on("-j", "--jobs JOBS", "Number of jobs to run simultaneously.") do |val| + ENV['jobs'] = "-j"+val + end + opts.on("--dry-run", "Only show the files the gem will include") do + ARGV.delete("--dry-run") + dry_run = true + end + elsif ARGV[0] == "install" + opts = OptionParser.new("#{$0} <--keep-cache>") + opts.on("--keep-cache", "Don't delete gem copy from cache") do + ARGV.delete("--keep-cache") + keepcache = true + end + opts.on("--fix-permissions", "Force standard permissions for files installed") do + ARGV.delete("--fix-permissions") + fixperms = true + end + opts.on("-i", "--install-dir GEMDIR", "Gem repository directory") do |val| + gemdir = val + end + end + while argv.length > 0 + begin + opts.parse!(argv) + rescue OptionParser::InvalidOption => e + e.recover(argv) + end + argv.delete_at(0) + end + + file_data = Zlib::GzipReader.open("metadata.gz") {|io| io.read} + header = YAML::load(file_data) + body = {} + # I don't know any better.. :/ + header.instance_variables.each do |iv| + body[iv.to_s.sub(/^@/,'')] = header.instance_variable_get(iv) + end + + spec = Gem::Specification.from_yaml(YAML.dump(header)) + + if ARGV[0] == "spec" + writespec(spec) + exit(0) + end + + if ARGV[0] == "install" + system("gem %s %s.gem" % [ARGV.join(' '), spec.full_name]) + if !keepcache + require 'fileutils' + FileUtils.rm_rf("%s/cache" % gemdir) + end + if fixperms + chmod = "chmod u+r,u+w,g-w,g+r,o+r -R %s" % gemdir + print "\nFixing permissions:\n\n%s\n" % chmod + system("%s" % chmod) + print "\n" + end + end + + if body['extensions'].size > 0 + require 'rubygems/ext' + module Gem::Ext + class Builder + def self.make(dest_path, results) + make_program = ENV['make'] + unless make_program then + make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make' + end + cmd = make_program + if ENV['GEM_MODE'] == "build" + cmd += " %s" % ENV['jobs'] + elsif ENV['GEM_MODE'] == "install" + cmd += " DESTDIR='%s' install" % ENV['DESTDIR'] + end + results << cmd + results << `#{cmd} #{redirector}` + + raise Gem::ExtensionBuildError, "make failed:\n\n#{results}" unless + $?.success? + end + end + end + + require 'rubygems/installer' + module Gem + class Installer + def initialize(spec, options={}) + @gem_dir = Dir.pwd + @spec = spec + end + end + class ConfigFile + def really_verbose + true + end + end + end + + unless dry_run + Gem::Installer.new(spec).build_extensions + else + for ext in body['extensions'] + files.push(ext[0..ext.rindex("/")-1]+".so") + end + end + + body['extensions'].clear() + end + if ARGV[0] == "build" + body['test_files'].clear() + + # We don't want ext/ in require_paths, it will only contain content for + # building extensions which needs to be installed in sitearchdir anyways.. + idx = 0 + for i in 0..body['require_paths'].size()-1 + if body['require_paths'][idx].match("^ext(/|$)") + body['require_paths'].delete_at(idx) + else + idx += 1 + end + end + + # We'll get rid of all the files we don't really need to install + idx = 0 + for i in 0..body['files'].size()-1 + if filter and body['files'][idx].match(filter) + match = true + else + match = false + for path in body['require_paths'] + if body['files'][idx].match("^%s/" % path) + match = true + end + end + end + if !match + body['files'].delete_at(idx) + else + idx += 1 + end + end + + spec = Gem::Specification.from_yaml(YAML.dump(header)) + unless dry_run + Gem::Builder.new(spec).build + else + files.concat(spec.files) + print "%s\n" % files.join("\n") + end + end +end diff --git a/macros.ruby b/macros.ruby new file mode 100644 index 0000000..e0d309a --- /dev/null +++ b/macros.ruby @@ -0,0 +1,46 @@ +# Ruby specific macro definitions. + +%__ruby /usr/bin/ruby + +# Ruby ABI version +# NOTE: %ruby_version may be empty, depending how Ruby was built +%ruby_abi %{expand:%%global ruby_abi %(%{__ruby} -r rbconfig -e 'print [RbConfig::CONFIG["MAJOR"], RbConfig::CONFIG["MINOR"]].join(".")' 2>/dev/null || echo ERROR)}%ruby_abi + +# get rbconfig parameter +%__ruby_rbconfig() %(%{__ruby} -r rbconfig -e 'print RbConfig::CONFIG["%1"]' 2>/dev/null || echo ERROR) +%__ruby_rbconfig_path() %(%{__ruby} -r rbconfig -r pathname -e 'print Pathname(RbConfig::CONFIG["%1"]).cleanpath' 2>/dev/null || echo ERROR) + +%ruby_archdir %{expand:%%global ruby_archdir %{__ruby_rbconfig_path archdir}}%ruby_archdir +%ruby_libdir %{expand:%%global ruby_libdir %{__ruby_rbconfig rubylibdir}}%ruby_libdir +%ruby_ridir %{expand:%%global ruby_ridir %(%{__ruby} -r rbconfig -e 'print File.join(RbConfig::CONFIG["datadir"], "ri", "system")' 2>/dev/null || echo ERROR)}%ruby_ridir +%ruby_rubylibdir %{expand:%%global ruby_rubylibdir %{__ruby_rbconfig_path rubylibdir}}%ruby_rubylibdir +%ruby_vendorarchdir %{expand:%%global ruby_vendorarchdir %{__ruby_rbconfig vendorarchdir}}%ruby_vendorarchdir +%ruby_vendorlibdir %{expand:%%global ruby_vendorlibdir %{__ruby_rbconfig_path vendorlibdir}}%ruby_vendorlibdir +%ruby_sitearchdir %{expand:%%global ruby_sitearchdir %{__ruby_rbconfig sitearchdir}}%ruby_sitearchdir +%ruby_sitedir %{expand:%%global ruby_sitedir %{__ruby_rbconfig sitedir}}%ruby_sitedir +%ruby_sitelibdir %{expand:%%global ruby_sitelibdir %{__ruby_rbconfig_path sitelibdir}}%ruby_sitelibdir +%ruby_rdocdir /usr/share/rdoc +%ruby_vendordir %{expand:%%global ruby_vendordir %{__ruby_rbconfig vendordir}}%ruby_vendordir +%ruby_version %{expand:%%global ruby_version %(r=%{__ruby_rbconfig ruby_version}; echo ${r:-%%nil})}%ruby_version + +%ruby_gemdir %{expand:%%global ruby_gemdir %(%{__ruby} -r rubygems -e 'puts Gem.respond_to?(:default_dirs) ? Gem.default_dirs[:system][:gem_dir] : Gem.path.first' 2>/dev/null || echo ERROR)}%{ruby_gemdir} +%ruby_specdir %{ruby_gemdir}/specifications + +# deprecated, ruby 2.0 noarch packages are versionless and extension dependency is generated by rpm5 +%ruby_ver_requires_eq %{nil} +%ruby_mod_ver_requires_eq %{nil} + +%__gem_helper %{_usrlibrpm}/gem_helper.rb + +%gem_build(f:j:) \ + %__gem_helper build \\\ + %{-f:-f%{-f*}} \\\ + %{!-j:%{_smp_mflags}}%{-j:-j%{-j*}} + +%gem_install(i:n:C) \ + DESTDIR=${DESTDIR:-%{buildroot}} \\\ + %__gem_helper install \\\ + --env-shebang --rdoc --ri --force --ignore-dependencies \\\ + %{!-i:--install-dir %{buildroot}%{ruby_gemdir}}%{-i:--install-dir %{-i*}} \\\ + %{!-n:--bindir %{buildroot}%{_bindir}}%{-n:--bindir%{-n*}} \\\ + %{!-C:--fix-permissions} diff --git a/rpm-build-macros.spec b/rpm-build-macros.spec index d97f42c..b60127a 100644 --- a/rpm-build-macros.spec +++ b/rpm-build-macros.spec @@ -5,6 +5,7 @@ Summary(pl.UTF-8): Makra do budowania pakietów RPM dla Linuksa PLD Name: rpm-build-macros Version: %{rpm_macros_rev} Release: 2 +Epoch: 1 License: GPL Group: Development/Building Source0: macros.pld @@ -12,6 +13,12 @@ Source1: service_generator.sh Source3: find-lang.sh Source4: dokuwiki-find-lang.sh Source5: macros.kernel + +Source10: attr.ruby +Source11: macros.ruby +Source12: rubygems.rb +Source13: gem_helper.rb + Patch0: disable-systemd.patch #Patchx: %{name}-pydebuginfo.patch BuildRequires: rpm >= 4.4.9-56 @@ -25,8 +32,8 @@ Conflicts: coreutils < 6.9 Conflicts: gettext-devel < 0.11 # tmpdir/_tmppath macros problems; optcppflags missing Conflicts: rpm < 4.4.9-72 -# macros.d/kernel -Conflicts: rpm-build < 5.4.15-6 +# macros.d/ruby +Conflicts: rpm-build < 5.4.15-52 # php-config --sysconfdir Conflicts: php-devel < 4:5.2.0-3 Conflicts: php4-devel < 3:4.4.4-10 @@ -48,6 +55,23 @@ This package contains rpm build macros for PLD Linux. %description -l pl.UTF-8 Ten pakiet zawiera makra rpm-a do budowania pakietów dla Linuksa PLD. +%package -n rpm-rubyprov +Summary: Ruby tools, which simplify creation of RPM packages with Ruby software +Summary(pl.UTF-8): Makra ułatwiające tworzenie pakietów RPM z programami napisanymi w Ruby +Group: Applications/File +Requires: %{name} = %{version}-%{release} +Requires: ruby +Requires: ruby-modules +Requires: ruby-rubygems + +%description -n rpm-rubyprov +Ruby tools, which simplifies creation of RPM packages with Ruby +software. + +%description -n rpm-rubyprov -l pl.UTF-8 +Makra ułatwiające tworzenie pakietów RPM z programami napisanymi w +Ruby. + %prep %setup -qcT cp -p %{SOURCE0} . @@ -84,6 +108,10 @@ install -p service_generator.sh $RPM_BUILD_ROOT%{_usrlibrpm} install -p %{SOURCE3} $RPM_BUILD_ROOT%{_usrlibrpm}/find-lang.sh install -p %{SOURCE4} $RPM_BUILD_ROOT%{_usrlibrpm}/dokuwiki-find-lang.sh +cat %{SOURCE11} %{SOURCE10} >$RPM_BUILD_ROOT%{_usrlibrpm}/macros.d/ruby +install -p %{SOURCE12} $RPM_BUILD_ROOT%{_usrlibrpm}/rubygems.rb +install -p %{SOURCE13} $RPM_BUILD_ROOT%{_usrlibrpm}/gem_helper.rb + %clean rm -rf $RPM_BUILD_ROOT @@ -91,6 +119,12 @@ rm -rf $RPM_BUILD_ROOT %defattr(644,root,root,755) %{_usrlibrpm}/macros.build %{_usrlibrpm}/macros.d/kernel +%{_usrlibrpm}/macros.d/ruby %attr(755,root,root) %{_usrlibrpm}/service_generator.sh %attr(755,root,root) %{_usrlibrpm}/find-lang.sh %attr(755,root,root) %{_usrlibrpm}/dokuwiki-find-lang.sh + +%files -n rpm-rubyprov +%defattr(644,root,root,755) +%attr(755,root,root) %{_usrlibrpm}/gem_helper.rb +%attr(755,root,root) %{_usrlibrpm}/rubygems.rb diff --git a/rubygems.rb b/rubygems.rb new file mode 100755 index 0000000..faeeae0 --- /dev/null +++ b/rubygems.rb @@ -0,0 +1,128 @@ +#!/usr/bin/ruby +#-- +# Copyright 2010 Per Øyvind Karlsen +# This program is free software. It may be redistributed and/or modified under +# the terms of the LGPL version 2.1 (or later). +# +# FIXME: Someone with actual ruby skills should really clean up and sanitize +# this! fugliness obvious... +#++ + +require 'optparse' +require 'rbconfig' + +provides = false +requires = false + +opts = OptionParser.new("#{$0} <--provides|--requires>") +opts.on("-P", "--provides", "Print provides") do |val| + provides = true +end +opts.on("-R", "--requires", "Print requires") do |val| + requires= true +end + +rest = opts.permute(ARGV) + +if rest.size != 0 or (!provides and !requires) or (provides and requires) + $stderr.puts "Use either --provides OR --requires" + $stderr.puts opts + exit(1) +end + +require 'rubygems' +gem_dir = Gem.respond_to?(:default_dirs) ? Gem.default_dirs[:system][:gem_dir] : Gem.path.first +specpatt = "#{gem_dir}/specifications/.*\.gemspec$" +gems = [] +ruby_versioned = false +abi_provide = false +# as ruby_version may be empty, take version from basename of archdir +ruby_version = RbConfig::CONFIG["ruby_version"].empty? ? File.basename(RbConfig::CONFIG["archdir"]) : RbConfig::CONFIG["ruby_version"] + +for path in $stdin.readlines + # way fugly, but we make the assumption that if the package has + # this file, the package is the current ruby version, and should + # therefore provide ruby(abi) = version + if provides and path.match(RbConfig::CONFIG["archdir"] + "/rbconfig.rb") + abi_provide = true + ruby_versioned = true + elsif path.match(specpatt) + gems.push(path.chomp) + # this is quite ugly and lame, but the assumption made is that if any files + # found in any of these directories specific to this ruby version, the + # package is dependent on this specific version. + # FIXME: only supports current ruby version + elsif not ruby_versioned + if path.match(RbConfig::CONFIG["rubylibdir"]) + ruby_versioned = true + elsif path.match(RbConfig::CONFIG["archdir"]) + ruby_versioned = true + elsif path.match(RbConfig::CONFIG["sitelibdir"]) + ruby_versioned = !RbConfig::CONFIG["ruby_version"].empty? + elsif path.match(RbConfig::CONFIG["sitearchdir"]) + ruby_versioned = true + elsif path.match(RbConfig::CONFIG["vendorlibdir"]) + ruby_versioned = !RbConfig::CONFIG["ruby_version"].empty? + elsif path.match(RbConfig::CONFIG["vendorarchdir"]) + ruby_versioned = true + end + end +end + +if requires or abi_provide + abidep = "ruby(abi)" + if ruby_versioned + abidep += " = %s" % ruby_version + end + print abidep + "\n" +end + +if gems.length > 0 + require 'rubygems' + + if requires + + module Gem + class Requirement + def rpm_dependency_transform(name, version) + pessimistic = "" + if version == "> 0.0.0" or version == ">= 0" + version = "" + else + if version[0..1] == "~>" + pessimistic = "rubygem(%s) < %s\n" % [name, Gem::Version.create(version[3..-1]).bump] + version = version.gsub(/\~>/, '=>') + end + if version[0..1] == "!=" + version = version.gsub(/\!=/, '>') + end + version = version.sub(/^/, ' ') + end + version = "rubygem(%s)%s\n%s" % [name, version, pessimistic] + end + + def to_rpm(name) + result = as_list + return result.map { |version| rpm_dependency_transform(name, version) } + end + + end + end + end + + for gem in gems + data = File.read(gem) + spec = eval(data) + if provides + print "rubygem(%s) = %s\n" % [spec.name, spec.version] + end + if requires + for d in spec.dependencies + print d.requirement.to_rpm(d.name)[0] unless d.type != :runtime + end + for d in spec.required_rubygems_version.to_rpm("rubygems") + print d.gsub(/(rubygem\()|(\))/, "") + end + end + end +end -- 2.43.0