mirror of
https://github.com/moparisthebest/pacman
synced 2025-02-28 09:21:53 -05:00
libalpm/deps.c : fix for remove044 pactest.
Patch from Nagy that makes removedeps use alpm_depcmp. I also renamed removedeps to recursedeps, as it can have a more general usage, and added an include_explicit argument, so we can control if packages explictly installed are added or not. Note: Small changes made by me (Dan) as well- mostly some English grammar correction and a few other cleanups. Signed-off-by: Chantry Xavier <shiningxc@gmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
8d62835ba1
commit
1c9f30b9fa
@ -520,10 +520,12 @@ pmdepend_t SYMEXPORT *alpm_splitdep(const char *depstring)
|
||||
return(depend);
|
||||
}
|
||||
|
||||
/* These parameters are messy. We check if this package, given a list of
|
||||
* targets (and a db), is safe to remove. We do NOT remove it if it is in the
|
||||
* target list */
|
||||
static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
|
||||
/* These parameters are messy. We check if this package, given a list of
|
||||
* targets and a db is safe to remove. We do NOT remove it if it is in the
|
||||
* target list, or if if the package was explictly installed and
|
||||
* include_explicit == 0 */
|
||||
static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets,
|
||||
int include_explicit)
|
||||
{
|
||||
alpm_list_t *i;
|
||||
|
||||
@ -531,13 +533,21 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* see if it was explicitly installed */
|
||||
if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
|
||||
_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed",
|
||||
alpm_pkg_get_name(pkg));
|
||||
return(0);
|
||||
if(!include_explicit) {
|
||||
/* see if it was explicitly installed */
|
||||
if(alpm_pkg_get_reason(pkg) == PM_PKG_REASON_EXPLICIT) {
|
||||
_alpm_log(PM_LOG_DEBUG, "excluding %s -- explicitly installed",
|
||||
alpm_pkg_get_name(pkg));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: checkdeps could be used here, it handles multiple providers
|
||||
* better, but that also makes it slower.
|
||||
* Also this would require to first add the package to the targets list,
|
||||
* then call checkdeps with it, then remove the package from the targets list
|
||||
* if checkdeps detected it would break something */
|
||||
|
||||
/* see if other packages need it */
|
||||
for(i = alpm_pkg_get_requiredby(pkg); i; i = i->next) {
|
||||
pmpkg_t *reqpkg = _alpm_db_get_pkgfromcache(db, i->data);
|
||||
@ -550,69 +560,55 @@ static int can_remove_package(pmdb_t *db, pmpkg_t *pkg, alpm_list_t *targets)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* return a new alpm_list_t target list containing all packages in the original
|
||||
* target list, as well as all their un-needed dependencies. By un-needed,
|
||||
* I mean dependencies that are *only* required for packages in the target
|
||||
* list, so they can be safely removed. This function is recursive.
|
||||
/**
|
||||
* @brief Adds unneeded dependencies to an existing list of packages.
|
||||
* By unneeded, we mean dependencies that are only required by packages in the
|
||||
* target list, so they can be safely removed.
|
||||
*
|
||||
* @param db package database to do dependency tracing in
|
||||
* @param *targs pointer to a list of packages
|
||||
* @param include_explicit if 0, explicitly installed packages are not included
|
||||
*/
|
||||
alpm_list_t *_alpm_removedeps(pmdb_t *db, alpm_list_t *targs)
|
||||
void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit)
|
||||
{
|
||||
alpm_list_t *i, *j, *k;
|
||||
alpm_list_t *newtargs = targs;
|
||||
|
||||
ALPM_LOG_FUNC;
|
||||
|
||||
if(db == NULL) {
|
||||
return(newtargs);
|
||||
if(db == NULL || targs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = targs; i; i = i->next) {
|
||||
pmpkg_t *pkg = i->data;
|
||||
for(j = alpm_pkg_get_depends(pkg); j; j = j->next) {
|
||||
pmdepend_t *depend = alpm_splitdep(j->data);
|
||||
pmpkg_t *deppkg;
|
||||
if(depend == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
deppkg = _alpm_db_get_pkgfromcache(db, depend->name);
|
||||
if(deppkg == NULL) {
|
||||
/* package not found... look for a provision instead */
|
||||
alpm_list_t *provides = _alpm_db_whatprovides(db, depend->name);
|
||||
if(!provides) {
|
||||
/* Not found, that's fine, carry on */
|
||||
_alpm_log(PM_LOG_DEBUG, "cannot find package \"%s\" or anything that provides it!", depend->name);
|
||||
/* TODO: the while loop should be removed if we can assume
|
||||
* that alpm_list_add (or another function) adds to the end of the list,
|
||||
* and that the target list is topo sorted (by _alpm_sortbydeps()).
|
||||
*/
|
||||
int ready = 0;
|
||||
while(!ready) {
|
||||
ready = 1;
|
||||
for(i = *targs; i; i = i->next) {
|
||||
pmpkg_t *pkg = i->data;
|
||||
for(j = alpm_pkg_get_depends(pkg); j; j = j->next) {
|
||||
pmdepend_t *depend = alpm_splitdep(j->data);
|
||||
if(depend == NULL) {
|
||||
continue;
|
||||
}
|
||||
for(k = provides; k; k = k->next) {
|
||||
pmpkg_t *provpkg = k->data;
|
||||
if(can_remove_package(db, provpkg, newtargs)) {
|
||||
pmpkg_t *pkg = _alpm_pkg_dup(provpkg);
|
||||
|
||||
for(k = _alpm_db_get_pkgcache(db); k; k = k->next) {
|
||||
pmpkg_t *deppkg = k->data;
|
||||
if(alpm_depcmp(deppkg,depend)
|
||||
&& can_remove_package(db, deppkg, *targs, include_explicit)) {
|
||||
_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets",
|
||||
alpm_pkg_get_name(pkg));
|
||||
alpm_pkg_get_name(deppkg));
|
||||
|
||||
/* add it to the target list */
|
||||
newtargs = alpm_list_add(newtargs, pkg);
|
||||
newtargs = _alpm_removedeps(db, newtargs);
|
||||
*targs = alpm_list_add(*targs, _alpm_pkg_dup(deppkg));
|
||||
ready = 0;
|
||||
}
|
||||
}
|
||||
alpm_list_free(provides);
|
||||
} else if(can_remove_package(db, deppkg, newtargs)) {
|
||||
pmpkg_t *pkg = _alpm_pkg_dup(deppkg);
|
||||
|
||||
_alpm_log(PM_LOG_DEBUG, "adding '%s' to the targets",
|
||||
alpm_pkg_get_name(pkg));
|
||||
|
||||
/* add it to the target list */
|
||||
newtargs = alpm_list_add(newtargs, pkg);
|
||||
newtargs = _alpm_removedeps(db, newtargs);
|
||||
free(depend);
|
||||
}
|
||||
free(depend);
|
||||
}
|
||||
}
|
||||
|
||||
return(newtargs);
|
||||
}
|
||||
|
||||
/* populates *list with packages that need to be installed to satisfy all
|
||||
|
@ -58,7 +58,7 @@ int _alpm_depmiss_isin(pmdepmissing_t *needle, alpm_list_t *haystack);
|
||||
alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode);
|
||||
alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
||||
alpm_list_t *packages);
|
||||
alpm_list_t *_alpm_removedeps(pmdb_t *db, alpm_list_t *targs);
|
||||
void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit);
|
||||
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
||||
alpm_list_t *list, alpm_list_t *trail, pmtrans_t *trans,
|
||||
alpm_list_t **data);
|
||||
|
@ -135,11 +135,6 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
|
||||
}
|
||||
}
|
||||
|
||||
if(trans->flags & PM_TRANS_FLAG_RECURSE) {
|
||||
_alpm_log(PM_LOG_DEBUG, "finding removable dependencies");
|
||||
trans->packages = _alpm_removedeps(db, trans->packages);
|
||||
}
|
||||
|
||||
/* re-order w.r.t. dependencies */
|
||||
_alpm_log(PM_LOG_DEBUG, "sorting by dependencies");
|
||||
lp = _alpm_sortbydeps(trans->packages, PM_TRANS_TYPE_REMOVE);
|
||||
@ -147,6 +142,11 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
|
||||
alpm_list_free(trans->packages);
|
||||
trans->packages = lp;
|
||||
|
||||
if(trans->flags & PM_TRANS_FLAG_RECURSE) {
|
||||
_alpm_log(PM_LOG_DEBUG, "finding removable dependencies");
|
||||
_alpm_recursedeps(db, &trans->packages, 0);
|
||||
}
|
||||
|
||||
EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);
|
||||
|
||||
return(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user