Hi! My patch creates remove041.py remove050.py and patches remove040.py. I removed a messy part of the source and patched sync.c instead; and implemented sophisticated (but slower) remove-checkdep (derived from the upgrade-checkdep). I also add a small speed-tuning to upgrade-checkdep ;-) Notes: sync895.py reports false error imho, we should implement --debug to pactest. (sync.c lines 680- is very messy... ) Enjoy, ngaba -------------------- diff -Naur pacman-lib/lib/libalpm/deps.c pacman-lib.new/lib/libalpm/deps.c --- pacman-lib/lib/libalpm/deps.c 2007-03-19 05:23:45.000000000 +0100 +++ pacman-lib.new/lib/libalpm/deps.c 2007-04-21 22:45:25.000000000 +0200 @@ -234,12 +234,12 @@ for(j = alpm_pkg_get_requiredby(oldpkg); j; j = j->next) { pmpkg_t *p; found = 0; - if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) { - /* hmmm... package isn't installed.. */ + if(_alpm_pkg_find(j->data, packages)) { + /* this package also in the upgrade list, so don't worry about it */ continue; } - if(_alpm_pkg_find(alpm_pkg_get_name(p), packages)) { - /* this package also in the upgrade list, so don't worry about it */ + if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) { + /* hmmm... package isn't installed.. */ continue; } for(k = alpm_pkg_get_depends(p); k; k = k->next) { @@ -370,52 +370,55 @@ } } } else if(op == PM_TRANS_TYPE_REMOVE) { - /* check requiredby fields */ for(i = packages; i; i = i->next) { - pmpkg_t *tp = i->data; - if(tp == NULL) { + pmpkg_t *rempkg = i->data; + + if(rempkg == NULL) { + _alpm_log(PM_LOG_DEBUG, _("null package found in package list")); continue; } - found=0; - for(j = alpm_pkg_get_requiredby(tp); j; j = j->next) { - /* Search for 'reqname' in packages for removal */ - char *reqname = j->data; - alpm_list_t *x = NULL; - for(x = packages; x; x = x->next) { - pmpkg_t *xp = x->data; - if(strcmp(reqname, alpm_pkg_get_name(xp)) == 0) { - found = 1; - break; - } + for(j = alpm_pkg_get_requiredby(rempkg); j; j = j->next) { + pmpkg_t *p; + found = 0; + if(_alpm_pkg_find(j->data, packages)) { + /* this package also in the remove list, so don't worry about it */ + continue; } - if(!found) { - /* check if a package in trans->packages provides this package */ - for(k = trans->packages; !found && k; k=k->next) { - pmpkg_t *spkg = NULL; - if(trans->type == PM_TRANS_TYPE_SYNC) { - pmsyncpkg_t *sync = k->data; - spkg = sync->pkg; - } else { - spkg = k->data; - } - if(spkg) { - if(alpm_list_find_str(alpm_pkg_get_provides(spkg), tp->name)) { - found = 1; + if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) { + /* hmmm... package isn't installed.. */ + continue; + } + for(k = alpm_pkg_get_depends(p); k; k = k->next) { + pmdepend_t *depend = alpm_splitdep(k->data); + if(depend == NULL) { + continue; + } + /* if rempkg satisfied this dep, we try to find an other satisfyer (which won't be removed)*/ + if(alpm_depcmp(rempkg, depend)) { + int satisfied = 0; + for(l = _alpm_db_get_pkgcache(db); l; l = l->next) { + pmpkg_t *pkg = l->data; + if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) { + _alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' satisfied by installed package '%s'"), + depend->name, alpm_pkg_get_name(pkg)); + satisfied = 1; + break; } } - } - if(!found) { - _alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"), - reqname, alpm_pkg_get_name(tp)); - miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), PM_DEP_TYPE_DEPEND, - PM_DEP_MOD_ANY, j->data, NULL); - if(!_alpm_depmiss_isin(miss, baddeps)) { - baddeps = alpm_list_add(baddeps, miss); - } else { - FREE(miss); + if(!satisfied) { + _alpm_log(PM_LOG_DEBUG, _("checkdeps: found %s as required by %s"), + alpm_pkg_get_name(rempkg), alpm_pkg_get_name(p)); + miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_DEPEND, depend->mod, + depend->name, depend->version); + if(!_alpm_depmiss_isin(miss, baddeps)) { + baddeps = alpm_list_add(baddeps, miss); + } else { + FREE(miss); + } } } + free(depend); } } } diff -Naur pacman-lib/pactest/tests/remove040.py pacman-lib.new/pactest/tests/remove040.py --- pacman-lib/pactest/tests/remove040.py 2007-03-04 01:14:26.000000000 +0100 +++ pacman-lib.new/pactest/tests/remove040.py 2007-04-21 21:00:03.000000000 +0200 @@ -10,9 +10,9 @@ self.addpkg2db("local", lp2) -self.args = "-R %s" % lp1.name +self.args = "-R %s" % lp2.name -self.addrule("PACMAN_RETCODE=0") -self.addrule("!PKG_EXIST=pkg1") +self.addrule("!PACMAN_RETCODE=0") +self.addrule("PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") -self.addrule("!PKG_REQUIREDBY=pkg2|pkg1") +self.addrule("PKG_REQUIREDBY=pkg2|pkg1") diff -Naur pacman-lib/pactest/tests/remove041.py pacman-lib.new/pactest/tests/remove041.py --- pacman-lib/pactest/tests/remove041.py 1970-01-01 01:00:00.000000000 +0100 +++ pacman-lib.new/pactest/tests/remove041.py 2007-04-21 22:56:16.000000000 +0200 @@ -0,0 +1,21 @@ +self.description = "Remove a package required by another package, but no longer needed (multiple provision)" + +lp1 = pmpkg("pkg1") +lp1.provides = ["imaginary"] +lp1.requiredby = ["pkg3"] +self.addpkg2db("local", lp1) + +lp2 = pmpkg("pkg2") +lp2.provides = ["imaginary"] +lp2.requiredby = ["pkg3"] +self.addpkg2db("local", lp2) + +lp3 = pmpkg("pkg3") +lp3.depends = ["imaginary"] +self.addpkg2db("local", lp3) + +self.args = "-R %s" % lp1.name + +self.addrule("PACMAN_RETCODE=0") +self.addrule("!PKG_EXIST=pkg1") +self.addrule("PKG_EXIST=pkg2")