OpenPKG CVS Repository
http://cvs.openpkg.org/
____________________________________________________________________________
Server: cvs.openpkg.org Name: Michael van Elst
Root: /e/openpkg/cvs Email: [EMAIL PROTECTED]
Module: openpkg-src openpkg-web Date: 09-Jan-2003 15:23:18
Branch: HEAD Handle: 2003010914231601
Modified files:
openpkg-src/openpkg-tool
openpkg-build.pl openpkg-index.pl
openpkg-tool.spec openpkg.pod
openpkg-web news.txt
Log:
changed index format, compatibility code, code cleanup, comments,
clean revdep sort, optionally ignore XML parser
Summary:
Revision Changes Path
1.27 +584 -355 openpkg-src/openpkg-tool/openpkg-build.pl
1.9 +54 -5 openpkg-src/openpkg-tool/openpkg-index.pl
1.20 +2 -2 openpkg-src/openpkg-tool/openpkg-tool.spec
1.8 +6 -0 openpkg-src/openpkg-tool/openpkg.pod
1.2624 +1 -0 openpkg-web/news.txt
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: openpkg-src/openpkg-tool/openpkg-build.pl
============================================================================
$ cvs diff -u -r1.26 -r1.27 openpkg-build.pl
--- openpkg-src/openpkg-tool/openpkg-build.pl 8 Jan 2003 15:12:38 -0000 1.26
+++ openpkg-src/openpkg-tool/openpkg-build.pl 9 Jan 2003 14:23:17 -0000 1.27
@@ -29,8 +29,8 @@
$|=1; # autoflush
use strict;
-use vars qw/$opt_R $opt_r $opt_f $opt_u $opt_U $opt_a $opt_A $opt_z $opt_Z $opt_P
$opt_N $opt_E $opt_i $opt_D $opt_p $opt_q $opt_s $opt_S/;
-getopts('R:r:f:uUaAzZP:N:E:iD:p:qsS');
+use vars qw/$opt_R $opt_r $opt_f $opt_u $opt_U $opt_a $opt_A $opt_z $opt_Z $opt_P
$opt_N $opt_E $opt_i $opt_D $opt_p $opt_q $opt_s $opt_S $opt_X/;
+getopts('R:r:f:uUaAzZP:N:E:iD:p:qsSX');
##########################################################################
@@ -106,6 +106,9 @@
##########################################################################
+#
+# evaluate a condition attribute from an option set
+#
sub conditional ($$) {
my($cond,$with) = @_;
my(@s,$res);
@@ -138,40 +141,6 @@
return $res;
}
-sub with_list ($$) {
- my($bags,$with) = @_;
- my($bag,$li);
- my(@out);
-
- foreach $bag (@$bags) {
- next unless conditional($bag->{'cond'}, $with);
- foreach $li (@{$bag->{'rdf:bag'}}) {
- push @out, @{$li->{'rdf:li'}};
- }
- }
-
- return \@out;
-}
-
-sub make_hash ($$$) {
- my($bags,$tag,$with) = @_;
- my($bag,$li);
- my(%out,$el);
-
- foreach $bag (@$bags) {
- next unless conditional($bag->{'cond'}, $with);
- foreach $li (@{$bag->{'rdf:bag'}}) {
- foreach (@{$li->{'rdf:li'}}) {
- next unless exists $_->{$tag};
- $el = $_->{$tag}->[0];
- $out{$el->{'ID'}} = $el->{'content'};
- }
- }
- }
-
- return \%out;
-}
-
##########################################################################
my($RPM,$RPM_PRIV,$RPM_NPRIV,$CURL,$PROG);
@@ -326,15 +295,111 @@
}
return {
- name => $nam,
- version => $ver,
- release => $rel,
- proxy => $pxy,
- prefix => $pre,
- with => $with
+ name => $nam, # the full name of the resource
+ version => $ver, # the version (or value)
+ release => $rel, # and release number
+ proxy => $pxy, # wether the resource is a PROXY resource
+ prefix => $pre, # the packagename (if resource is an option)
+ with => $with # the buildoption (if resource is an option)
+ };
+}
+
+sub parse_depends ($) {
+ my($dep) = @_;
+ my($name, $op, $val);
+
+ if (ref $dep) {
+ #
+ # dependency from new index stored as a node
+ #
+ # content of the node is the name
+ # certain attributes denote the comparison operator
+ # the value of such an attribute is the comparison operand
+ #
+ # the operator (and operand) are optional and there can
+ # only be one
+ #
+ $name = $dep->{content};
+ $op = undef;
+ $op = 'equ' if exists $dep->{equ};
+ $op = 'geq' if exists $dep->{geq};
+ $op = 'leq' if exists $dep->{leq};
+ $op = 'gt' if exists $dep->{gt};
+ $op = 'lt' if exists $dep->{lt};
+ if (defined $op) {
+ $val = $dep->{$op};
+ }
+ } elsif ($dep =~ /\S/) {
+ #
+ # dependency from old index stored as text string
+ #
+ # "name operator operand"
+ # or
+ # "name"
+ #
+ ($name,$op,$val) = $dep =~ /(\S+)\s*(?:(\S+)\s*(\S+))?\s*$/;
+ if (defined $op) {
+ $op = {
+ '==' => 'equ', '=' => 'equ',
+ '>=' => 'geq', '=>' => 'geq',
+ '<=' => 'leq', '=<' => 'leq',
+ '>' => 'gt', '<' => 'lt'
+ }->{$op};
+ unless (defined $op) {
+ print "# don't know how to handle dependency: $dep\n";
+ return;
+ }
+ }
+ }
+
+ return {
+ name => $name,
+ op => $op,
+ val => $val
};
}
+sub depends2provides ($) {
+ my($dep) = @_;
+ my($ver,$rel,$pxy);
+
+ ($ver,$rel,$pxy) = $dep->{val} =~ /^([^\s\-]+)-([^\s\+]+)(\+PROXY)?$/;
+
+ return {
+ name => $dep->{name},
+ version => (defined $ver ? $ver : $dep->{val}),
+ release => $rel,
+ proxy => $pxy
+ }
+}
+
+#
+# convert parser output to dependency records
+#
+sub depend_list ($) {
+ my($deps) = @_;
+ foreach (@$deps) {
+ $_ = parse_depends($_);
+ }
+ return $deps;
+}
+
+#
+# compute list of package names from dependency list
+#
+sub depends2pkglist ($) {
+ my($deps) = @_;
+ return map { $_->{name} } @$deps;
+}
+
+#
+# retrieve the local installed base
+#
+# for packages that provide option resources (packagename::buildoption)
+# the options are parsed into the OPTIONS hash
+#
+# other packages will query options on demand
+#
sub get_installed () {
my(%map);
my(@l) = `$RPM_NPRIV --provides -qa`;
@@ -371,23 +436,16 @@
return \%map;
}
-sub revdep ($$$) {
- my($rev,$t,$name) = @_;
-
- return 1 if $name eq $t->{name};
-
- foreach (@{$rev->{$_}}) {
- return 1 if revdep($rev,$t,$_->{name});
- }
- return -1;
-}
-
+#
+# compute reverse dependency map
+#
+#
sub get_revdep ($) {
my($env) = @_;
my($i) = $env->{'installed'};
my($r) = $env->{'repository'};
- my($pkg, %rev);
- my(@vers,$t,@names);
+ my($pkg, %dep, %dlist, %rev);
+ my(@vers,$t);
print "# computing reverse dependencies\n";
@@ -398,26 +456,39 @@
next;
}
+ #
+ # get list of package versions from repository
+ #
@vers = get_versions($r->{$pkg}, sub { 1; });
+
+ #
+ # get forward dependencies from repository packages
+ #
+ # dep{a}{b} is true if b depends directly on a
+ # dlist{a} is list of packages that depend on a
+ #
foreach (@vers) {
foreach $t (@{$r->{$pkg}->{$_}}) {
next unless $i->{$t->{name}};
next unless $t->{depends};
-
- @names = grep { $_ ne '' }
- map { /^(\S+)/ }
- @{$t->{depends}};
- next unless @names;
- push @{$rev{$_}}, $t foreach @names;
+ foreach (depends2pkglist($t->{depends})) {
+ $dep{$_}{$t->{name}} = 1;
+ push @{$dlist{$_}}, $t;
+ }
}
}
}
- foreach $pkg (keys %rev) {
+ #
+ # sort reverse dependencies
+ #
+ foreach $pkg (keys %dep) {
$rev{$pkg} = [
sort {
- revdep(\%rev, $b, $a->{name});
- } @{$rev{$pkg}}
+ $dep{$a->{name}}{$b->{name}} ||
+ -$dep{$b->{name}}{$a->{name}} ||
+ $a->{name} cmp $b->{name}
+ } @{$dlist{$pkg}}
];
}
@@ -450,6 +521,9 @@
}
}
+#
+# pull in OPTIONS for a package or an RPM file
+#
sub get_with ($;$) {
my($t,$fn) = @_;
my(@l,%with);
@@ -465,11 +539,33 @@
return $t->{OPTIONS};
}
+#
+# compute absolute paths
+#
+# (url, fn) point to a base document
+# the location is the file path fn if fn is
+# defined, otherwise it is url.
+#
+# augment the pointer with suburl
+#
+# suburl can be an absolute url
+# then the new pointer is (suburl, undef)
+#
+# suburl can be a absolute file path
+# then the new pointer is (suburl, suburl)
+#
+# suburl can be a relative path
+# then it augments url or fn accordingly
+#
sub relurl ($$$) {
my($url,$fn,$suburl) = @_;
- my($subfn,$submap);
+ my($subfn);
- unless ($suburl =~ /^\w+:\/\// || $suburl =~ /^\//) {
+ if ($suburl =~ /^\w+:\/\//) {
+ # NOP
+ } elsif ($suburl =~ /^\//) {
+ $subfn = $suburl;
+ } else {
if (defined $fn) {
$subfn = $fn;
$subfn =~ s/\/[^\/]*$//;
@@ -488,19 +584,291 @@
return ($suburl, $subfn);
}
+#
+# return node value from XML parser
+#
sub xel($) {
my($a) = @_;
my($l) = $a->[0];
return '' if ref $l;
return $l;
}
-
-sub get_index ($$$) {
- my($url,$fn,$with) = @_;
- my($ua,$req,$res,$rdf);
- my($bzip2,$path);
- my(%map,@include);
- my($fetch);
+
+#
+# grep XML Bag against condition
+# return as flat list
+#
+sub with_list ($$) {
+ my($bags,$with) = @_;
+ my($bag,$li,$el);
+ my(@out);
+
+ foreach $bag (@$bags) {
+ next unless conditional($bag->{'cond'}, $with);
+ foreach $li (@{$bag->{'rdf:bag'}}) {
+ $el = $li->{'resource'} || $li->{'rdf:li'};
+ push @out, @$el;
+ }
+ }
+
+ return \@out;
+}
+
+sub simple_text_parser ($$$$) {
+ my($fh,$url,$with,$map) = @_;
+ my(@include);
+
+ my($section);
+ my($name,$version);
+ my($href,$release,$desc);
+ my(@prereq,@bprereq);
+ my(@provides,@conflicts,@source,@nosource);
+ my(%options);
+ my($platform,$prefix);
+ my($rec);
+ my($tag,$cond,$attrname,$attrval,$body);
+ my($useit);
+
+ print "# using simple text parser\n";
+
+ while (<$fh>) {
+
+ s/>/>/g;
+ s/</</g;
+
+ if (!(defined $href) && /<rdf:Description.*?href="([^"]*)"/) {
+ $href = $1;
+ $section = undef;
+ $name = undef;
+ $release = undef;
+ $desc = '';
+ $platform = undef;
+ $prefix = undef;
+ @prereq = ();
+ @bprereq = ();
+ @provides = ();
+ @conflicts = ();
+ @source = ();
+ @nosource = ();
+ }
+
+ if (!(defined $href) && /<Repository.*?href="([^"]*)"/) {
+ push(@include, $1);
+ next;
+ }
+
+ next unless defined $href;
+
+ ($tag,$cond,$attrname,$attrval,$body) = /
+ <
+ (\/?[\w:]+)
+ \s*
+ (?:cond="([^"]+)")?
+ (?:(\w+)="([^"]+)")?
+ >
+ (.*?)
+ (?:<\/\1>)?
+ $
+ /mx;
+
+ $useit = conditional($cond,$with);
+
+ if ($tag eq 'Description') {
+ $section = 'description';
+ } elsif ($tag eq '/Description') {
+ $section = undef;
+ } elsif ($section eq 'description') {
+ $desc .= $_;
+ } elsif ($tag eq 'PreReq') {
+ $section = 'prereq' if $useit;
+ } elsif ($tag eq '/PreReq') {
+ $section = undef;
+ } elsif ($tag eq 'BuildPreReq') {
+ $section = 'bprereq' if $useit;
+ } elsif ($tag eq '/BuildPreReq') {
+ $section = undef;
+ } elsif ($tag eq 'Provides') {
+ $section = 'provides' if $useit;
+ } elsif ($tag eq '/Provides') {
+ $section = undef;
+ } elsif ($tag eq 'Conflicts') {
+ $section = 'conflicts' if $useit;
+ } elsif ($tag eq '/Conflicts') {
+ $section = undef;
+ } elsif ($tag eq 'NoSource') {
+ $section = 'nosource' if $useit;
+ } elsif ($tag eq '/NoSource') {
+ $section = undef;
+ } elsif ($tag eq 'Source') {
+ $section = 'source' if $useit;
+ } elsif ($tag eq '/Source') {
+ $section = undef;
+ } elsif ($tag eq 'Name') {
+ $name = $body;
+ } elsif ($tag eq 'Version') {
+ $version = $body;
+ } elsif ($tag eq 'Release') {
+ $release = $body;
+ } elsif ($tag eq 'Platform') {
+ $platform = $body;
+ } elsif ($tag eq 'Prefixes') {
+ $prefix = $body;
+ } elsif ($tag eq 'rdf:li' || $tag eq 'resource') {
+ if ($section eq 'prereq') {
+ push(@prereq, $body);
+ } elsif ($section eq 'bprereq') {
+ push(@bprereq, $body);
+ } elsif ($section eq 'provides') {
+ push(@provides, $body);
+ } elsif ($section eq 'conflicts') {
+ push(@conflicts, $body);
+ } elsif ($section eq 'source') {
+ push(@source, $body);
+ } elsif ($section eq 'nosource') {
+ push(@nosource, $body);
+ }
+ } elsif ($tag eq '/rdf:Description') {
+
+ if (defined $href &&
+ defined $name &&
+ defined $version &&
+ defined $release) {
+
+ @provides = map {
+ depends2provides(parse_depends($_))
+ } @provides;
+
+ %options = map {
+ ( $_->{with} => $_->{version} )
+ } grep {
+ defined $_->{with}
+ } @provides;
+
+ unless (grep($_->{name} eq $name, @provides)) {
+ push(@provides, {
+ name => $name,
+ version => $version,
+ release => $release
+ });
+ }
+
+ $rec = {
+ href => (relurl($url, undef, $href))[0],
+ name => $name,
+ version => $version,
+ release => $release,
+ depends => depend_list([ @bprereq ]),
+ keeps => depend_list([ @prereq ]),
+ conflicts => [ @conflicts ],
+ source => [ @source ],
+ nosource => [ @nosource ],
+ desc => $desc,
+ platform => $platform,
+ prefix => $prefix
+ };
+
+ $rec->{OPTIONS} =
+ %options
+ ? { %options }
+ : parse_options($rec->{desc});
+
+ foreach (@provides) {
+ push(@{$map->{$_->{name}}->{vs($_)}}, $rec);
+ }
+ }
+
+ $href = undef;
+ }
+ }
+
+ return \@include;
+}
+
+sub xml_parser ($$$$) {
+ my($fh, $url, $with, $map) = @_;
+ my(@include);
+
+ my($xml,$desc,$sub);
+ my($provides,@provides,%options,$rec);
+ my($href,$name,$version,$release);
+
+ print "# using XML parser\n";
+
+ $xml = XML::Simple::XMLin($fh, forcearray => 1);
+ $desc = $xml->{'Repository'}->[0]->{'rdf:Description'};
+ $sub = $xml->{'Repository'}->[0]->{'Repository'};
+
+ foreach (@$desc) {
+
+ $href = $_->{'href'};
+ $name = xel($_->{'Name'});
+ $version = xel($_->{'Version'});
+ $release = xel($_->{'Release'});
+
+ next unless defined $href &&
+ defined $name &&
+ defined $version &&
+ defined $release;
+
+ $provides = $_->{'Provides'}->[0]->{'rdf:bag'}->[0];
+ if ($provides->{'rdf:li'}) {
+ $provides = $provides->{'rdf:li'};
+ } else {
+ $provides = $provides->{'resource'};
+ }
+ @provides = map {
+ depends2provides(parse_depends($_))
+ } @$provides;
+
+ %options = map {
+ ( $_->{with} => $_->{version} )
+ } grep {
+ defined $_->{with}
+ } @provides;
+
+ unless (grep($_->{name} eq $name, @provides)) {
+ push(@provides, {
+ name => $name,
+ version => $version,
+ release => $release
+ });
+ }
+
+ $rec = {
+ href => (relurl($url, undef, $href))[0],
+ name => $name,
+ version => $version,
+ release => $release,
+ platform => xel($_->{'Platform'}),
+ prefix => xel($_->{'Prefixes'}),
+ depends => depend_list(with_list($_->{'BuildPreReq'}, $with)),
+ keeps => depend_list(with_list($_->{'PreReq'}, $with)),
+ conflicts => with_list($_->{'Conflicts'}, $with),
+ source => with_list($_->{'Source'}, $with),
+ nosource => with_list($_->{'NoSource'}, $with),
+ desc => xel($_->{'Description'})
+ };
+
+ $rec->{OPTIONS} =
+ %options
+ ? { %options }
+ : parse_options($rec->{desc});
+
+ foreach (@provides) {
+ push(@{$map->{$_->{name}}->{vs($_)}}, $rec);
+ }
+ }
+
+ if ($sub) {
+ @include = map { $_->{href} } @$sub;
+ }
+
+ return \@include;
+}
+
+sub open_index ($$) {
+ my($url, $fn) = @_;
+ my($fetch,$bzip2,$path);
$fetch = defined $fn ? $fn : $url;
@@ -530,239 +898,29 @@
open(RFH, $path) or
die "FATAL: cannot open '$fetch' ($!)\n";
+}
- eval {
- require XML::Simple;
- };
- if ($@) {
-
- print "# using simple text parser\n";
-
- my($section);
- my($name,$version);
- my($href,$release,$desc);
- my(@prereq,@bprereq);
- my(@provides,@conflicts,@source,@nosource);
- my(%options);
- my($platform,$prefix);
- my($rec);
- my($tag,$cond,$body);
- my($useit);
-
- while (<RFH>) {
-
- s/>/>/g;
- s/</</g;
-
- if (!(defined $href) && /<rdf:Description.*?href="([^"]*)"/) {
- $href = $1;
- $section = undef;
- $name = undef;
- $release = undef;
- $desc = '';
- $platform = undef;
- $prefix = undef;
- @prereq = ();
- @bprereq = ();
- @provides = ();
- @conflicts = ();
- @source = ();
- @nosource = ();
- }
-
- if (!(defined $href) && /<Repository.*?href="([^"]*)"/) {
- push(@include, $1);
- next;
- }
-
- next unless defined $href;
-
- ($tag,$cond,$body) = /
- <
- (\/?[\w:]+)
- \s*
- (?:cond="([^"]+)")?
- >
- (.*?)
- (?:<\/\1>)?
- $
- /mx;
-
- $useit = conditional($cond,$with);
-
- if ($tag eq 'Description') {
- $section = 'description';
- } elsif ($tag eq '/Description') {
- $section = undef;
- } elsif ($section eq 'description') {
- $desc .= $_;
- } elsif ($tag eq 'PreReq') {
- $section = 'prereq' if $useit;
- } elsif ($tag eq '/PreReq') {
- $section = undef;
- } elsif ($tag eq 'BuildPreReq') {
- $section = 'bprereq' if $useit;
- } elsif ($tag eq '/BuildPreReq') {
- $section = undef;
- } elsif ($tag eq 'Provides') {
- $section = 'provides' if $useit;
- } elsif ($tag eq '/Provides') {
- $section = undef;
- } elsif ($tag eq 'Conflicts') {
- $section = 'conflicts' if $useit;
- } elsif ($tag eq '/Conflicts') {
- $section = undef;
- } elsif ($tag eq 'NoSource') {
- $section = 'nosource' if $useit;
- } elsif ($tag eq '/NoSource') {
- $section = undef;
- } elsif ($tag eq 'Source') {
- $section = 'nosource' if $useit;
- } elsif ($tag eq '/Source') {
- $section = undef;
- } elsif ($tag eq 'Name') {
- $name = $body;
- } elsif ($tag eq 'Version') {
- $version = $body;
- } elsif ($tag eq 'Release') {
- $release = $body;
- } elsif ($tag eq 'Platform') {
- $platform = $body;
- } elsif ($tag eq 'Prefixes') {
- $prefix = $body;
- } elsif ($tag eq 'rdf:li') {
- if ($section eq 'prereq') {
- push(@prereq, $body);
- } elsif ($section eq 'bprereq') {
- push(@bprereq, $body);
- } elsif ($section eq 'provides') {
- push(@provides, $body);
- } elsif ($section eq 'conflicts') {
- push(@conflicts, $body);
- } elsif ($section eq 'source') {
- push(@source, $body);
- } elsif ($section eq 'nosource') {
- push(@nosource, $body);
- }
- } elsif ($tag eq '/rdf:Description') {
-
- if (defined $href &&
- defined $name &&
- defined $version &&
- defined $release) {
-
- @provides = map { parse_provides($_) } @provides;
-
- %options = map {
- ( $_->{with} => $_->{version} )
- } grep {
- defined $_->{with}
- } @provides;
-
- unless (grep($_->{name} eq $name, @provides)) {
- push(@provides, {
- name => $name,
- version => $version,
- release => $release
- });
- }
-
- $rec = {
- href => (relurl($url, undef, $href))[0],
- name => $name,
- version => $version,
- release => $release,
- depends => [ @bprereq ],
- keeps => [ @prereq ],
- conflicts => [ @conflicts ],
- nosource => [ @source ],
- nosource => [ @nosource ],
- desc => $desc,
- platform => $platform,
- prefix => $prefix
- };
-
- $rec->{OPTIONS} =
- %options
- ? { %options }
- : parse_options($rec->{desc});
-
- foreach (@provides) {
- push(@{$map{$_->{name}}->{vs($_)}}, $rec);
- }
- }
+#
+# fetch index from file or URL
+# recursively fetch sub-indexes
+#
+sub get_index ($$$$) {
+ my($url,$fn,$with,$noxml) = @_;
+ my(%map,$include);
+
+ open_index($url,$fn);
+
+ unless ($noxml) {
+ eval {
+ require XML::Simple;
+ };
+ $noxml = 1 if $@;
+ }
- $href = undef;
- }
- }
+ if ($noxml) {
+ $include = simple_text_parser(\*RFH, $url, $with, \%map);
} else {
-
- print "# using XML parser\n";
-
- my($xml) = XML::Simple::XMLin(\*RFH, forcearray => 1);
- my($desc) = $xml->{'Repository'}->[0]->{'rdf:Description'};
- my($sub) = $xml->{'Repository'}->[0]->{'Repository'};
- my($provides,@provides,%options,$rec);
- my($href,$name,$version,$release);
-
- foreach (@$desc) {
-
- $href = $_->{'href'};
- $name = xel($_->{'Name'});
- $version = xel($_->{'Version'});
- $release = xel($_->{'Release'});
-
- next unless defined $href &&
- defined $name &&
- defined $version &&
- defined $release;
-
- $provides = $_->{'Provides'}->[0]->{'rdf:bag'}->[0]->{'rdf:li'};
-
- @provides = map { parse_provides($_) } @$provides;
-
- %options = map {
- ( $_->{with} => $_->{version} )
- } grep {
- defined $_->{with}
- } @provides;
-
- unless (grep($_->{name} eq $name, @provides)) {
- push(@provides, {
- name => $name,
- version => $version,
- release => $release
- });
- }
-
- $rec = {
- href => (relurl($url, undef, $href))[0],
- name => $name,
- version => $version,
- release => $release,
- platform => xel($_->{'Platform'}),
- prefix => xel($_->{'Prefixes'}),
- depends => with_list($_->{'BuildPreReq'}, $with),
- keeps => with_list($_->{'PreReq'}, $with),
- conflicts => with_list($_->{'Conflicts'}, $with),
- source => with_list($_->{'Source'}, $with),
- nosource => with_list($_->{'NoSource'}, $with),
- desc => xel($_->{'Description'})
- };
-
- $rec->{OPTIONS} =
- %options
- ? { %options }
- : parse_options($rec->{desc});
-
- foreach (@provides) {
- push(@{$map{$_->{name}}->{vs($_)}}, $rec);
- }
- }
-
- if ($sub) {
- @include = map { $_->{href} } @$sub;
- }
+ $include = xml_parser(\*RFH, $url, $with, \%map);
}
close(RFH)
@@ -772,10 +930,10 @@
# cannot do real recursions on file handles, so we simply append
# all sub-RDFs, the result is flattend into a big hash anyway
#
- foreach (@include) {
+ foreach (@$include) {
my($submap);
my($suburl,$subfn) = relurl($url,$fn,$_);
- $submap = get_index($suburl,$subfn,$with);
+ $submap = get_index($suburl,$subfn,$with,$noxml);
while (my($name,$vmap) = each %$submap) {
while (my($vs,$recs) = each %$vmap) {
push @{$map{$name}->{$vs}}, @$recs;
@@ -786,6 +944,8 @@
return \%map;
}
+############################################################################
+
#
# grep all versions of a name that
# satisfy a condition
@@ -807,10 +967,10 @@
@recs = grep {
$env->{sourceonly} ? (
- !(defined $_->{'platform'})
+ !(defined $_->{'prefix'})
) : (
- !(defined $_->{'platform'}) || (
- defined $_->{'prefix'} &&
+ !(defined $_->{'prefix'}) || (
+ defined $_->{'platform'} &&
$_->{'platform'} eq $env->{config}->{platform} &&
$_->{'prefix'} eq $env->{config}->{prefix}
)
@@ -933,6 +1093,20 @@
}
#
+# strip doubles from depend/keep lists
+# and a return a map name => depend/keep
+#
+sub unique_map {
+ my(%out);
+ foreach (@_) {
+ foreach (@$_) {
+ $out{$_->{name}} = $_;
+ }
+ }
+ return %out;
+}
+
+#
# test wether target could be upgraded
#
sub target_newer ($$) {
@@ -992,17 +1166,22 @@
}
}
+############################################################################
+
+#
+# LOGIC
+#
+
#
# locate target for a dependency
#
sub dep2target ($$) {
my($dep, $env) = @_;
- my($name,@vers);
+ my($name,$op,@vers);
my($i,$r,$b,$cond,$version);
my($t,$tdef);
- $dep =~ s/(\S+)\s*//;
- $name = $1;
+ ($name, $op, $version) = ($dep->{name}, $dep->{op}, $dep->{val});
$i = $env->{installed}->{$name};
$r = $env->{repository}->{$name};
@@ -1010,26 +1189,20 @@
return unless $i || $r || $b;
- if ($dep =~ /^(?:>=|=>)\s*(\S+)$/) {
- $version = $1;
+ if (!defined $op) {
+ $cond = sub { 1; };
+ } elsif ($op eq 'geq') {
$cond = sub { vcmp($_[0],$version) >= 0; };
- } elsif ($dep =~ /^(?:<=|=<)\s*(\S+)$/) {
- $version = $1;
+ } elsif ($op eq 'leq') {
$cond = sub { vcmp($_[0],$version) <= 0; };
- } elsif ($dep =~ /^>\s*(\S+)$/) {
- $version = $1;
+ } elsif ($op eq 'gt') {
$cond = sub { vcmp($_[0],$version) > 0; };
- } elsif ($dep =~ /^<\s*(\S+)$/) {
- $version = $1;
+ } elsif ($op eq 'lt') {
$cond = sub { vcmp($_[0],$version) < 0; };
- } elsif ($dep =~ /^==?\s*(\S+)$/) {
- $version = $1;
+ } elsif ($op eq 'equ') {
$cond = sub { vcmp($_[0],$version) == 0; };
- } elsif ($dep =~ /^\s*$/) {
- $cond = sub { 1; };
} else {
- print "# don't know how to handle PreReq: $name $dep\n";
- return;
+ die "FATAL: internal error in dep2target\n";
}
$tdef = undef;
@@ -1037,9 +1210,10 @@
if ($i && (@vers = get_versions($i, $cond))) {
foreach (@vers) {
$t = $i->{$_}->[0];
- if (get_with($t), target_suitable($t, $env->{with})) {
+ get_with($t);
+ if (target_suitable($t, $env->{with})) {
$tdef = $t;
- if (!$env->{upgrade}) {
+ unless ($env->{upgrade}) {
return ($t, 1);
}
}
@@ -1051,7 +1225,10 @@
$t = chose_source($env, $name, $r, get_versions($r, $cond));
if ($t) {
- return ($t, 0);
+ if (!$tdef ||
+ ($env->{upgrade} && target_newer($t, $env->{installed}))) {
+ return ($t, 0);
+ }
}
if ($tdef) {
@@ -1061,7 +1238,9 @@
return;
}
-
+#
+#
+#
sub make_dep ($$$$$$) {
my($target,$depth,$env,$list,$blist,$clist) = @_;
my($d,$k,%d,%k,$t,$old);
@@ -1094,6 +1273,7 @@
print "# excluding $target->{name} (no upgrade allowed)\n";
return;
}
+ # pull in options
get_with($t);
if ($target->{REBUILD}) {
target_setstatus($target,'DEPEND',1);
@@ -1112,7 +1292,7 @@
return;
}
# use options from installed base
- override_options($target->{OPTIONS}, $t->{OPTIONS},
+ override_options(get_with($target), get_with($t),
$env->{config}->{optreg});
# remember this is a rebuild for a proxy package
$target->{PROXY} = $t->{PROXY};
@@ -1137,8 +1317,8 @@
#
if (@$d || @$k) {
- %d = map { $_ => 1 } @$d, @$k;
- %k = map { $_ => 1 } @$k;
+ %d = unique_map($d, $k);
+ %k = unique_map($k);
@deps = ();
$conflict = 0;
@@ -1147,7 +1327,7 @@
# old index misses a OpenPKG provider in the index... skip it
next if $_ eq 'OpenPKG';
- ($t,$old) = dep2target($_, $env);
+ ($t,$old) = dep2target($d{$_}, $env);
if ($t) {
if ($old) {
print "# $target->{name} uses ".vsn($t)." for $_\n";
@@ -1182,9 +1362,13 @@
push(@$list, $target);
foreach (@{$target->{nosource}}) {
- print "# ATTENTION: unpackaged source '$target->{source}->[$_]'\n";
+ print "# ATTENTION: unpackaged source $_: $target->{source}->[$_]\n";
}
+ #
+ # a dependency could not be resolved, don't bother with reverse
+ # dependencies for this target
+ #
return if $conflict;
if (!$env->{quick} &&
@@ -1209,23 +1393,20 @@
}
}
-sub remove_list ($$$) {
- my($targets, $keeps, $installed) = @_;
- my(%keep);
-
- %keep = map { $_ => 1 } @$keeps;
- return [ grep {
- !$keep{$_} && !$installed->{$_->{name}}->{vs($_)};
- } @$targets
- ];
-}
-
+#
+# generate build lists for targets matched by pattern
+#
+# all input and output is passed in 'env' hash
+#
sub build_list ($$) {
my($pattern, $env) = @_;
- my(@goals,@targets,@keeps,@conflicts,$bonly,$t);
+ my(@goals,@targets,@keeps,@conflicts,@bonly,$t);
my($name,$r,$i,@vers);
- my(@todo);
+ my(@todo,%keep);
+ #
+ # handle various patterns
+ #
if (defined $pattern) {
@todo = ();
foreach (split(/\s+/,$pattern)) {
@@ -1241,6 +1422,10 @@
grep(/$p/, keys %{$env->{repository}})
} @todo;
} else {
+ #
+ # undefined pattern means -a option that selects
+ # all packages from repository that are installed
+ #
@todo = grep {
my($n) = $_;
(ref $env->{installed}->{$n}) &&
@@ -1296,13 +1481,23 @@
make_dep($t,0,$env,\@targets,\@keeps,\@conflicts);
}
- $bonly = remove_list(\@targets, \@keeps, $env->{installed});
+ %keep = map { $_ => 1 } @keeps;
+ @bonly = grep {
+ !$keep{$_} && !$env->{installed}->{$_->{name}}->{vs($_)};
+ } @targets;
- return (\@targets, $bonly, \@conflicts);
+ return (\@targets, \@bonly, \@conflicts);
}
#######################################################################
+#
+# OUTPUT
+#
+
+#
+# compute path to binary RPM from rpm config and target data
+#
sub target2rpm ($$) {
my($target,$c) = @_;
my($tmpl) = $c->{template};
@@ -1315,17 +1510,23 @@
return $c->{rpmdir}.'/'.$tmpl;
}
-#######################################################################
-
+#
+# compute new target based on old target augmented with options from
+# a binary RPM file
+#
sub binary_target ($$) {
my($t, $fn) = @_;
my(%target) = %$t;
+ # pull in options from binary RPM file
get_with(\%target, $fn);
return \%target;
}
+#
+# return path to master package for a proxy package
+#
sub find_proxy ($$) {
my($t,$bpkg) = @_;
my(@l) = `$RPM_NPRIV -ql $t->{name}`;
@@ -1339,6 +1540,14 @@
return (glob("$prefix/RPM/PKG/$bpkg"))[0];
}
+#
+# merge parameters from installed package
+# with new parameter set and global parameters
+# from configuration
+#
+# then map the result to --define command line arguments
+# suitable for rpm
+#
sub make_defines ($$$) {
my($old, $new, $c) = @_;
my($with);
@@ -1363,13 +1572,21 @@
# skip parameter templates from index
#
$with = join(' ',map { "--define '$_ $old->{$_}'" }
- grep { $old->{$_} !~ /^%/ } keys %$old);
+ sort grep { $old->{$_} !~ /^%/ } keys %$old);
$with = ' '.$with if $with ne '';
return $with;
}
+#
+# print commands from package build list
+#
+# c -> configuration to derive paths from
+# uncond -> always do the --rebuild
+# with -> parameter set passed to build tool
+# ignore -> generate script that does not stop on error
+#
sub print_list1 ($$$@$) {
my($list,$c,$uncond,$with,$ignore) = @_;
my($spkg,$bpkg,$ppkg);
@@ -1440,6 +1657,12 @@
}
}
+#
+# print commands for the temporary package list
+#
+# temporary packages are only used for building other packages
+# and are removed when everything is done
+#
sub print_list2 ($$) {
my($list,$c) = @_;
my($pkg);
@@ -1450,6 +1673,11 @@
}
}
+#
+# instead of printing a command list, print a status map
+# that shows all packages and how the build process would
+# change their status
+#
sub print_status ($$$$$) {
my($installed,$repository,$list,$bonly,$clist) = @_;
my(%bonly) = map { $_ => 1 } @$bonly;
@@ -1457,6 +1685,7 @@
my($old,$tag,$new);
foreach (@$list, @$clist) {
+ next unless defined $_->{release};
$map{$_->{name}} = {
rel => "$_->{version}-$_->{release}",
status => $_->{STATUS}
@@ -1472,6 +1701,7 @@
@names = keys %map;
foreach $n (keys %$installed) {
+ next if $n =~ /::/;
next if exists $map{$n};
next unless grep { $_ ne '-' } keys %{$installed->{$n}};
$map{$n}->{'status'} = 'OK';
@@ -1479,6 +1709,7 @@
}
foreach $n (keys %$repository) {
+ next if $n =~ /::/;
next if exists $map{$n};
next unless grep { $_ ne '-' } keys %{$repository->{$n}};
$t = find_target($n, $repository);
@@ -1537,18 +1768,16 @@
$url = get_release();
}
-#
# if we read the index from a file we can no longer deduce
# repository paths from index paths. For now lets assume
# that everything is below SRC/ to be compatible with
# existing file indexes.
-#
if (defined $opt_f && !defined $opt_r) {
$url .= 'SRC/';
}
$installed = $opt_Z ? {} : get_installed();
-$repository = get_index($url.'00INDEX.rdf',$opt_f,\%with);
+$repository = get_index($url.'00INDEX.rdf',$opt_f,\%with,$opt_X);
$env = {
config => $config,
@@ .
patch -p0 <<'@@ .'
Index: openpkg-src/openpkg-tool/openpkg-index.pl
============================================================================
$ cvs diff -u -r1.8 -r1.9 openpkg-index.pl
--- openpkg-src/openpkg-tool/openpkg-index.pl 8 Jan 2003 15:12:38 -0000 1.8
+++ openpkg-src/openpkg-tool/openpkg-index.pl 9 Jan 2003 14:23:17 -0000 1.9
@@ -68,11 +68,48 @@
return $s;
}
+my %attrname = (
+ '==' => 'equ',
+ '=' => 'equ',
+ '>=' => 'geq',
+ '=>' => 'geq',
+ '<=' => 'leq',
+ '=<' => 'leq',
+ '>' => 'gt',
+ '<' => 'lt'
+);
+my($opreg) = join '|',
+ map {
+ "\Q$_\E"
+ } sort {
+ length($b) <=> length($a) ||
+ $b cmp $a
+ } keys %attrname;
+
+sub make_resource ($) {
+ my($s) = @_;
+
+ if ($s =~ /(\S+)\s*($opreg)\s*(.*?)\s*$/o) {
+ return {
+ resource => $1,
+ attrname => $attrname{$2},
+ attrval => $3
+ }
+ }
+
+ return {
+ resource => $s
+ }
+}
+
sub commasep ($$) {
my($k,$v) = @_;
- if ($k =~ /^(PreReq|BuildPreReq|Provides|Conflicts|NoSource)$/) {
+ if ($k =~ /^(NoSource)$/) {
return split(/\s*,\s*/, $v);
+ } elsif ($k =~ /^(PreReq|BuildPreReq|Provides|Conflicts)$/) {
+ return map { make_resource($_) }
+ split(/\s*,\s*/, $v);
}
return $v;
@@ -289,8 +326,11 @@
# store option for current condition
#
if (exists $attr{'Name'}->{''}) {
- push @{$attr{'Provides'}->{$cond}},
- $attr{'Name'}->{''}->[0].'::'.$1.' = '.optesc($2);
+ push @{$attr{'Provides'}->{$cond}}, {
+ resource => $attr{'Name'}->{''}->[0].'::'.$1,
+ attrname => 'equ',
+ attrval => optesc($2)
+ }
} else {
warn "ERROR: no package name set for option $1 = $2\n";
}
@@ -455,7 +495,16 @@
($cond ne '' ? "<$tag cond=\"$upn\">\n" : "<$tag>\n").
"$i <rdf:bag>\n".
join("",
- map { "$i <rdf:li>".e($_)."</rdf:li>\n" }
+ map {
+ ref $_
+ ? "$i <resource".
+ ( exists $_->{attrname}
+ ? " $_->{attrname}=\"".e($_->{attrval})."\""
+ : ""
+ ).
+ ">".e($_->{resource})."</resource>\n"
+ : "$i <rdf:li>".e($_)."</rdf:li>\n"
+ }
@{$a->{$k}->{$cond}}).
"$i </rdf:bag>\n".
"$i</$tag>\n";
@@ -819,7 +868,7 @@
if (/\.spec$/) {
$spec = readfile($_);
$a = spec2data($spec);
- } elsif (/([^\/]+\.src\.rpm)$/) {
+ } elsif (/([^\/]+\.(?:no)?src\.rpm)$/) {
$h = relpath($prefix, $_);
if ($cache) {
$mtime = (stat $_)[9];
@@ .
patch -p0 <<'@@ .'
Index: openpkg-src/openpkg-tool/openpkg-tool.spec
============================================================================
$ cvs diff -u -r1.19 -r1.20 openpkg-tool.spec
--- openpkg-src/openpkg-tool/openpkg-tool.spec 8 Jan 2003 15:12:38 -0000
1.19
+++ openpkg-src/openpkg-tool/openpkg-tool.spec 9 Jan 2003 14:23:17 -0000
1.20
@@ -32,8 +32,8 @@
Distribution: OpenPKG [EVAL]
Group: Bootstrapping
License: GPL
-Version: 20030108
-Release: 20030108
+Version: 20030109
+Release: 20030109
# list of sources
Source0: openpkg.sh
@@ .
patch -p0 <<'@@ .'
Index: openpkg-src/openpkg-tool/openpkg.pod
============================================================================
$ cvs diff -u -r1.7 -r1.8 openpkg.pod
--- openpkg-src/openpkg-tool/openpkg.pod 30 Dec 2002 22:05:36 -0000 1.7
+++ openpkg-src/openpkg-tool/openpkg.pod 9 Jan 2003 14:23:17 -0000 1.8
@@ -59,6 +59,7 @@
[B<-q>]
[B<-s>]
[B<-S>]
+[B<-X>]
[B<-P> I<priv-cmd>]
[B<-N> I<non-priv-cmd>]
[B<-p> I<platform>]
@@ -248,6 +249,11 @@
The package exists in the repository but isn't required yet.
=back
+
+=item B<-X>
+
+Ignore an installed XML parser module but use the internal
+simple text parser instead.
=item B<-P> I<priv-cmd>
@@ .
patch -p0 <<'@@ .'
Index: openpkg-web/news.txt
============================================================================
$ cvs diff -u -r1.2623 -r1.2624 news.txt
--- openpkg-web/news.txt 9 Jan 2003 14:02:56 -0000 1.2623
+++ openpkg-web/news.txt 9 Jan 2003 14:23:16 -0000 1.2624
@@ -1,3 +1,4 @@
+09-Jan-2003: Upgraded package: P<openpkg-tool-20030109-20030109>
09-Jan-2003: Upgraded package: P<make-3.80-20030109>
09-Jan-2003: Upgraded package: P<openpkg-20030109-20030109>
09-Jan-2003: Upgraded package: P<perl-gd-20030109-20030109>
@@ .
______________________________________________________________________
The OpenPKG Project www.openpkg.org
CVS Repository Commit List [EMAIL PROTECTED]