b7242a
#!/usr/bin/ruby
b7242a
b7242a
require 'rubygems/package'
b7242a
b7242a
module RubyGemsReq
b7242a
  module Helpers
b7242a
    # Expands '~>' and '!=' gem requirements.
b7242a
    def self.expand_requirement(requirements)
b7242a
      requirements.inject([]) do |output, r|
b7242a
        output.concat case r.first
b7242a
        when '~>'
b7242a
          expand_pessimistic_requirement(r)
b7242a
        when '!='
b7242a
          # If there is only the conflict requirement, we still need to depend
b7242a
          # on the specified gem.
b7242a
          if requirements.size == 1
b7242a
            Gem::Requirement.default.requirements
b7242a
          else
b7242a
            []
b7242a
          end
b7242a
        else
b7242a
          [r]
b7242a
        end
b7242a
      end.reject {|r| r.empty? }
b7242a
    end
b7242a
b7242a
    # Expands the pessimistic version operator '~>' into equivalent '>=' and
b7242a
    # '<' pair.
b7242a
    def self.expand_pessimistic_requirement(requirement)
b7242a
      next_version = Gem::Version.create(requirement.last).bump
b7242a
      return ['>=', requirement.last], ['<', next_version]
b7242a
    end
b7242a
b7242a
    # Converts Gem::Requirement into array of requirements strings compatible
b7242a
    # with RPM .spec file.
b7242a
    def self.requirement_versions_to_rpm(requirement)
b7242a
      self.expand_requirement(requirement.requirements).map do |op, version|
b7242a
        version == Gem::Version.new(0) ? "" : " #{op} #{version}"
b7242a
      end
b7242a
    end
b7242a
b7242a
    # Compose dependency together with its requirements in RPM rich dependency
b7242a
    # string.
b7242a
    def self.compose_dependency_string(name, requirements)
b7242a
      dependency_strings = requirements.map { |requirement| name + requirement }
b7242a
      dependency_string = dependency_strings.join(' with ')
b7242a
      dependency_string.prepend('(').concat(')') if dependency_strings.length > 1
b7242a
      dependency_string
b7242a
    end
b7242a
  end
b7242a
b7242a
  # Report RubyGems dependency, versioned if required.
b7242a
  def self.rubygems_dependency(specification)
b7242a
    dependency_name = "ruby(rubygems)"
b7242a
    requirements = Helpers::requirement_versions_to_rpm(specification.required_rubygems_version)
b7242a
b7242a
    puts Helpers::compose_dependency_string(dependency_name, requirements)
b7242a
  end
b7242a
b7242a
  # Report all gem dependencies including their version.
b7242a
  def self.gem_depenencies(specification)
b7242a
    specification.runtime_dependencies.each do |dependency|
b7242a
      dependency_name = "rubygem(#{dependency.name})"
b7242a
      requirements = Helpers::requirement_versions_to_rpm(dependency.requirement)
b7242a
b7242a
      puts Helpers::compose_dependency_string(dependency_name, requirements)
b7242a
    end
b7242a
  end
b7242a
b7242a
  # Reports all requirements specified by all provided .gemspec files.
b7242a
  def self.requires
b7242a
    while filename = gets
b7242a
      filename.strip!
b7242a
      begin
b7242a
        specification = Gem::Specification.load filename
b7242a
b7242a
        rubygems_dependency(specification)
b7242a
        gem_depenencies(specification)
b7242a
      rescue => e
b7242a
        # Ignore all errors.
b7242a
      end
b7242a
    end
b7242a
  end
b7242a
end
b7242a
b7242a
if __FILE__ == $0
b7242a
  RubyGemsReq::requires
b7242a
end