aboutsummaryrefslogtreecommitdiffstats
path: root/rubygems.rb
blob: a1189afb69e1ea01797e58391fb6ffbc2fa1f070 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env ruby
#--
# Copyright 2010 Per Øyvind Karlsen <peroyvind@mandriva.org>
# 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

specpatt = "%s/specifications/.*\.gemspec$" % Gem.default_dirs[:system][:gem_dir]

gems = []
ruby_versioned = false
abi_provide = false

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
  elsif path.match(specpatt)
    ruby_versioned = true
    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["sitelibdir"])
      ruby_versioned = true
    elsif path.match(RbConfig::CONFIG["vendorlibdir"])
      ruby_versioned = true
    end
  end
end

if requires or abi_provide
  abidep = "ruby(abi)"
  if ruby_versioned and RbConfig::CONFIG["ruby_version"] != ""
    abidep += " = %s" % RbConfig::CONFIG["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
            version = version.gsub(/^/, ' ')
          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