package URPM;
use strict;
use DynaLoader;
# different files, but same package
# require them here to avoid dependencies
use URPM::Build;
use URPM::Resolve;
use URPM::Signature;
our @ISA = qw(DynaLoader);
our $VERSION = '1.03';
URPM->bootstrap($VERSION);
sub new {
my ($class, %options) = @_;
my $self = bless {
depslist => [],
provides => {},
}, $class;
$self->{nofatal} = 1 if $options{nofatal};
$self;
}
sub set_nofatal { $_[0]->{nofatal} = $_[1] }
sub search {
my ($urpm, $name, %options) = @_;
my $best;
#- tries other alternative if no strict searching.
unless ($options{strict_name}) {
if ($name =~ /^(.*)-([^\-]*)-([^\-]*)\.([^\.\-]*)$/) {
foreach (keys %{$urpm->{provides}{$1} || {}}) {
my $pkg = $urpm->{depslist}[$_];
$pkg->fullname eq $name and return $pkg;
}
}
unless ($options{strict_fullname}) {
if ($name =~ /^(.*)-([^\-]*)-([^\-]*)$/) {
foreach (keys %{$urpm->{provides}{$1} || {}}) {
my $pkg = $urpm->{depslist}[$_];
my ($n, $v, $r, $a) = $pkg->fullname;
$options{src} && $a eq 'src' || $pkg->is_arch_compat or next;
"$n-$v-$r" eq $name or next;
!$best || $pkg->compare_pkg($best) > 0 and $best = $pkg;
}
$best and return $best;
}
if ($name =~ /^(.*)-([^\-]*)$/) {
foreach (keys %{$urpm->{provides}{$1} || {}}) {
my $pkg = $urpm->{depslist}[$_];
my ($n, $v, undef, $a) = $pkg->fullname;
$options{src} && $a eq 'src' || $pkg->is_arch_compat or next;
"$n-$v" eq $name or next;
!$best || $pkg->compare_pkg($best) > 0 and $best = $pkg;
}
$best and return $best;
}
}
}
unless ($options{strict_fullname}) {
foreach (keys %{$urpm->{provides}{$name} || {}}) {
my $pkg = $urpm->{depslist}[$_];
my ($n, undef, undef, $a) = $pkg->fullname;
$options{src} && $a eq 'src' || $pkg->is_arch_compat or next;
$n eq $name or next;
!$best || $pkg->compare_pkg($best) > 0 and $best = $pkg;
}
}
return $best;
}
sub traverse {
my ($urpm, $callback) = @_;
if ($callback) {
foreach (@{$urpm->{depslist} || []}) {
$callback->($_);
}
}
scalar @{$urpm->{depslist} || []};
}
sub traverse_tag {
my ($urpm, $tag, $names, $callback) = @_;
my $count = 0;
my %names;
if (@{$names || []}) {
if ($tag eq 'name') {
foreach my $n (@$names) {
foreach (keys %{$urpm->{provides}{$n} || {}}) {
my $p = $urpm->{depslist}[$_];
$p->name eq $n or next;
$callback and $callback->($p);
++$count;
}
}
} elsif ($tag eq 'whatprovides') {
foreach (@$names) {
foreach (keys %{$urpm->{provides}{$_} || {}}) {
$callback and $callback->($urpm->{depslist}[$_]);
++$count;
}
}
} else {
@names{@$names} = ();
if ($tag eq 'whatrequires') {
foreach (@{$urpm->{depslist} || []}) {
if (grep { exists $names{$_} } $_->requires_nosense) {
$callback and $callback->($_);
++$count;
}
}
} elsif ($tag eq 'whatconflicts') {
foreach (@{$urpm->{depslist} || []}) {
if (grep { exists $names{$_} } $_->conflicts_nosense) {
$callback and $callback->($_);
++$count;
}
}
} elsif ($tag eq 'group') {
foreach (@{$urpm->{depslist} || []}) {
if (exists $names{$_->group}) {
$callback and $callback->($_);
++$count;
}
}
} elsif ($tag eq 'triggeredby' || $tag eq 'path') {
foreach (@{$urpm->{depslist} || []}) {
if (grep { exists $names{$_} } $_->files, grep { m!^/! } $_->provides_nosense) {
$callback and $callback->($_);
++$count;
}
}
} else {
die "unknown tag";
}
}
}
$count;
}
package URPM::Package;
our @ISA = qw(); # help perl_checker
package URPM::Transaction;
our @ISA = qw(); # help perl_checker
package URPM::DB;
our @ISA = qw(); # help perl_checker
1;
__END__
=head1 NAME
URPM - Perl module to manipulate RPM files
=head1 SYNOPSIS
use URPM;
# using the local RPM database
my $db = URPM::DB::open();
$db->traverse(sub {
my ($package) = @_; # this is a URPM::Package object
print $package->filename, "\n";
# ...
});
# loading and parsing a synthesis file
my $urpm = new URPM;
$urpm->parse_synthesis("synthesis.sample.cz");
$urpm->traverse(sub {
# retrieve all packages from the dependency list
# ...
});
=head1 DESCRIPTION
The URPM module allows you to manipulate RPM files, RPM header files and
hdlist files and manage them in memory. It is notably used by the B<urpmi>
utility. It provides four classes : C<URPM>, C<URPM::DB>, C<URPM::Package>,
and C<URPM::Transaction>.
=head2 The URPM class
=over 4
=item new()
The constructor creates a new, empty URPM object. It's a blessed hash that
contains two fields:
B<depslist> is an arrayref containing the list of depending packages (which are
C<URPM::Package> objects).
B<provides> is an hashref containing as keys the list of items provided by the
URPM object.
If the constructor is called with the arguments C<< nofatal => 1 >>, various
fatal error messages are suppressed (file not found in parse_hdlist() and
parse_synthesis()).
=item read_config_files()
Force the re-reading of the RPM configuration files.
=item list_rpm_tag()
Return a hash containing the key/id values of know rpm tags
=item ranges_overlap($range1, $range2 [, $nopromoteepoch])
This utility function compares to version ranges, in order to calculate
dependencies properly. The ranges have roughly the form
[<|<=|==|=>|>] [epoch:]version[-release]
where epoch, version and release are RPM-style version numbers.
If the optional parameter $nopromoteepoch is true, and if the 2nd range has no
epoch while the first one has one, then the 2nd range is assumed to have an
epoch == 0.
=item $urpm->parse_synthesis($file, [ callback => sub {...} ])
This method gets the B<depslist> and the B<provides> from a synthesis file
and adds them to the URPM object.
=item $urpm->parse_hdlist($file, %options)
This method load rpm informations from B<headers> contains in hdlist file
and adds them to the URPM object. Allowed options are
packing => 0 / 1
callback => sub { ... }
keep_all_tags => 0 / 1
Return value is an array of first and last id parsed.
=item $urpm->parse_rpms($files, %options)
This method load rpm informations from rpms B<headers> and adds them to
the URPM object. Allowed options are
Return value is an array of first and last id parsed.
=item $urpm->parse_rpm($file, %options)
This method gets the B<depslist> and the B<provides> from an RPM file
and adds them to the URPM object. Allowed options are
packing => 0 / 1
keep_all_tags => 0 / 1
callback => sub { ... }
=item $urpm->search($name, %options)
Search an RPM by name or by part of name in the list of RPMs represented by
this $urpm. The behaviour of the search is influenced by several options:
strict_name => 0 / 1
strict_fullname => 0 / 1
src => 0 / 1
=item $urpm->traverse($callback)
Executes the callback for each package in the depslist, passing a
C<URPM::Package> object as argument the callback.
=item $urpm->traverse_tag($tag, $names, $callback)
$tag may be one of C<name>, C<whatprovides>, C<whatrequires>, C<whatconflicts>,
C<group>, C<triggeredby>, or C<path>.
$names is a reference to an array, holding the acceptable values of the said
tag for the searched variables.
Then, $callback is called for each matching package in the depslist.
=item $urpm->verify_rpm($file, %options)
Verifies an RPM file.
Recognized options are:
db => $urpm_db
nopgp => 0 / 1
nogpg => 0 / 1
nomd5 => 0 / 1
norsa => 0 / 1
nodsa => 0 / 1
nodigests => 0 / 1
tmp_filename => '...'
nosignatures => 0 / 1 (equivalent to nopgp = nogpg = norsa = nodsa = 1)
=item $urpm->import_pubkey(%options)
db => $urpm_db
root => '...'
block => '...'
filename => '...'
=back
=head2 The URPM::DB class
=over 4
=item open($prefix, $write_perm)
Returns a new C<URPM::DB> object pointing on the local RPM database.
$prefix defaults to C<""> and indicates the RPM DB root directory prefix if
any. (See the B<--root> option to rpm(1)).
$write_perm is a boolean that defaults to false, and that indicates whether
the RPM DB should be open in read/write mode.
=item rebuild($prefix)
Rebuilds the RPM database (like C<rpm --rebuilddb>). $prefix defaults to C<"">.
=item $db->traverse($callback)
Executes the specified callback (a code reference) for each package
in the DB, passing a C<URPM::Package> object as argument the callback.
=item $db->traverse_tag($tag,$names,$callback)
$tag may be one of C<name>, C<whatprovides>, C<whatrequires>, C<whatconflicts>,
C<group>, C<triggeredby>, or C<path>.
$names is a reference to an array, holding the acceptable values of the said
tag for the searched variables.
Then, $callback is called for each matching package in the DB.
=item $db->create_transaction($prefix)
Creates and returns a new transaction (an C<URPM::Transaction> object) on the
specified DB. For $prefix, cf L<open>.
=back
=head2 The URPM::Package class
Most methods of C<URPM::Package> are accessors for the various properties
of an RPM package.
=over 4
=item $package->arch()
=item $package->build_header($fileno)
=item $package->build_info($fileno, [$provides_files])
=item $package->buildarchs()
=item $package->buildhost()
=item $package->buildtime()
=item $package->changelog_name()
=item $package->changelog_text()
=item $package->changelog_time()
=item $package->compare($evr)
=item $package->compare_pkg($other_pkg)
=item $package->conf_files()
=item $package->conflicts()
=item $package->conflicts_nosense()
=item $package->description()
=item $package->distribution()
=item $package->epoch()
=item $package->excludearchs()
=item $package->exclusivearchs()
=item $package->filename()
=item $package->files()
=item $package->files_flags()
=item $package->files_gid()
=item $package->files_group()
=item $package->files_md5sum()
=item $package->files_mode()
=item $package->files_mtime()
=item $package->files_owner()
=item $package->files_size()
=item $package->files_uid()
=item $package->flag($name)
=item $package->flag_available()
=item $package->flag_base()
=item $package->flag_disable_obsolete()
=item $package->flag_installed()
=item $package->flag_requested()
=item $package->flag_required()
=item $package->flag_selected()
=item $package->flag_skip()
=item $package->flag_upgrade()
=item $package->free_header()
=item $package->fullname()
Returns a 4 element list: name, version, release and architecture in an array context.
Returns a string NAME-VERSION-RELEASE.ARCH in scalar context.
=item $package->get_tag($tagid)
Returns an array containing values of $tagid. $tagid is the numerical value of
rpm tags. See rpmlib.h.
=item $package->queryformat($format)
Querying the package like rpm --queryformat do.
The function call directlly the rpmlib, then use headers informations, so it
silently failed if you use synthesis instead hdlist/rpms/headers files or rpmdb.
=item $package->get_tag_modifiers($tagid)
Return an array of human readable view of tag values. $tagid is the numerical value of rpm tags.
=item $package->group()
=item $package->header_filename()
=item $package->id()
=item $package->is_arch_compat()
=item $package->license()
=item $package->name()
=item $package->obsoletes()
=item $package->obsoletes_nosense()
=item $package->obsoletes_overlap($s, [$nopromoteepoch,] [$direction])
=item $package->os()
=item $package->pack_header()
=item $package->packager()
=item $package->provides()
=item $package->provides_nosense()
=item $package->provides_overlap($s, [$nopromoteepoch,] [$direction])
=item $package->rate()
=item $package->release()
=item $package->requires()
=item $package->requires_nosense()
=item $package->rflags()
=item $package->set_flag($name, $value)
=item $package->set_flag_base($value)
=item $package->set_flag_disable_obsolete($value)
=item $package->set_flag_installed($value)
=item $package->set_flag_requested($value)
=item $package->set_flag_required($value)
=item $package->set_flag_skip($value)
=item $package->set_flag_upgrade($value)
=item $package->set_id($id)
=item $package->set_rate($rate)
=item $package->set_rflags(...)
=item $package->size()
=item $package->sourcerpm()
=item $package->summary()
=item $package->update_header($filename, ...)
=item $package->upgrade_files()
=item $package->url()
=item $package->vendor()
=item $package->version()
=back
=head2 The URPM::Transaction class
=over 4
=item $trans->set_script_fd($fileno)
Sets the transaction output filehandle.
=item $trans->add($pkg, %options)
Adds a package to be installed to the transaction represented by $trans.
$pkg is an C<URPM::Package> object.
Options are:
update => 0 / 1 : indicates whether this is an upgrade
excludepath => [ ... ]
=item $trans->remove($name)
Adds a package to be erased to the transaction represented by $trans.
$name is the name of the package.
=item $trans->check(%options)
Checks that all dependencies can be resolved in this transaction.
Options are:
translate_message => 0 / 1 (currently ignored.)
=item $trans->order()
Determines package order in a transaction set according to dependencies.
Returns a boolean indicating success.
=item $trans->run($data, %options)
Runs the transaction.
$data is an arbitrary user-provided piece of data to be passed to callbacks.
Recognized options are:
callback_close => sub { ... }
callback_inst => sub { ... }
callback_open => sub { ... }
callback_trans => sub { ... }
callback_uninst => sub { ... }
delta => used for progress callbacks (trans, uninst, inst)
excludedocs => 0 / 1
force => 0 / 1
nosize => 0 / 1
oldpackage => 0 / 1
test => 0 / 1
translate_message
They roughly correspond to command-line options to rpm(1).
=back
=head1 COPYRIGHT
Copyright 2002, 2003, 2004 MandrakeSoft (Fran�ois Pons
<
[email protected]>)
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut