#!/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 bundled=false opts.on("-b", "--bundled", "Output provides as bundled ones") do |val| bundled=true end file_match=nil 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 if file_match.nil? if bundled file_match = ".*/vendor/bundle/[^/]*/[^/]*/specifications/.*\.gemspec$" else file_match = ".*/gems/[^/]*/specifications/.*\.gemspec$" end end $rubyapi_re = %r{.*/([^/]*)/gems/([^/]*)/.*} if bundled $rubyapi_re = %r{.*/vendor/bundle/([^/]*)/([^/]*)/.*} 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($rubyapi_re) # 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 if bundled puts "bundled(rubygem(#{spec.name})) = #{spec.version}" else 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 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