From d3ca123d6a9dafdb76e961ee975db38f015d1371 Mon Sep 17 00:00:00 2001 From: Francois Pons Date: Mon, 2 Jun 2003 16:38:41 +0000 Subject: 0.90-4mdk --- URPM.xs | 126 +++++++++++++++++++++++++++++++------------------------- URPM/Resolve.pm | 61 ++++++++++++++++++++++++--- perl-URPM.spec | 10 ++++- 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 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 0.90-3mdk - add license function for urpm->{depslist}[$id] -- cgit v1.2.1