From 7d37d9278d0ab6eb46ec4689c8091780382cbb95 Mon Sep 17 00:00:00 2001 From: Nagy Gabor Date: Sun, 12 Aug 2007 22:26:54 +0200 Subject: [PATCH] Fix for sync1003 and sync1004 pactests checkdeps and resolvedeps now take both a remove list and an install list as arguments, allowing dependencies to be calculated correctly. This broke the sync990 pactest, but this pactest used dependencies and provides in an unusual way, so it has been changed. Dan: the sync990 pactest was just plain wrong. It didn't satisfy the dependencies correctly, so should never have succeeded. Signed-off-by: Chantry Xavier [Dan: some variable renaming, clarification in commit message] Signed-off-by: Dan McGee --- lib/libalpm/add.c | 2 +- lib/libalpm/alpm.h | 4 +- lib/libalpm/deps.c | 283 +++++++++++++++++---------------------- lib/libalpm/deps.h | 4 +- lib/libalpm/remove.c | 4 +- lib/libalpm/sync.c | 98 +++++--------- pactest/tests/sync990.py | 7 +- src/util/testdb.c | 2 +- 8 files changed, 161 insertions(+), 243 deletions(-) diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 0b40f957..3b51110b 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -140,7 +140,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) /* look for unsatisfied dependencies */ _alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); - lp = _alpm_checkdeps(db, trans->type, trans->packages); + lp = alpm_checkdeps(db, trans->type == PM_TRANS_TYPE_UPGRADE, NULL, trans->packages); if(lp != NULL) { if(data) { *data = lp; diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 76c7208a..335ce39e 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -370,8 +370,8 @@ typedef enum _pmdepmod_t { pmdepend_t *alpm_splitdep(const char *depstring); int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep); -alpm_list_t *alpm_checkdeps(pmdb_t *db, pmtranstype_t op, - alpm_list_t *packages); +alpm_list_t *alpm_checkdeps(pmdb_t *db, int reversedeps, + alpm_list_t *remove, alpm_list_t *upgrade); const char *alpm_miss_get_target(const pmdepmissing_t *miss); pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss); diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index ac07c0b7..4a4f6545 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -121,7 +121,7 @@ static alpm_list_t *_alpm_graph_init(alpm_list_t *targets) for(i = vertices; i; i = i->next) { pmgraph_t *vertex_i = i->data; pmpkg_t *p_i = vertex_i->data; - /* TODO this should be somehow combined with _alpm_checkdeps */ + /* TODO this should be somehow combined with alpm_checkdeps */ for(j = vertices; j; j = j->next) { pmgraph_t *vertex_j = j->data; pmpkg_t *p_j = vertex_j->data; @@ -232,18 +232,13 @@ alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, pmtranstype_t mode) /** Checks dependencies and returns missing ones in a list. * Dependencies can include versions with depmod operators. * @param db pointer to the local package database - * @param op transaction type - * @param packages an alpm_list_t* of packages to be checked + * @param reversedeps handles the backward dependencies + * @param remove an alpm_list_t* of packages to be removed + * @param upgrade an alpm_list_t* of packages to be upgraded (remove-then-upgrade) * @return an alpm_list_t* of pmpkg_t* of missing_t pointers. */ -alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, pmtranstype_t op, - alpm_list_t *packages) -{ - return(_alpm_checkdeps(db, op, packages)); -} - -alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, - alpm_list_t *packages) +alpm_list_t SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps, + alpm_list_t *remove, alpm_list_t *upgrade) { alpm_list_t *i, *j, *k, *l; int found = 0; @@ -256,16 +251,68 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, return(NULL); } - if(op == PM_TRANS_TYPE_UPGRADE) { - /* PM_TRANS_TYPE_UPGRADE handles the backwards dependencies, ie, - * the packages listed in the requiredby field. - */ - for(i = packages; i; i = i->next) { + /* look for unsatisfied dependencies of the upgrade list */ + for(i = upgrade; i; i = i->next) { + pmpkg_t *tp = i->data; + if(tp == NULL) { + _alpm_log(PM_LOG_DEBUG, "null package found in upgrade list\n"); + continue; + } + _alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n", + alpm_pkg_get_name(tp), alpm_pkg_get_version(tp)); + + for(j = alpm_pkg_get_depends(tp); j; j = j->next) { + /* split into name/version pairs */ + pmdepend_t *depend = j->data; + found = 0; + /* 1. we check the upgrade list */ + for(k = upgrade; k && !found; k = k->next) { + pmpkg_t *p = k->data; + found = p && alpm_depcmp(p, depend); + } + /* 2. we check database for untouched satisfying packages */ + for(k = _alpm_db_get_pkgcache(db); k && !found; k = k->next) { + pmpkg_t *p = k->data; + found = p && alpm_depcmp(p, depend) + && !_alpm_pkg_find(alpm_pkg_get_name(p), upgrade) + && !_alpm_pkg_find(alpm_pkg_get_name(p), remove); + } + /* else if still not found... */ + if(!found) { + char *missdepstring = alpm_dep_get_string(depend); + _alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n", + missdepstring, alpm_pkg_get_name(tp)); + free(missdepstring); + miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod, + depend->name, depend->version); + if(!_alpm_depmiss_isin(miss, baddeps)) { + baddeps = alpm_list_add(baddeps, miss); + } else { + FREE(miss); + } + } + } + } + + if(reversedeps) { + /* reversedeps handles the backwards dependencies, ie, + * the packages listed in the requiredby field. */ + + /* we check the upgrade list then the remove list in one loop */ + int upgr = 1; /* we are in the upgrade list */ + i = upgrade; + while(upgr || i) { + if(!i) { /*this is the end of the upgrade list, jump to the remove list*/ + i = remove; + upgr = 0; + continue; + } pmpkg_t *newpkg = i->data; pmpkg_t *oldpkg; alpm_list_t *requiredby; if(newpkg == NULL) { _alpm_log(PM_LOG_DEBUG, "null package found in package list\n"); + i = i->next; continue; } _alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n", @@ -273,7 +320,8 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, if((oldpkg = _alpm_db_get_pkgfromcache(db, alpm_pkg_get_name(newpkg))) == NULL) { _alpm_log(PM_LOG_DEBUG, "cannot find package installed '%s'\n", - alpm_pkg_get_name(newpkg)); + alpm_pkg_get_name(newpkg)); + i = i->next; continue; } @@ -282,8 +330,7 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, pmpkg_t *p; found = 0; - if(_alpm_pkg_find(j->data, packages)) { - /* this package also in the upgrade list, so don't worry about it */ + if(_alpm_pkg_find(j->data, upgrade) || _alpm_pkg_find(j->data, remove)) { continue; } if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) { @@ -292,95 +339,60 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, } for(k = alpm_pkg_get_depends(p); k; k = k->next) { - /* don't break any existing dependencies (possible provides) */ pmdepend_t *depend = k->data; + char *missdepstring = alpm_dep_get_string(depend); - /* if oldpkg satisfied this dep, and newpkg doesn't */ - if(alpm_depcmp(oldpkg, depend) && !alpm_depcmp(newpkg, depend)) { - /* we've found a dep that was removed... see if any other package - * still contains/provides the dep */ - int satisfied = 0; - for(l = packages; l; l = l->next) { - pmpkg_t *pkg = l->data; + if(!alpm_depcmp(oldpkg, depend)) { + continue; + } + /* OK, we don't want to break this depend */ - if(alpm_depcmp(pkg, depend)) { - _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' has moved from '%s' to '%s'\n", - depend->name, - alpm_pkg_get_name(oldpkg), alpm_pkg_get_name(pkg)); - satisfied = 1; - break; - } - } - - if(!satisfied) { - /* worst case... check installed packages to see if anything else - * satisfies this... */ - 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)) { - /* we ignore packages that will be updated because we know - * that the updated ones don't satisfy depend */ - _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n", - depend->name, alpm_pkg_get_name(pkg)); - satisfied = 1; - break; - } - } - } - - if(!satisfied) { - _alpm_log(PM_LOG_DEBUG, "checkdeps: updated '%s' won't satisfy a dependency of '%s'\n", - alpm_pkg_get_name(oldpkg), alpm_pkg_get_name(p)); - miss = _alpm_depmiss_new(p->name, depend->mod, depend->name, depend->version); - if(!_alpm_depmiss_isin(miss, baddeps)) { - baddeps = alpm_list_add(baddeps, miss); - } else { - FREE(miss); - } + /* 1. for efficiency we check newpkg first if we are in the upgrade list */ + if(upgr && alpm_depcmp(newpkg, depend)) { + _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' also satisfied by the upgraded version of '%s'\n", + missdepstring, alpm_pkg_get_name(newpkg)); + free(missdepstring); + continue; + } + /* 2. we check the upgrade targets */ + int satisfied = 0; + for(l = upgrade; l; l = l->next) { + pmpkg_t *pkg = l->data; + if(pkg && alpm_depcmp(pkg, depend)) { + _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by '%s' from the upgrade list\n", + missdepstring, alpm_pkg_get_name(pkg)); + free(missdepstring); + satisfied = 1; + break; } } - } - } - FREELIST(requiredby); - } - } - if(op == PM_TRANS_TYPE_ADD || op == PM_TRANS_TYPE_UPGRADE) { - /* DEPENDENCIES -- look for unsatisfied dependencies */ - for(i = packages; i; i = i->next) { - pmpkg_t *tp = i->data; - if(tp == NULL) { - _alpm_log(PM_LOG_DEBUG, "null package found in package list\n"); - continue; - } - _alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n", - alpm_pkg_get_name(tp), alpm_pkg_get_version(tp)); + if(satisfied) { + continue; + } + /* 3. we check untouched installed packages to see if anything else + * satisfies this... */ + for(l = _alpm_db_get_pkgcache(db); l; l = l->next) { + pmpkg_t *pkg = l->data; - for(j = alpm_pkg_get_depends(tp); j; j = j->next) { - pmdepend_t *depend = j->data; + if(pkg && alpm_depcmp(pkg, depend) + && !_alpm_pkg_find(alpm_pkg_get_name(pkg), upgrade) + && !_alpm_pkg_find(alpm_pkg_get_name(pkg), remove)) { + _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n", + missdepstring, alpm_pkg_get_name(pkg)); + free(missdepstring); + satisfied = 1; + break; + } + } + if(satisfied) { + continue; + } - found = 0; - /* check other targets */ - for(k = packages; k && !found; k = k->next) { - pmpkg_t *p = k->data; - found = alpm_depcmp(p, depend); - } - - /* check database for satisfying packages */ - /* we can ignore packages being updated, they were checked above */ - for(k = _alpm_db_get_pkgcache(db); k && !found; k = k->next) { - pmpkg_t *p = k->data; - found = alpm_depcmp(p, depend) - && !_alpm_pkg_find(alpm_pkg_get_name(p), packages); - } - - /* else if still not found... */ - if(!found) { - char *depstring = alpm_dep_get_string(depend); - _alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n", - depstring, alpm_pkg_get_name(tp)); - free(depstring); - miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod, + /* The transaction would break this depend, record it */ + _alpm_log(PM_LOG_DEBUG, "checkdeps: the transaction would break '%s' dependency of '%s'\n", + missdepstring, alpm_pkg_get_name(p)); + free(missdepstring); + miss = _alpm_depmiss_new(p->name, depend->mod, depend->name, depend->version); if(!_alpm_depmiss_isin(miss, baddeps)) { baddeps = alpm_list_add(baddeps, miss); @@ -389,65 +401,8 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op, } } } - } - } else if(op == PM_TRANS_TYPE_REMOVE) { - /* check requiredby fields */ - for(i = packages; i; i = i->next) { - pmpkg_t *rmpkg = alpm_list_getdata(i); - alpm_list_t *requiredby; - - if(rmpkg == NULL) { - _alpm_log(PM_LOG_DEBUG, "null package found in package list\n"); - continue; - } - - requiredby = alpm_pkg_compute_requiredby(rmpkg); - for(j = requiredby; j; j = j->next) { - pmpkg_t *p; - found = 0; - if(_alpm_pkg_find(j->data, packages)) { - /* package also in the remove list, so don't worry about it */ - continue; - } - - 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 = k->data; - - /* if rmpkg satisfied this dep, try to find an other satisfier - * (which won't be removed)*/ - if(alpm_depcmp(rmpkg, 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)) { - char *depstring = alpm_dep_get_string(depend); - _alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n", - depstring, alpm_pkg_get_name(pkg)); - free(depstring); - satisfied = 1; - break; - } - } - - if(!satisfied) { - _alpm_log(PM_LOG_DEBUG, "checkdeps: found %s which requires %s\n", - alpm_pkg_get_name(p), alpm_pkg_get_name(rmpkg)); - miss = _alpm_depmiss_new(alpm_pkg_get_name(p), - depend->mod, depend->name, depend->version); - if(!_alpm_depmiss_isin(miss, baddeps)) { - baddeps = alpm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } - } - } - } FREELIST(requiredby); + i = alpm_list_next(i); } } @@ -642,10 +597,11 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) /* populates *list with packages that need to be installed to satisfy all * dependencies (recursive) for syncpkg * + * @param remove contains packages elected for removal * make sure **list is already initialized */ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, - alpm_list_t **list, pmtrans_t *trans, alpm_list_t **data) + alpm_list_t **list, alpm_list_t *remove, pmtrans_t *trans, alpm_list_t **data) { alpm_list_t *i, *j, *k; alpm_list_t *targ; @@ -659,7 +615,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, _alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n"); targ = alpm_list_add(NULL, syncpkg); - deps = _alpm_checkdeps(local, PM_TRANS_TYPE_ADD, targ); + deps = alpm_checkdeps(local, 0, remove, targ); alpm_list_free(targ); if(deps == NULL) { @@ -694,7 +650,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, if(!sync) { continue; } - found = alpm_depcmp(sync, missdep); + found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove); if(!found) { continue; } @@ -715,6 +671,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, continue; } found = alpm_depcmp(sync, missdep); + found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove); if(!found) { continue; } @@ -747,7 +704,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg, _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n", alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg)); *list = alpm_list_add(*list, sync); - if(_alpm_resolvedeps(local, dbs_sync, sync, list, trans, data)) { + if(_alpm_resolvedeps(local, dbs_sync, sync, list, remove, trans, data)) { goto error; } } diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index a736f705..e4bba8bf 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -54,11 +54,9 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod, const char *depname, const char *depversion); 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); 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, pmtrans_t *trans, alpm_list_t **data); + alpm_list_t **list, alpm_list_t *remove, pmtrans_t *trans, alpm_list_t **data); #endif /* _ALPM_DEPS_H */ diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index e1f19ec8..349ff10c 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -103,7 +103,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { _alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n"); - lp = _alpm_checkdeps(db, trans->type, trans->packages); + lp = alpm_checkdeps(db, 1, trans->packages, NULL); if(lp != NULL) { if(trans->flags & PM_TRANS_FLAG_CASCADE) { while(lp) { @@ -123,7 +123,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) } } FREELIST(lp); - lp = _alpm_checkdeps(db, trans->type, trans->packages); + lp = alpm_checkdeps(db, 1, trans->packages, NULL); } } else { if(data) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index b49bbfb6..f6fa3185 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -402,7 +402,7 @@ static int syncpkg_cmp(const void *s1, const void *s2) int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data) { alpm_list_t *deps = NULL; - alpm_list_t *list = NULL; /* allow checkdeps usage with trans->packages */ + alpm_list_t *list = NULL, *remove = NULL; /* allow checkdeps usage with trans->packages */ alpm_list_t *i, *j; int ret = 0; @@ -426,10 +426,21 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync /* Resolve targets dependencies */ EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL); _alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n"); + + /* build remove list for resolvedeps */ + for(i = trans->packages; i; i = i->next) { + pmsyncpkg_t *sync = i->data; + if(sync->type == PM_SYNC_TYPE_REPLACE) { + for(j = sync->data; j; j = j->next) { + remove = alpm_list_add(remove, j->data); + } + } + } + for(i = trans->packages; i; i = i->next) { pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg; if(_alpm_resolvedeps(db_local, dbs_sync, spkg, &list, - trans, data) == -1) { + remove, trans, data) == -1) { /* pm_errno is set by resolvedeps */ ret = -1; goto cleanup; @@ -471,19 +482,6 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync trans->packages = newpkgs; EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL); - - _alpm_log(PM_LOG_DEBUG, "looking for unresolvable dependencies\n"); - deps = _alpm_checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list); - if(deps) { - if(data) { - *data = deps; - } else { - FREELIST(deps); - } - pm_errno = PM_ERR_UNSATISFIED_DEPS; - ret = -1; - goto cleanup; - } } /* We don't care about conflicts if we're just printing uris */ @@ -648,72 +646,38 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL); } - alpm_list_free(list); - list = NULL; - - /* XXX: this fails for cases where a requested package wants - * a dependency that conflicts with an older version of - * the package. It will be removed from final, and the user - * has to re-request it to get it installed properly. - * - * Not gonna happen very often, but should be dealt with... - */ - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { - /* Check dependencies of packages in rmtargs and make sure - * we won't be breaking anything by removing them. - * If a broken dep is detected, make sure it's not from a - * package that's in our final (upgrade) list. - */ - /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/ + /* rebuild remove and list */ + alpm_list_free(list); + list = NULL; + for(i = trans->packages; i; i = i->next) { + pmsyncpkg_t *sync = i->data; + list = alpm_list_add(list, sync->pkg); + } + alpm_list_free(remove); + remove = NULL; for(i = trans->packages; i; i = i->next) { pmsyncpkg_t *sync = i->data; if(sync->type == PM_SYNC_TYPE_REPLACE) { for(j = sync->data; j; j = j->next) { - list = alpm_list_add(list, j->data); + remove = alpm_list_add(remove, j->data); } } } - if(list) { - _alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal\n"); - deps = _alpm_checkdeps(db_local, PM_TRANS_TYPE_REMOVE, list); - if(deps) { - /* Check if broken dependencies are fixed by packages we are installing */ - int errorout = 0; - for(i = deps; i; i = i->next) { - pmdepmissing_t *miss = i->data; - alpm_list_t *l; - int satisfied = 0; - for(l = trans->packages; l && !satisfied; l = l->next) { - pmsyncpkg_t *sp = l->data; - pmpkg_t *sppkg = sp->pkg; - if(alpm_depcmp(sppkg, &(miss->depend))) { - char *missdepstring = alpm_dep_get_string(&(miss->depend)); - _alpm_log(PM_LOG_DEBUG, "sync: dependency '%s' satisfied by package '%s'\n", - missdepstring, alpm_pkg_get_name(sppkg)); - free(missdepstring); - satisfied = 1; - } - } - if(!satisfied) { - errorout++; - *data = alpm_list_add(*data, miss); - } - } - if(errorout) { - pm_errno = PM_ERR_UNSATISFIED_DEPS; - ret = -1; - goto cleanup; - } - FREELIST(deps); - } + _alpm_log(PM_LOG_DEBUG, "checking dependencies\n"); + deps = alpm_checkdeps(db_local, 1, remove, list); + if(deps) { + pm_errno = PM_ERR_UNSATISFIED_DEPS; + ret = -1; + FREELIST(deps); + goto cleanup; } - /*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/ } cleanup: alpm_list_free(list); + alpm_list_free(remove); return(ret); } diff --git a/pactest/tests/sync990.py b/pactest/tests/sync990.py index ee6a590b..6ac5a1f6 100644 --- a/pactest/tests/sync990.py +++ b/pactest/tests/sync990.py @@ -7,14 +7,13 @@ sp2 = pmpkg("pkg2") sp3 = pmpkg("pkg3") sp3.conflicts = ["pkg2"] -sp3.provides = ["pkg2"] for p in sp1, sp2, sp3: self.addpkg2db("sync", p) self.args = "-S %s" % " ".join([p.name for p in sp1, sp2]) -self.addrule("PACMAN_RETCODE=0") -self.addrule("PKG_EXIST=pkg1") -self.addrule("PKG_EXIST=pkg2") +self.addrule("PACMAN_RETCODE=1") +self.addrule("!PKG_EXIST=pkg1") +self.addrule("!PKG_EXIST=pkg2") self.addrule("!PKG_EXIST=pkg3") diff --git a/src/util/testdb.c b/src/util/testdb.c index ca10dd9f..31b4ff0d 100644 --- a/src/util/testdb.c +++ b/src/util/testdb.c @@ -140,7 +140,7 @@ int main(int argc, char **argv) /* check dependencies */ alpm_list_t *data; - data = alpm_checkdeps(db, PM_TRANS_TYPE_ADD, alpm_db_getpkgcache(db)); + data = alpm_checkdeps(db, 0, alpm_db_getpkgcache(db), NULL); for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); pmdepend_t *dep = alpm_miss_get_dep(miss);