You are not logged in.
Today i had the need to find out exactly which of my installed arch packages a ruby program depends on.
This script intercepts all require calls of a ruby program, resolves the absolute path to the file that gets loaded by ruby and determines the package it belongs to using pkgfile. After the program exist, a list of dependencies is generated, as well as a list of files that were not found in any of the installed arch packages.
For example, if you run a program that uses mysql and gnome2 like this:
ruby -r/path/to/pkgdebs.rb program.rb
then after it exists, pkgdeps will give ypu
--------------------------------------------------------------------------------
Resolving package dependencies for 'program.rb' ...
--------------------------------------------------------------------------------
/usr/lib/ruby/1.8/i686-linux/rbconfig.rb -> ruby
/usr/lib/ruby/1.8/English.rb -> ruby
/usr/lib/ruby/site_ruby/1.8/i686-linux/glib2.so -> ruby-glib2
[...]
--------------------------------------------------------------------------------
Found 11 package dependencies:
--------------------------------------------------------------------------------
'mysql-ruby'
'ruby'
'ruby-atk'
'ruby-gdkpixbuf2'
'ruby-glib2'
'ruby-gnome2'
'ruby-gnomecanvas'
'ruby-gtk2'
'ruby-libart'
'ruby-pango'
'ruby-rcairo'
pkgdeps.rb:
require 'pathname'
class ArchLinuxDependencies
@@required = []
@@depends = []
@@missing = []
def self.collect(required)
# collect absolute paths to the files loaded by ruby
if Pathname.new(required).absolute?
# check which file this path resolves to and add it
["", ".rb", ".so"].each do |extension|
file = required + extension
if File.exists? file
@@required << file unless @@required.include? file
break
end
end
else
# not an absolute pathname, search $: just like ruby does
extglob = "{.rb,.so}"
extglob = "" if required =~ /\.[^.]+$/
$:.each do |inc|
found = Dir["#{inc}/#{required}#{extglob}"]
unless found.empty?
file = File.expand_path(found[0])
@@required << file unless @@required.include? file
end
end
end
end
def self.resolve()
# resolve package this file belongs to using pkgfile
puts "-"*80
puts "Resolving package dependencies for '#{$0}' ..."
puts "-"*80
@@required.each do |file|
print "#{file} -> "
STDOUT.flush()
package = `pkgfile #{file} 2> /dev/null`.chomp.split("/")[1]
if package
@@depends << package unless @@depends.include? package
puts package
else
@@missing << file unless @@missing.include? file
puts "?"
end
end
puts self
end
def self.to_s
s = ("-"*80) + "\n"
s += "Found #{@@depends.length} package dependencies:\n"
s += ("-"*80) + "\n\n"
s+= (@@depends.sort.map { |d| "'#{d}'\n" }.join("")) + "\n"
unless @@missing.empty?
s += ("-"*80) + "\n"
s += "Required files not found in any installed package:\n"
s += ("-"*80) + "\n\n"
@@missing.each do |m|
s += "#{m}\n"
end
s += "\n"
end
s += ("-"*80) + "\n"
return s
end
end
class Object
def require(arg)
if super(arg)
ArchLinuxDependencies.collect(arg)
end
end
end
at_exit do
ArchLinuxDependencies.resolve()
end
I've tested this with a bunch of my own ruby programs and so far it seems to work very well.
Offline