aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--URPM.xs126
-rw-r--r--URPM/Resolve.pm61
-rw-r--r--perl-URPM.spec10
3 files changed, 134 insertions, 63 deletions
diff --git a/URPM.xs b/URPM.xs
index e449c4d..37f6f6a 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -900,6 +900,34 @@ open_archive(char *filename, pid_t *pid) {
return fd;
}
+static int
+call_package_callback(SV *urpm, SV *sv_pkg, SV *callback) {
+ if (sv_pkg != NULL && callback != NULL) {
+ int count;
+
+ /* now, a callback will be called for sure */
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(sp);
+ XPUSHs(urpm);
+ XPUSHs(sv_pkg);
+ PUTBACK;
+ count = call_sv(callback, G_SCALAR);
+ SPAGAIN;
+ if (count == 1 && !POPi) {
+ /* package should not be added in depslist, so we free it */
+ SvREFCNT_dec(sv_pkg);
+ sv_pkg = NULL;
+ }
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
+
+ return sv_pkg != NULL;
+}
+
static void
parse_line(AV *depslist, HV *provides, URPM__Package pkg, char *buff, SV *urpm, SV *callback) {
SV *sv_pkg;
@@ -916,24 +944,7 @@ parse_line(AV *depslist, HV *provides, URPM__Package pkg, char *buff, SV *urpm,
pkg->flag |= 1 + av_len(depslist);
sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package",
_pkg = memcpy(malloc(sizeof(struct s_Package)), pkg, sizeof(struct s_Package)));
- if (callback != NULL) {
- /* now, a callback will be called for sure */
- dSP;
- PUSHMARK(sp);
- XPUSHs(urpm);
- XPUSHs(sv_pkg);
- PUTBACK;
- if (call_sv(callback, G_SCALAR) == 1) {
- SPAGAIN;
- if (!POPi) {
- /* package should not be added in depslist, so we free it */
- SvREFCNT_dec(sv_pkg);
- sv_pkg = NULL;
- }
- PUTBACK;
- }
- }
- if (sv_pkg) {
+ if (call_package_callback(urpm, sv_pkg, callback)) {
if (provides) update_provides(_pkg, provides);
av_push(depslist, sv_pkg);
}
@@ -953,7 +964,7 @@ parse_line(AV *depslist, HV *provides, URPM__Package pkg, char *buff, SV *urpm,
}
static int
-update_header(char *filename, URPM__Package pkg, HV *provides, int packing, int keep_all_tags) {
+update_header(char *filename, URPM__Package pkg, int keep_all_tags) {
int d = open(filename, O_RDONLY);
if (d >= 0) {
@@ -994,12 +1005,7 @@ update_header(char *filename, URPM__Package pkg, HV *provides, int packing, int
pkg->h = header;
pkg->flag &= ~FLAG_NO_HEADER_FREE;
- if (provides) {
- update_provides(pkg, provides);
- update_provides_files(pkg, provides);
- }
- if (packing) pack_header(pkg);
- else if (!keep_all_tags) {
+ if (!keep_all_tags) {
headerRemoveEntry(pkg->h, RPMTAG_POSTIN);
headerRemoveEntry(pkg->h, RPMTAG_POSTUN);
headerRemoveEntry(pkg->h, RPMTAG_PREIN);
@@ -1831,13 +1837,31 @@ Pkg_pack_header(pkg)
pack_header(pkg);
int
-Pkg_update_header(pkg, filename, packing=0, keep_all_tags=0)
+Pkg_update_header(pkg, filename, ...)
URPM::Package pkg
char *filename
- int packing
- int keep_all_tags
+ PREINIT:
+ int packing = 0;
+ int keep_all_tags = 0;
CODE:
- RETVAL = update_header(filename, pkg, NULL, packing, keep_all_tags);
+ /* compability mode with older interface of parse_hdlist */
+ if (items == 3) {
+ packing = SvIV(ST(2));
+ } else if (items > 3) {
+ int i;
+ for (i = 2; i < items-1; i+=2) {
+ STRLEN len;
+ char *s = SvPV(ST(i), len);
+
+ if (len == 7 && !memcmp(s, "packing", 7)) {
+ packing = SvIV(ST(i + 1));
+ } else if (len == 13 && !memcmp(s, "keep_all_tags", 13)) {
+ keep_all_tags = SvIV(ST(i+1));
+ }
+ }
+ }
+ RETVAL = update_header(filename, pkg, !packing && keep_all_tags);
+ if (RETVAL && packing) pack_header(pkg);
OUTPUT:
RETVAL
@@ -2865,28 +2889,7 @@ Urpm_parse_hdlist(urpm, filename, ...)
pkg.h = header;
sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package",
_pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package)));
- if (callback != NULL) {
- int count;
-
- /* now, a callback will be called for sure */
- ENTER;
- SAVETMPS;
- PUSHMARK(sp);
- XPUSHs(urpm);
- XPUSHs(sv_pkg);
- PUTBACK;
- count = call_sv(callback, G_SCALAR);
- SPAGAIN;
- if (count == 1 && !POPi) {
- /* package should not be added in depslist, so we free it */
- SvREFCNT_dec(sv_pkg);
- sv_pkg = NULL;
- }
- PUTBACK;
- FREETMPS;
- LEAVE;
- }
- if (sv_pkg) {
+ if (call_package_callback(urpm, sv_pkg, callback)) {
if (provides) {
update_provides(_pkg, provides);
update_provides_files(_pkg, provides);
@@ -2911,11 +2914,9 @@ Urpm_parse_hdlist(urpm, filename, ...)
} else croak("first argument should be a reference to HASH");
void
-Urpm_parse_rpm(urpm, filename, packing=0, keep_all_tags=0)
+Urpm_parse_rpm(urpm, filename, ...)
SV *urpm
char *filename
- int packing;
- int keep_all_tags;
PPCODE:
if (SvROK(urpm) && SvTYPE(SvRV(urpm)) == SVt_PVHV) {
SV **fdepslist = hv_fetch((HV*)SvRV(urpm), "depslist", 8, 0);
@@ -2924,7 +2925,10 @@ Urpm_parse_rpm(urpm, filename, packing=0, keep_all_tags=0)
HV *provides = fprovides && SvROK(*fprovides) && SvTYPE(SvRV(*fprovides)) == SVt_PVHV ? (HV*)SvRV(*fprovides) : NULL;
if (depslist != NULL) {
- struct s_Package pkg;
+ struct s_Package pkg, *_pkg;
+ SV *sv_pkg;
+ int packing = 0;
+ int keep_all_tags = 0;
SV *callback = NULL;
/* compability mode with older interface of parse_hdlist */
@@ -2947,7 +2951,17 @@ Urpm_parse_rpm(urpm, filename, packing=0, keep_all_tags=0)
}
memset(&pkg, 0, sizeof(struct s_Package));
pkg.flag = 1 + av_len(depslist);
- if (update_header(filename, &pkg, provides, packing, keep_all_tags)) {
+ sv_pkg = sv_setref_pv(newSVpv("", 0), "URPM::Package",
+ _pkg = memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package)));
+ if (update_header(filename, &_pkg, keep_all_tags)) {
+ if (call_package_callback(urpm, sv_pkg, callback)) {
+ if (provides) {
+ update_provides(_pkg, provides);
+ update_provides_files(_pkg, provides);
+ }
+ if (packing) pack_header(_pkg);
+ av_push(depslist, sv_pkg);
+ }
av_push(depslist, sv_setref_pv(newSVpv("", 0), "URPM::Package",
memcpy(malloc(sizeof(struct s_Package)), &pkg, sizeof(struct s_Package))));
diff --git a/URPM/Resolve.pm b/URPM/Resolve.pm
index 73098d5..8b68932 100644
--- a/URPM/Resolve.pm
+++ b/URPM/Resolve.pm
@@ -221,11 +221,15 @@ sub backtrack_selected {
}
}
$state->{backtrack}{selected}{$_->id} = undef;
+
#- in such case, we need to drop the problem caused so that rejected condition is removed.
#- if this is not possible, the next backtrack on the same package will be refused above.
- $urpm->disable_selected($db, $state,
- map { $urpm->search($_, strict_fullname => 1) }
- keys %{($state->{rejected}{$_->fullname} || {})->{closure}});
+ my @l = map { $urpm->search($_, strict_fullname => 1) }
+ keys %{($state->{rejected}{$_->fullname} || {})->{closure}};
+
+ $options{keep_unrequested_dependencies} ? $urpm->disable_selected($db, $state, @l) :
+ $urpm->disable_selected_unrequested_dependencies($db, $state, @l);
+
return { required => $_->id,
exists $dep->{from} ? (from => $dep->{from}) : @{[]},
exists $dep->{requested} ? (requested => $dep->{requested}) : @{[]},
@@ -237,9 +241,10 @@ sub backtrack_selected {
#- at this point, dep cannot be resolved, this means we need to disable
#- all selection tree, re-enabling removed and obsoleted packages as well.
if (defined $dep->{from}) {
- unless (exists $state->{rejected}{$dep->{from}->fullname}) {
+ unless ($options{nodeps} || exists $state->{rejected}{$dep->{from}->fullname}) {
#- package is not currently rejected, compute the closure now.
- my @l = $urpm->disable_selected($db, $state, $dep->{from});
+ my @l = $options{keep_unrequested_dependencies} ? $urpm->disable_selected($db, $state, $dep->{from}) :
+ $urpm->disable_selected_unrequested_dependencies($db, $state, $dep->{from});
foreach (@l) {
#- disable all these packages in order to avoid selecting them again.
$_->fullname eq $dep->{from}->fullname or
@@ -366,7 +371,7 @@ sub resolve_requested {
#- if multiple packages are possible, simply ask the user which one to choose.
#- else take the first one available.
if (!@chosen) {
- unshift @properties, $urpm->backtrack_selected($db, $state, $dep);
+ unshift @properties, $urpm->backtrack_selected($db, $state, $dep, %options);
next; #- backtrack code choose to continue with same package or completely new strategy.
} elsif ($options{callback_choices} && @chosen > 1) {
unshift @properties, map { +{ required => $_->id,
@@ -640,6 +645,50 @@ sub disable_selected {
@unselected;
}
+#- determine dependencies that can safely been removed and are not requested,
+sub disable_selected_unrequested_dependencies {
+ my ($urpm, $db, $state, @closure) = @_;
+ my @unselected_closure;
+
+ #- disable selected packages, then extend unselection to all required packages
+ #- no more needed and not requested.
+ while (my @unselected = disable_selected($db, $state, @closure)) {
+ my %required;
+
+ #- keep in mind averything that have been unselected.
+ push @unselected_closure, @unselected;
+
+ #- search for unrequested required packages.
+ foreach (@unselected) {
+ foreach ($_->requires_nosense) {
+ foreach (keys %{$urpm->{provides}{$_} || {}}) {
+ my $pkg = $urpm->{depslist}[$_] or next;
+ $pkg->flag_selected || exists $state->{selected}{$pkg->id} or next;
+ $pkg->flag_requested and next;
+ $required{$pkg->id} = undef;
+ }
+ }
+ }
+
+ #- check required packages are not needed by another selected package.
+ foreach (keys %required) {
+ my $pkg = $urpm->{depslist}[$_] or next;
+ foreach ($pkg->provides_nosense) {
+ foreach (keys %{$state->{whatrequires}{$_}}) {
+ my $p = $urpm->{depslist}[$_] or next;
+ $p eq $pkg and next;
+ $p->flag_selected and $required{$pkg->id} = 1;
+ }
+ }
+ }
+
+ #- now required values still undefined indicates packages than can be removed.
+ @closure = map { $urpm->{depslist}[$_] } grep { !$required{$_} } keys %required;
+ }
+
+ @unselected_closure;
+}
+
#- compute installed flags for all package in depslist.
sub compute_installed_flags {
my ($urpm, $db) = @_;
diff --git a/perl-URPM.spec b/perl-URPM.spec
index 7f0c365..a2da908 100644
--- a/perl-URPM.spec
+++ b/perl-URPM.spec
@@ -1,7 +1,7 @@
%define name perl-URPM
%define real_name URPM
%define version 0.90
-%define release 3mdk
+%define release 4mdk
%{expand:%%define rpm_version %(rpm -q --queryformat '%{VERSION}-%{RELEASE}' rpm)}
@@ -51,6 +51,14 @@ rm -rf $RPM_BUILD_ROOT
%changelog
+* Mon Jun 2 2003 François Pons <fpons@mandrakesoft.com> 0.90-4mdk
+- added an option to disable unrequested dependencies when
+ backtracking a selection.
+- added an option to avoid deselecting package with broken
+ dependencies.
+- simplified update_header and parse_rpm methods.
+- cleaned XS code.
+
* Wed May 28 2003 Warly <warly@mandrakesoft.com> 0.90-3mdk
- add license function for urpm->{depslist}[$id]