diff --git a/gem_build_cleanup b/gem_build_cleanup new file mode 100644 index 0000000000000000000000000000000000000000..f1a41953ed833f37eaacb83a916d628202fee4d6 --- /dev/null +++ b/gem_build_cleanup @@ -0,0 +1,16 @@ +#!/bin/sh +if [ ${#*} = 1 ] ; then + if [ -d "$1" ] ; then + find $1 \ + \( -name \*.o -o -name Makefile -o -name config.log -o -name config.status -o -name Makefile.html -o -name gem_make.out -o -name mkmf.log -o -name \*.bak -o -name .deps -o -name .libs -o -name CVS \) \ + -print0 | xargs -r0 rm -rv || : + # remove more strict in the docu + find $1/doc \( -name Makefile.ri -o -name ext -o -name page\*.ri \) -print0 | xargs -r0 rm -rv || : + else + echo "'$1' does not exists or is not a directory! Exiting." >&2 + exit 1 + fi +else + echo "Please pass exact one argument to this script! Exiting." >&2 + exit 1 +fi diff --git a/gem_install.sh b/gem_install.sh new file mode 100644 index 0000000000000000000000000000000000000000..866aa782e26fc766d3079fee307bdf5935d8040e --- /dev/null +++ b/gem_install.sh @@ -0,0 +1,249 @@ +#!/bin/sh +# vim: set sw=2 sts=2 et tw=80 ft=ruby: +=begin &>/dev/null +# workaround for rubinius bug +# https://github.com/rubinius/rubinius/issues/2732 +export LC_ALL="en_US.UTF-8" +export LANG="en_US.UTF-8" +shopt -s nullglob +for ruby in $(/usr/bin/ruby-find-versioned) ; do + $ruby -x $0 "$@" +done +exit $? +=end +#!/usr/bin/ruby +require 'rbconfig' +require 'optparse' +require 'optparse/time' +require 'ostruct' +require 'fileutils' +require 'find' +require 'tempfile' +require 'logger' +require 'rubygems' +require 'rubygems/package' +begin + require 'rubygems/format' +rescue LoadError => ex +end +begin + require 'rbconfigpackagingsupport' +rescue LoadError => ex +end + +options=OpenStruct.new +options.defaultgem=nil +options.gemfile=nil +options.otheropts=nil +options.buildroot=nil +options.docfiles=[] +options.gemname=nil +options.gemversion=nil +options.gemsuffix=nil +options.otheropts=[] +options.ua_dir='/etc/alternatives' +options.docdir='/usr/share/doc/packages' +# once we start fixing packages set this to true +options.symlinkbinaries=false +options.verbose = false +options.rpmsourcedir = ENV['RPM_SOURCE_DIR'] || '/home/abuild/rpmbuild/SOURCES' +options.rpmbuildroot = ENV['RPM_BUILD_ROOT'] || '/home/abuild/rpmbuild/BUILDROOT/just-testing' + +GILogger = Logger.new(STDERR) +GILogger.level=Logger::DEBUG +def bail_out(msg) + GILogger.error(msg) + exit 1 +end + +def patchfile(fname, needle, replace) + tmpdir = File.dirname(fname) + tmp = Tempfile.new('snapshot', tmpdir) + begin + stat = File.stat(fname) + tmp.chmod(stat.mode) + fc = File.read(fname) + # fc.gsub!(/^(#!\s*.*?)(\s+-.*)?$/, "#!#{ruby} \2") + fc.gsub!(needle, replace) + tmp.write(fc) + tmp.close + File.rename(tmp.path, fname) + rescue ArgumentError => ex + GILogger.error "Exception while patching '#{fname}'. (#{ex}) Skipping ..." + ensure + tmp.close + end +end + +opt_parser = OptionParser.new do |opts| + opts.banner = "Usage: gem_install.rb [options]" + + opts.separator "" + opts.separator "Specific options:" + + opts.on('--config [FILENAME]', 'path to gem2rpm.yml') do |name| + options.config = name + end + + opts.on('--default-gem [FILENAME]', 'Which filename to use when we dont find another gem file.') do |fname| + options.defaultgem=fname + end + opts.on('--gem-binary [PATH]', 'Path to gem. By default we loop over all gem binaries we find') do |fname| + GILogger.warn("The --gem-binary option is deprecated.") + end + opts.on('--doc-files [FILES]', 'Whitespace separated list of documentation files we should link to /usr/share/doc/packages/') do |files| + options.docfiles = files.split(/\s+/) + end + opts.on('--gem-name [NAME]', 'Name of them gem') do |name| + options.gemname = name + end + opts.on('--gem-version [VERSION]', 'Version of them gem') do |version| + options.gemversion = version + end + opts.on('--gem-suffix [SUFFIX]', 'Suffix we should append to the subpackage names') do |suffix| + options.gemsuffix = suffix + end + opts.on('--build-root [BUILDROOT]', 'Path to rpm buildroot') do |buildroot| + options.buildroot = buildroot + end + # Boolean switches + opts.on('--[no-]symlink-binaries', 'Create all the version symlinks for the binaries') do |v| + options.symlinkbinaries = v + end + opts.on('-d', 'Forwarded to gem install') do |v| + options.otheropts << '-d' + end + opts.on('-f', 'Forwarded to gem install') do |v| + options.otheropts << '-f' + end + opts.on('-E', 'Forwarded to gem install') do |v| + options.otheropts << '-E' + end + opts.on('--no-ri', 'Forwarded to gem install') do |v| + options.otheropts << '--no-ri' + end + opts.on('--no-rdoc', 'Forwarded to gem install') do |v| + options.otheropts << '--no-rdoc' + end + opts.separator "" + opts.separator "Common options:" + opts.on("-v", "--[no-]verbose", "Run verbosely") do |v| + options.verbose = v + end + opts.on_tail('-h', '--help', 'Show this message') do + puts opts + exit + end +end + +options.otheropts+=opt_parser.parse!(ARGV) +GILogger.info "unhandled options: #{options.otheropts.inspect}" +if options.gemfile.nil? + # we are in /home/abuild/rpmbuild/BUILD/ + # search for rebuild gem files + gemlist = Dir['*/*.gem', '*/*/.gem', "#{options.rpmsourcedir}/*.gem"] + if gemlist.empty? + bail_out("Can not find any gem file") + end + options.gemfile = gemlist.first + GILogger.info "Found gem #{options.gemfile}" +end + +package = Gem::Package.new(options.gemfile) rescue Gem::Format.from_file_by_path(options.gemfile) +spec = package.spec +gemdir = File.join(Gem.dir, 'gems', "#{options.gemname}-#{options.gemversion}") +# TODO: ruby = "#{File.join(RbConfig::CONFIG['bindir'],RbConfig::CONFIG['ruby_install_name'])}mo" +ruby = Gem.ruby +gembinary = Gem.default_exec_format % "/usr/bin/gem" + +rubysuffix = Gem.default_exec_format % '' +case rubysuffix + when /\A\d+.\d+\z/ + options.rubysuffix = ".ruby#{rubysuffix}" + options.rubyprefix = "ruby#{rubysuffix}" + when /\A\.(.*)\z/ + options.rubysuffix = ".#{$1}" + options.rubyprefix = $1 + when '' + # TODO: case seems broken + rb_ver = RbConfig::CONFIG['ruby_version'].gsub(/^(\d+\.\d+).*$/, "\1") + options.rubysuffix = ".ruby#{rb_ver}" + options.rubyprefix = "ruby#{rb_ver}" + else + bail_out "unknown binary naming scheme: #{rubysuffix}" +end +GILogger.info "Using prefix #{options.rubyprefix}" +GILogger.info "Using suffix #{options.rubysuffix}" + +cmdline = [gembinary, 'install', '--verbose', '--local', '--build-root', options.buildroot] +cmdline += options.otheropts +cmdline << options.gemfile +GILogger.info "install cmdline: #{cmdline.inspect}" +if Process.respond_to? :spawn + pid = Process.spawn(*cmdline) + pid, status = Process.wait2(pid) +else + system(*cmdline) + status = $? +end +exit status.exitstatus unless 0 == status.exitstatus + +rpmname="#{options.rubyprefix}-rubygem-#{options.gemname}#{options.gemsuffix}" +GILogger.info "RPM name: #{rpmname}" +pwd = Dir.pwd +bindir = File.join(options.rpmbuildroot, Gem.bindir) +GILogger.info "bindir: #{bindir}" +if options.symlinkbinaries && File.exists?(bindir) + br_ua_dir = File.join(options.rpmbuildroot, options.ua_dir) + GILogger.info "Creating upate-alternatives dir: #{br_ua_dir}" + FileUtils.mkdir_p(br_ua_dir) + begin + Dir.chdir(bindir) + GILogger.info "executables: #{spec.executables.inspect}" + spec.executables.each do |unversioned| + default_path = Gem.default_exec_format % unversioned + full_versioned = "#{unversioned}#{options.rubysuffix}-#{spec.version}" + ruby_versioned = "#{unversioned}#{options.rubysuffix}" + gem_versioned = "#{unversioned}-#{spec.version}" + File.rename(default_path, full_versioned) + patchfile(full_versioned, />= 0(\.a)?/, "= #{options.gemversion}") + # unversioned + [unversioned, ruby_versioned, gem_versioned].each do |linkname| + full_path = File.join(br_ua_dir, linkname) + ua_path = File.join(options.ua_dir, linkname) + GILogger.info "Linking '#{linkname}' to '#{full_path}'" + File.symlink(linkname, full_path) unless File.symlink? full_path + GILogger.info "Linking '#{ua_path}' to '#{linkname}'" + File.symlink(ua_path, linkname) unless File.symlink? linkname + end + end + ensure + Dir.chdir(pwd) + end +end + +# shebang line fix +Find.find(File.join(options.buildroot, gemdir)) do |fname| + if File.file?(fname) && File.executable?(fname) + next if fname =~ /\.so$/ + GILogger.info "Looking at #{fname}" + patchfile(fname, /^(#!\s*.*(?:rub|rbx).*?)(\s+-.*)?$/, "#!#{ruby} \\2") + else + next + end +end + +unless options.docfiles.empty? + GILogger.info "Linking documentation" + docdir = File.join(options.rpmbuildroot, options.docdir, rpmname) + FileUtils.mkdir_p(docdir) + + options.docfiles.each do |fname| + fullpath = File.join(gemdir, fname) + GILogger.info "- #{fullpath}" + File.symlink(fullpath, File.join(docdir,fname)) + end +end + +system("chmod -R u+w,go+rX,go-w #{options.rpmbuildroot}") +#system("find #{options.rpmbuildroot} -ls") diff --git a/gem_packages.sh b/gem_packages.sh new file mode 100644 index 0000000000000000000000000000000000000000..9da2c535bf1b2cd9317f170ab17aedc28dc21bc1 --- /dev/null +++ b/gem_packages.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# we always start in /home/abuild but in older distros we wouldnt find the sources that way. +# switch to /usr/src/packages/ +if [ ! -d $PWD/rpmbuild ] ; then + cd /usr/src/packages/ +fi +shopt -s nullglob +# options may be followed by one colon to indicate they have a required argument +if ! options=$(getopt -o dEf -l default-gem:,build-root:,gem-name:,gem-version:,gem2rpm-config: -- "$@") +then + # something went wrong, getopt will put out an error message for us + exit 1 +fi + +eval set -- "$options" + +otheropts="--local -t /usr/lib/rpm/gem_packages.template" +defaultgem= +buildroot= +gemfile= +gemname= +gemversion= + +while [ $# -gt 0 ] +do + case $1 in + --default-gem) defaultgem=$2 ; shift;; + --gem-name) gemname="$2" ; shift;; + --gem-version) gemversion="$2" ; shift;; + --build-root) buildroot=$2; shift;; + --gem2rpm-config) gem_config=$2; shift;; + (--) ;; + (-*) otheropts="$otheropts $1";; + (*) gemfile=$1; otheropts="$otheropts $1"; break;; + esac + shift +done + +if [ "x$gem_config" = "x" ] ; then + gem_config=$(find $RPM_SOURCE_DIR -name "*gem2rpm.yml") + if [ "x$gem_config" != "x" ] ; then + otheropts="$otheropts --config=$gem_config" + fi +fi + +if [ "x$gemfile" = "x" ] ; then + gemfile=$(find . -maxdepth 2 -type f -name "$defaultgem" -not -path \*/.gem/\* | head -n 1) + # if still empty, we pick the sources + if [ "x$gemfile" = "x" ] ; then + gemfile=$(find $RPM_SOURCE_DIR -name "$defaultgem") + fi + otheropts="$otheropts $gemfile" +fi +# workaround for rubinius bug +# https://github.com/rubinius/rubinius/issues/2732 +export LC_ALL="en_US.UTF-8" +export LANG="en_US.UTF-8" +set -x +for gr in $(/usr/bin/ruby-find-versioned gem2rpm) ; do + $gr $otheropts +done diff --git a/gemrc b/gemrc new file mode 100644 index 0000000000000000000000000000000000000000..b55f7d408ed065c02c6a6850ea34342d266ac8ed --- /dev/null +++ b/gemrc @@ -0,0 +1,13 @@ +--- +:benchmark: false +:install: --format-executable --no-user-install +install: --format-executable --no-user-install +:backtrace: true +:update_sources: true +:format_executable: true +:verbose: true +:update: --format-executable --no-user-install +update: --format-executable --no-user-install +:bulk_threshold: 1000 +:sources: +- https://rubygems.org diff --git a/generate_buildrequires.sh b/generate_buildrequires.sh new file mode 100644 index 0000000000000000000000000000000000000000..dced73619f343ed8957d49704f8b5475a03acef9 --- /dev/null +++ b/generate_buildrequires.sh @@ -0,0 +1,212 @@ +#!/bin/sh +# +# In the current package's specfile, updates a block delimited +# by "# BEGIN" / "# END" lines to contain BuildRequires: lines +# for each rubygem rpm (or rpm matching a given pattern) which +# has been built by the project. +# +# This gives us project-build-time dependency checking without the +# performance impact that specifying BuildRequires lines within +# each gem would cause. For more information, see: +# +# http://en.opensuse.org/openSUSE:Packaging_Ruby#Compensating_for_lack_of_BuildRequires +# +# Usage: +# ------ +# +# 1. Ensure you have an "all-rubygems-good" package or similar +# in your project. If in doubt, copy the one from +# devel:languages:ruby:extensions. +# +# 2. cd to a working copy +# +# If you're feeling lazy, you are probably fine skipping the next two +# steps. +# +# 3. Run this script with the -l option and make sure you understand +# any differences between each repository/arch combination in the +# numbers of matching gems found. +# +# 4. If you don't, run with -l REPO ARCH to compare individual lists +# of matching gems. +# +# 5. If you want a BuildRequires: list of matching gems from *all* +# repo/arch combinations, run again with no arguments. +# +# OR +# +# If you want a BuildRequires: list of matching gems from a specific +# repo/arch combinations, run again with REPO ARCH as arguments. +# +# 6. osc diff to review the changes to the spec file, then osc commit. + +me=`basename $0` + +DEFAULT_PATTERN="rubygem-" + +main () { + parse_opts "$@" + + if [ -z "$project" ]; then + project=$( osc info | sed -ne '/^Project name: / { s///; p }' ) + if [ -z "$project" ]; then + echo "Couldn't establish build service project name." >&2 + echo "Are you inside a package working directory?" >&2 + exit 1 + fi + fi + echo "Project: $project" + + case "$project" in + home:*:branches:*) + cat <&2 + +WARNING: you are running this in a branch. + +You probably need to specify the parent project via -P, +otherwise you may not get the dependencies you want. + +EOF + ;; + esac + + specfile=$( ls -1 *.spec ) + if ! [ -f "$specfile" ]; then + echo "Couldn't find spec file." >&2 + echo "Are you inside a package working directory?" >&2 + exit 1 + fi + + if [ -n "$list" ]; then + if [ -n "$repo" ]; then + get_buildrequires_lines "$repo" "$arch" + else + list_matches + fi + else + if [ -n "$repo" ]; then + get_buildrequires_lines "$repo" "$arch" | update_spec + else + find_all_matches | update_spec + fi + fi +} + +usage () { + # Call as: usage [EXITCODE] [USAGE MESSAGE] + case "$1" in + [0-9]) + exit_code="$1" + shift + ;; + *) + exit_code=1 + ;; + esac + if [ -n "$1" ]; then + echo "$*" >&2 + echo + fi + + cat <&2 +Usage: $me [options] [REPOSITORY ARCH] +Options: + -h, --help Show this help and exit + -l, --list List matching rpms for the given repository / arch. + If no repository specified, show counts of matching + rpms per repository / arch. + -P, --project=PROJ Retrieve rpm lists from PROJ, not the current project. + -p, --pattern=PAT Set the pattern to match rpms by [$DEFAULT_PATTERN] +EOF + exit "$exit_code" +} + +parse_opts () { + list= + project= + pattern="$DEFAULT_PATTERN" + + while [ $# != 0 ]; do + case "$1" in + -h|--help) + usage 0 + ;; + -l|--list) + list=y + shift + ;; + -p|--pattern) + pattern="$2" + shift 2 + ;; + -P|--project) + project="$2" + shift 2 + ;; + -*) + usage "Unrecognised option: $1" + ;; + *) + break + ;; + esac + done + + if [ $# = 1 ]; then + usage "Insufficient arguments." + fi + + if [ $# -gt 2 ]; then + usage "Too many arguments." + fi + + repo="$1" + arch="$2" +} + +get_buildrequires_lines () { + repo="$1" arch="$2" + osc api "/build/$project/$repo/$arch/_repository" | \ + grep "binary .*filename=\"$pattern" | \ + sed -e 's,.* &2 + get_buildrequires_lines "$repo" "$arch" + done | sort -u +} + +edit_spec () { + sed -n -e '1,/BEGIN/p' $specfile + echo "# Automatically generated by $0" + echo "# on `date`" + echo "# See http://en.opensuse.org/openSUSE:Packaging_Ruby#Compensating_for_lack_of_BuildRequires" + cat + sed -n -e '/END/,$p' $specfile +} + +update_spec () { + if edit_spec > $specfile.new; then + mv $specfile.new $specfile + echo "Updated spec: $specfile" + else + echo "Failed to generate new spec file contents; aborting." >&2 + exit 1 + fi +} + +main "$@" diff --git a/openEuler.spec.erb b/openEuler.spec.erb new file mode 100644 index 0000000000000000000000000000000000000000..6add6a75fcbda6ade680f6ef72daef00a79e00d8 --- /dev/null +++ b/openEuler.spec.erb @@ -0,0 +1,249 @@ +<% + + begin + require 'rbconfigpackagingsupport' + rescue LoadError => ex + end + def self.patch_mod_full_name(path, mod_full_name) + path.gsub(/\/-/, "/#{mod_full_name}") + end + + def self.patch_libdir(path) + # path ? path.gsub(/\/usr\/lib(64)?/, '%{_libdir}') : path + path + end + + def self.get_extension_doc_dir(gem_spec) + return nil unless Gem.ruby_engine == 'ruby' && Gem::Requirement.new("~> 2.1.0").satisfied_by?(Gem.ruby_version) + if gem_spec.respond_to?(:extensions_dir) + rp = gem_spec.extensions_dir.rpartition(gem_spec.base_dir) + return File.join(rp[1], 'doc', rp[2]) + end + return nil + end + + def self.get_mod_weight(spec) + versions=spec.version.to_s.split('.') + begin v1=Integer(versions[0]) rescue v1=1 end + begin v2=Integer(versions[1]) rescue v2=0 end + begin v3=Integer(versions[2]) rescue v3=0 end + weight=v1*10000+v2*100+v3 + end + + def self.filecontent_or_value(path) + (path and File.exists?(path)) ? File.read(path) : path + end + + def self.parse_custom_pkgs(env_value) + custom_pkgs = {} + if env_value + list = env_value.split(/\s+/) + list.each do |element| + pkg_name,filelist_path, preamble, description = element.split(/\|/, 4) + filelist = filecontent_or_value(filelist_path) + preamble = filecontent_or_value(preamble) + description = filecontent_or_value(description) + custom_pkgs[pkg_name] = { + "filelist" => filelist, + "preamble" => preamble, + "description" => description, + } + end + end + custom_pkgs + end + + rb_suffix = RbConfig::CONFIG['ruby_install_name'].gsub(/^ruby/, '') + rb_pkgname = RbConfig::CONFIG['ruby_install_name'].gsub(/^ruby\./, '') + if rb_suffix =~ /\A\d+\.\d+\z/ + rb_suffix = '.ruby' + rb_suffix + end + pkg_basename = rb_pkgname + '-rubygem-' + spec.name + + mod_full_name = "#{spec.name}-#{spec.version}" + mod_weight = get_mod_weight(spec) + + gem_platform = Gem::Platform.new(RbConfig::CONFIG["arch"]).to_s + rb_bindir = RbConfig::CONFIG['bindir'] + rb_sysconfdir = RbConfig::CONFIG['sysconfdir'] + docdir = '/usr/share/doc/packages' + gem_spec = Gem::Specification.new + gem_base_dir = patch_libdir(gem_spec.base_dir) + gem_cache_dir = patch_libdir(gem_spec.cache_dir) + gem_gems_dir = patch_libdir(gem_spec.gems_dir) + gem_spec_dir = patch_libdir(gem_spec.spec_dir) + gem_bin_dir = patch_libdir(patch_mod_full_name(gem_spec.bin_dir , mod_full_name )) + gem_doc_dir = patch_libdir(patch_mod_full_name(gem_spec.doc_dir, mod_full_name )) + gem_gem_dir = patch_libdir(patch_mod_full_name(gem_spec.gem_dir, mod_full_name )) + gem_ri_dir = patch_libdir(patch_mod_full_name(gem_spec.ri_dir, mod_full_name )) + #ruby2.1 + gem_extensions_dir = gem_spec.respond_to?(:extensions_dir) ? patch_libdir(gem_spec.extensions_dir) : nil + gem_extension_dir = gem_spec.respond_to?(:extension_dir) ? patch_libdir(patch_mod_full_name(gem_spec.extension_dir, mod_full_name)) : nil + gem_extension_doc = patch_libdir(get_extension_doc_dir(gem_spec)) + #/ruby2.1 +%> +%package -n <%= pkg_basename %><%= config[:version_suffix] %> +# MANUAL +<% if config[:main] && config[:main][:preamble] -%> +<%= config[:main][:preamble] %> +<% end -%> +# /MANUAL +Summary: <%= config[:summary] or spec.summary %> +Group: Development/Languages/Ruby +<% unless spec.executables.empty? -%> +PreReq: update-alternatives +<% end -%> + +%description -n <%= pkg_basename %><%= config[:version_suffix] %> +<%= config[:description] or spec.description -%> + +<% if spec.has_rdoc && !(config[:disable_docs]) -%> +%package -n <%= pkg_basename %>-doc<%= config[:version_suffix] %> +Summary: RDoc documentation for <%= spec.name %> +Group: Development/Languages/Ruby +Requires: <%= pkg_basename %><%= config[:version_suffix] %> = <%= spec.version %> + +%description -n <%= pkg_basename %>-doc<%= config[:version_suffix] %> +Documentation generated at gem installation time. +Usually in RDoc and RI formats. + +<% end -%> +<% test_frameworks = Hash.new + docdirfiles = [] + format.file_entries.each do |entry| + # new rubygems version has it different + if entry.kind_of?(Array) + path=entry[0]['path'] + else + path=entry + end + path.gsub!(%r{^\./}, '') + %w(test spec).each { |framework| + test_frameworks[framework] = 1 if path.index(framework + "/") == 0 + } + %w(changes + copying + history + legal + licence + license + license-mit + mit-license + changelog + news + release_notes + readme + ).each { |file| + bpath = path.downcase.gsub(%r{\.rdoc$}, '').gsub(%r{\.txt$}, '').gsub(%r{\.md$}, '').gsub(%r{\.markdown$}, '') + #$stderr.puts "PATH #{path} #{bpath} #{file}" + docdirfiles << path if bpath == file + } + end + + test_frameworks = test_frameworks.keys.sort +-%> +<% unless test_frameworks.empty? -%> +%package -n <%= pkg_basename %>-testsuite<%= config[:version_suffix] %> +Summary: Test suite for <%= spec.name %> +Group: Development/Languages/Ruby +Requires: <%= pkg_basename %><%= config[:version_suffix] %> = <%= spec.version %> + +%description -n <%= pkg_basename %>-testsuite<%= config[:version_suffix] %> +Test::Unit or RSpec files, useful for developers. + +<% end -%> + +<% unless spec.executables.empty? -%> +%post -n <%= pkg_basename %><%= config[:version_suffix] %> +<% spec.executables.each do |executable| -%> +/usr/sbin/update-alternatives --install \ + <%= rb_bindir %>/<%= executable %> <%= executable %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> <%= mod_weight %> +/usr/sbin/update-alternatives --install \ + <%= rb_bindir %>/<%= "#{executable}-#{spec.version}" %> <%= "#{executable}-#{spec.version}" %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> <%= mod_weight %> +/usr/sbin/update-alternatives --install \ + <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}" %> <%= "#{executable}#{rb_suffix}" %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> <%= mod_weight %> +<% end -%> + +%preun -n <%= pkg_basename %><%= config[:version_suffix] %> +if [ "$1" = 0 ] ; then +<% spec.executables.each do |executable| -%> + /usr/sbin/update-alternatives --remove <%= executable %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> + /usr/sbin/update-alternatives --remove <%= "#{executable}-#{spec.version}" %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> + /usr/sbin/update-alternatives --remove <%= "#{executable}#{rb_suffix}" %> <%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> +<% end -%> +fi +<% end -%> + +%files -n <%= pkg_basename %><%= config[:version_suffix] %> +%defattr(-,root,root,-) +# MANUAL +<% if config[:main] && config[:main][:filelist] -%> +<%= config[:main][:filelist] -%> +<% end -%> +# /MANUAL +<% unless docdirfiles.empty? -%> +<%= docdir %>/<%= pkg_basename %><%= config[:version_suffix] %> +<% end -%> +<% spec.executables.each do |executable| -%> +<%= rb_bindir %>/<%= "#{executable}#{rb_suffix}-#{spec.version}" %> +<%= rb_bindir %>/<%= "#{executable}#{rb_suffix}" %> +<%= rb_bindir %>/<%= "#{executable}-#{spec.version}" %> +<%= rb_bindir %>/<%= executable %> +%ghost <%= rb_sysconfdir %>/alternatives/<%= executable %> +%ghost <%= rb_sysconfdir %>/alternatives/<%= "#{executable}#{rb_suffix}" %> +%ghost <%= rb_sysconfdir %>/alternatives/<%= "#{executable}-#{spec.version}" %> +<% end -%> +# cache file +<%= gem_cache_dir %>/<%= mod_full_name %>.gem +<%= gem_gem_dir %> +<% unless spec.extensions.empty? or gem_extension_dir.nil? -%> +<%= gem_extension_dir %> +<% end -%> +<% test_frameworks.each do |framework| -%> +%exclude <%= File.join gem_gem_dir, framework %> +<% end -%> +<%= gem_spec_dir %>/<%= mod_full_name -%>.gemspec + +<% if spec.has_rdoc && !(config[:disable_docs]) -%> +%files -n <%= pkg_basename %>-doc<%= config[:version_suffix] %> +%defattr(-,root,root,-) +%doc <%= gem_doc_dir %> +<% unless spec.extensions.empty? or gem_extension_doc.nil? -%> +%doc <%= gem_extension_doc %> +<% end -%> +<% end -%> + +<% unless test_frameworks.empty? -%> +%files -n <%= pkg_basename %>-testsuite<%= config[:version_suffix] %> +%defattr(-,root,root,-) +<% test_frameworks.each do |framework| -%> +<%= File.join gem_gem_dir, framework %> +<% end -%> +<% end -%> +<% + if config[:custom_pkgs_ruby_versioned] + config[:custom_pkgs_ruby_versioned].each do |custom_pkg_name, data| +-%> +%package -n <%= pkg_basename %>-<%= custom_pkg_name %><%= config[:version_suffix] %> +<% if data[:preamble] and data[:preamble] != '' -%> +<%= data[:preamble] %> +<% else %> +Summary: <%= custom_pkg_name %> sub package for <%= spec.name %> +Group: Development/Languages/Ruby +<% end %> +Requires: <%= pkg_basename %><%= config[:version_suffix] %> = <%= spec.version %> +%description -n <%= pkg_basename %>-<%= custom_pkg_name %><%= config[:version_suffix] %> +<% if data[:description] and data[:description] != '' -%> +<%= data[:description] %> +<% else %> +<%= spec.description -%> + +This package holds the <%= custom_pkg_name %> sub package for <%= spec.name -%> +<% end %> +%files -n <%= pkg_basename %>-<%= custom_pkg_name %><%= config[:version_suffix] %> +%defattr(-,root,root,-) +<%= data['filelist'] -%> +<% + end + end +-%> diff --git a/ruby-common.macros b/ruby-common.macros new file mode 100644 index 0000000000000000000000000000000000000000..06bf4c91f6816ec6db35bea666f042e7582c7223 --- /dev/null +++ b/ruby-common.macros @@ -0,0 +1,23 @@ +# +# IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT +# +# if you change any macros here you have to update the copy in the +# prjconf aswell. +# +# IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT +# +%rubygem() %{expand:%%{rubygems%rb_build_versions STOP %*}} +%rubygemsSTOP() %nil +%rubygemsxSTOP() %{expand:%%rubygemsxxSTOP -a %*} +%rubygemsxxSTOP(a:) %{-a*}) %* + +%rubySTOP() %nil +%rubyxSTOP() %* + +%ruby() %{expand:%%{ruby%rb_build_versions STOP %*}} + +%rubydevel() %{expand:%%{rubydevel%rb_build_versions STOP %*}} + +%rubydevelSTOP() %nil +%rubydevelxSTOP() %* +# diff --git a/ruby-common.spec b/ruby-common.spec new file mode 100644 index 0000000000000000000000000000000000000000..49c5dedadb59a9f1178aff199ced0c7076b2dbbb --- /dev/null +++ b/ruby-common.spec @@ -0,0 +1,78 @@ +# +# spec file for package ruby-common +# +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + + +Name: ruby-common +Version: 2.1 +Release: 106.2 +Summary: ruby packaging scripts and macros +License: MIT +URL: https://github.com/openSUSE/ruby-packaging/ +Source1: gemrc +Source2: ruby-common.macros +Source3: ruby.rpm-macros +Source4: rubygems.attr +Source5: gem_build_cleanup +Source6: gem_install.sh +Source7: gem_packages.sh +Source8: openEuler.spec.erb +Source9: generate_buildrequires.sh +Source10: rubygemsdeps.rb +Source11: ruby-find-versioned + +Requires: fdupes rubygem(gem2rpm) util-linux +Recommends: rubygem(%{rb_default_ruby_abi}:gem2rpm) + +BuildRoot: %{_tmppath}/%{name}-%{version}-build +BuildArch: noarch + +Provides: ruby-macros = 5 + +%description +This package is used for generatting ruby gems. It provides hooks for +automatic rpm provides, requires and macros that gem2rpm uses. + +%prep + +%build + +%install +install -D -m 0644 %{SOURCE1} %{buildroot}/etc/gemrc +install -D -m 0644 %{SOURCE2} %{buildroot}/etc/rpm/macros.ruby-common +install -D -m 0644 %{SOURCE3} %{buildroot}/etc/rpm/macros.openEuler-ruby +install -D -m 0644 %{SOURCE4} %{buildroot}/usr/lib/rpm/fileattrs/rubygems.attr +install -D -m 0755 %{SOURCE5} %{buildroot}/usr/lib/rpm/gem_build_cleanup.sh +install -D -m 0755 %{SOURCE6} %{buildroot}/usr/lib/rpm/gem_install.sh +install -D -m 0755 %{SOURCE7} %{buildroot}/usr/lib/rpm/gem_packages.sh +install -D -m 0644 %{SOURCE8} %{buildroot}/usr/lib/rpm/gem_packages.template +install -D -m 0755 %{SOURCE9} %{buildroot}/usr/lib/rpm/generate_buildrequires.sh +install -D -m 0755 %{SOURCE10} %{buildroot}/usr/lib/rpm/rubygemsdeps.rb +install -D -m 0755 %{SOURCE11} %{buildroot}%{_bindir}/ruby-find-versioned + +%files +%defattr(-,root,root) +%config /etc/gemrc +%config /etc/rpm/macros.* +%dir /usr/lib/rpm/fileattrs +/usr/lib/rpm/fileattrs/* +/usr/lib/rpm/ge* +/usr/lib/rpm/rubygemsdeps.rb +%{_bindir}/ruby-find-versioned + +%changelog +* Mon Mar 9 2020 hy - 2.1-106.2 +- Package init diff --git a/ruby-find-versioned b/ruby-find-versioned new file mode 100644 index 0000000000000000000000000000000000000000..8c7b3e162d2eba1790b962794fcf0d2e2327e37c --- /dev/null +++ b/ruby-find-versioned @@ -0,0 +1,7 @@ +#!/bin/bash +shopt -s nullglob +binary="ruby" +if [ "x$1" != "x" ] ; then + binary="$1" +fi +ls -1 /usr/bin/$binary.{ruby,rbx,jruby}[0-9].[0-9] /usr/bin/$binary[0-9].[0-9] diff --git a/ruby.rpm-macros b/ruby.rpm-macros new file mode 100644 index 0000000000000000000000000000000000000000..6fa5e8bfbed8a3618383f776c5be650fa0aee01e --- /dev/null +++ b/ruby.rpm-macros @@ -0,0 +1,92 @@ +%rb_binary /usr/bin/ruby +%rb_arch %(%{rb_binary} -e 'print RUBY_PLATFORM') +%rb_ver %(%{rb_binary} -r rbconfig -e 'print RbConfig::CONFIG["ruby_version"]') +# + +## Base +# "rubylibprefix"=>"/usr/lib64/ruby", +%rb_dir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["rubylibprefix"]' ) +# "rubylibdir" =>"/usr/lib64/ruby/2.1.0", +%rb_libdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["rubylibdir"]' ) +# "archdir" =>"/usr/lib64/ruby/2.1.0/x86_64-linux", +%rb_archdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["archdir"]' ) + +## Site +# "sitedir" =>"/usr/lib64/ruby/site_ruby", +%rb_sitedir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["sitedir"]' ) +# "sitelibdir" =>"/usr/lib64/ruby/site_ruby/2.1.0", +%rb_sitelibdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["sitelibdir"]' ) +# "sitearchdir" =>"/usr/lib64/ruby/site_ruby/2.1.0/x86_64-linux", +%rb_sitearchdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["sitearchdir"]' ) + +## Vendor +# "vendordir" =>"/usr/lib64/ruby/vendor_ruby", +%rb_vendordir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["vendordir"]' ) +# "vendorlibdir" =>"/usr/lib64/ruby/vendor_ruby/2.1.0", +%rb_vendorlibdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["vendorlibdir"]' ) +# "vendorarchdir" =>"/usr/lib64/ruby/vendor_ruby/2.1.0/x86_64-linux", +%rb_vendorarchdir %(%{rb_binary} -rrbconfig -e 'puts RbConfig::CONFIG["vendorarchdir"]' ) + +# backward compat +%rb_sitearch %{rb_sitearchdir} +%rb_sitelib %{rb_sitelibdir} +%rb_vendorlib %{rb_vendorlibdir} +%rb_vendorarch %{rb_vendorarchdir} + +# %%gem_unpack macro unpacks a gem file into %%{_builddir} +# +# example: +# %prep +# %gem_unpack %{SOURCE0} +# %patch1 -p1 +# +%gem_unpack(s:) \ + source=%{-s:%{-s*}}%{!-s:%{SOURCE0}} \ + %{?gem_binary}%{!?gem_binary:/usr/bin/gem} unpack --verbose $source \ + cd %{mod_name}-%{version} \ + chmod og-w -R . \ + %{?gem_binary}%{!?gem_binary:/usr/bin/gem} specification --ruby $source > %{mod_name}-%{version}.gemspec \ +%{nil} + +# %%gem_build macro ... +# +%gem_build() \ +GEMSPEC_SOURCE_DIR=`find . -maxdepth 2 -type f -name %{mod_name}-%{version}.gemspec | xargs dirname` \ +cd $GEMSPEC_SOURCE_DIR && %{?gem_binary}%{!?gem_binary:/usr/bin/gem} build --verbose %{mod_name}-%{version}.gemspec \ +%{nil} + +# %%gem_install macro ... +# +# When invoked with a single parameter, the macro retains the old macro behavior, i.e. +# building the upstream gem directly in $RPM_BUILD_ROOT without unpacking to %{_builddir} first. +# +%gem_install /usr/lib/rpm/gem_install.sh --default-gem %{mod_name}-%{version}.gem --gem-name=%{mod_name} --gem-version=%{version} --build-root %{buildroot} %{?mod_version_suffix:--gem-suffix=%{mod_version_suffix}} %{?gem_binary:--gem-binary %{gem_binary}} +%gem_packages %{expand:%(/usr/lib/rpm/gem_packages.sh --default-gem %{mod_name}-%{version}.gem --gem-name=%{mod_name} --gem-version=%{version} --build-root %{buildroot})} + +# we need to copy parts of the %fdupes macro as rpm can't expand parameters in macro "calls" ;( +%gem_cleanup() \ +for gem in $(/usr/bin/ruby-find-versioned gem) ; do \ + gem_base="$($gem env gemdir)" \ + /usr/lib/rpm/gem_build_cleanup.sh %{buildroot}${gem_base} \ + fdupes -q -p -n -r %{buildroot}${gem_base} | \ + while read _file; do \ + if test -z "$_target" ; then \ + _target="$_file"; \ + else \ + if test -z "$_file" ; then \ + _target=""; \ + continue ; \ + fi ; \ + ln -sf "${_target#%{buildroot}}" "$_file"; \ + fi ; \ + done \ +done \ +%{nil} + +# this is used in older gems - but it's pointless with newer ruby/rpm versions +%rubygems_requires %{nil} + +%gem_base %(%{rb_binary} -rrubygems -e 'print Gem::Specification.new.base_dir' ) +%gem_extensions %(%{rb_binary} -rrubygems -e 'print Gem::Specification.new.extensions_dir' || echo %{_libdir}/ruby/gems/%{rb_ver}/gems ) +%gem_doc_ext %(%{rb_binary} -r rubygems -e 'bs = Gem::Specification.new; rp = bs.extensions_dir.rpartition(bs.base_dir); print rp[1]+"/doc"+rp[2]' ) +%gem_platform %(%{rb_binary} -r rubygems -r rbconfig -e 'print Gem::Platform.new(RbConfig::CONFIG["arch"]).to_s' ) diff --git a/rubygems.attr b/rubygems.attr new file mode 100644 index 0000000000000000000000000000000000000000..07bb3e13bc245afa9cadff6ebe5a159e011954b4 --- /dev/null +++ b/rubygems.attr @@ -0,0 +1,4 @@ +%__rubygems_requires %{_rpmconfigdir}/rubygemsdeps.rb --requires +%__rubygems_provides %{_rpmconfigdir}/rubygemsdeps.rb --provides +%__rubygems_path ^%{_libdir}/.*/gems/[^/]*/specifications + diff --git a/rubygemsdeps.rb b/rubygemsdeps.rb new file mode 100644 index 0000000000000000000000000000000000000000..40d663daa2a53e9018a7f39241ebec8c287872a4 --- /dev/null +++ b/rubygemsdeps.rb @@ -0,0 +1,164 @@ +#!/bin/sh +=begin &>/dev/null +# workaround for rubinius bug +# https://github.com/rubinius/rubinius/issues/2732 +export LC_ALL="en_US.UTF-8" +export LANG="en_US.UTF-8" +for ruby in $(/usr/bin/ruby-find-versioned) ; do + test -x "$ruby" && break +done +exec $ruby -x $0 "$@" +=end +#!/usr/bin/ruby + +# Copyright (c) 2012 Stephan Kulow +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +require 'optparse' +require 'rubygems' +#require 'rubygems/format' +require 'rubygems/specification' + +opts = OptionParser.new("Usage: #{$0}") + +provides=false +opts.on("-P", "--provides", "Output the provides of the package") do |val| + provides=true +end +requires=false +opts.on("-R", "--requires", "Output the requires of the package") do |val| + requires=true +end +file_match=".*/gems/[^/]*/specifications/.*\.gemspec$" +opts.on("-m", "--file-match REGEX", String, + "Override the regex against which the input file names", + "matched with the supplied regex") do |val| + file_match=val +end +in_file=nil +opts.on("-g", "--gemspec FILE", String, + "Take gemspec from FILE, not filename in STDIN", + "Can be a .gem file or a .gemspec file") do |file| + in_file=file +end +rest = opts.permute(ARGV) + +unless provides || requires + exit(0) +end + +def fatal(msg) + $stderr.puts msg + exit 1 +end + +def register_gemspec_from_file(gemspecs, rubyabi, file) + fatal "Couldn't read '#{file}'" unless File.readable? file + + case file + when /\.gem$/ + gem = Gem::Format.from_file_by_path(file) + fatal "Failed to load gem from '#{file}'" unless gem + spec = gem.spec + when /\.gemspec$/ + spec = Gem::Specification.load(file) + fatal "Failed to load gem spec from '#{file}'" unless spec + else + fatal "'#{file}' must be a .gem or .gemspec file" + end + + gemspecs << [ rubyabi, spec ] +end + +def rubyabi_from_path(path) + m = path.match(%r{.*/([^/]*)/gems/([^/]*)/.*}) + # return m ? m[1] : RbConfig::CONFIG["ruby_version"] + return { :interpreter => m[1], :version => m[2], :abi => "#{m[1]}:#{m[2]}", :requires => "#{m[1]}(abi) = #{m[2]}" } +end + +gemspecs = Array.new + +if in_file + # This mode will not be used during actual rpm builds, but only by + # gem packagers for debugging / diagnostics, so that they can + # predict in advance what the dependencies will look like. + rubyabi = rubyabi_from_path(in_file) || '$RUBYABI' + register_gemspec_from_file(gemspecs, rubyabi, in_file) +else + $stdin.each_line do |line| + line.chomp! + m = line.match(%r{#{file_match}$}) + if m + register_gemspec_from_file(gemspecs, rubyabi_from_path(line), line) + end + end +end + +gemspecs.each do |rubyabi_hash, spec| + rubyabi = rubyabi_hash[:abi] + rubyabi_requires = rubyabi_hash[:requires] + if provides + versions = spec.version.to_s.split('.') + # old forms + # puts "rubygem-#{spec.name} = #{spec.version}" + # puts "rubygem-#{spec.name}-#{versions[0]} = #{spec.version}" if versions.length > 0 + # puts "rubygem-#{spec.name}-#{versions[0]}_#{versions[1]} = #{spec.version}" if versions.length > 1 + # puts "rubygem-#{spec.name}-#{versions[0]}_#{versions[1]}_#{versions[2]} = #{spec.version}" if versions.length > 2 + + # version without ruby version - asking for trouble + puts "rubygem(#{spec.name}) = #{spec.version}" + if rubyabi + puts "rubygem(#{rubyabi}:#{spec.name}) = #{spec.version}" + puts "rubygem(#{rubyabi}:#{spec.name}:#{versions[0]}) = #{spec.version}" if versions.length > 0 + puts "rubygem(#{rubyabi}:#{spec.name}:#{versions[0]}.#{versions[1]}) = #{spec.version}" if versions.length > 1 + puts "rubygem(#{rubyabi}:#{spec.name}:#{versions[0]}.#{versions[1]}.#{versions[2]}) = #{spec.version}" if versions.length > 2 + end + end + + if requires + puts rubyabi_requires if rubyabi_requires + puts "rubygems" if rubyabi_hash[:version].to_f < 1.9 + spec.runtime_dependencies.each do |dep| + dep.requirement.requirements.each do |r| + if r.first == '~>' + minversion = r.last.to_s.split('.') + versions = minversion[0,minversion.length-1] + # ~> 2 is pretty nonsense, so avoid being tricked + if versions.length > 0 + if minversion[minversion.length-1] == '0' + # ~> 1.2.0 is the same as >= 1.2 for rpm and it avoids problems when 1.2 is followed by 1.2.1 + minversion = versions + end + puts "rubygem(#{rubyabi}:#{dep.name}:#{versions.join('.')}) >= #{minversion.join('.')}" + else + puts "rubygem(#{rubyabi}:#{dep.name}) >= #{minversion.join('.')}" + end + elsif r.first == '!=' + # this is purely guessing, but we can't generate conflicts here ;( + puts "rubygem(#{rubyabi}:#{dep.name}) > #{r.last}" + #puts "rubygem(#{rubyabi}:#{dep.name}) < #{r.last}" + else + puts "rubygem(#{rubyabi}:#{dep.name}) #{r.first} #{r.last}" + end + end + end + end +end