mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 00:08:50 -05:00
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 <shiningxc@gmail.com> [Dan: some variable renaming, clarification in commit message] Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
1e9a1a0292
commit
7d37d9278d
@ -140,7 +140,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
|
|||||||
|
|
||||||
/* look for unsatisfied dependencies */
|
/* look for unsatisfied dependencies */
|
||||||
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
|
_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(lp != NULL) {
|
||||||
if(data) {
|
if(data) {
|
||||||
*data = lp;
|
*data = lp;
|
||||||
|
@ -370,8 +370,8 @@ typedef enum _pmdepmod_t {
|
|||||||
|
|
||||||
pmdepend_t *alpm_splitdep(const char *depstring);
|
pmdepend_t *alpm_splitdep(const char *depstring);
|
||||||
int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
|
int alpm_depcmp(pmpkg_t *pkg, pmdepend_t *dep);
|
||||||
alpm_list_t *alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
alpm_list_t *alpm_checkdeps(pmdb_t *db, int reversedeps,
|
||||||
alpm_list_t *packages);
|
alpm_list_t *remove, alpm_list_t *upgrade);
|
||||||
|
|
||||||
const char *alpm_miss_get_target(const pmdepmissing_t *miss);
|
const char *alpm_miss_get_target(const pmdepmissing_t *miss);
|
||||||
pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);
|
pmdepend_t *alpm_miss_get_dep(pmdepmissing_t *miss);
|
||||||
|
@ -121,7 +121,7 @@ static alpm_list_t *_alpm_graph_init(alpm_list_t *targets)
|
|||||||
for(i = vertices; i; i = i->next) {
|
for(i = vertices; i; i = i->next) {
|
||||||
pmgraph_t *vertex_i = i->data;
|
pmgraph_t *vertex_i = i->data;
|
||||||
pmpkg_t *p_i = vertex_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) {
|
for(j = vertices; j; j = j->next) {
|
||||||
pmgraph_t *vertex_j = j->data;
|
pmgraph_t *vertex_j = j->data;
|
||||||
pmpkg_t *p_j = vertex_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.
|
/** Checks dependencies and returns missing ones in a list.
|
||||||
* Dependencies can include versions with depmod operators.
|
* Dependencies can include versions with depmod operators.
|
||||||
* @param db pointer to the local package database
|
* @param db pointer to the local package database
|
||||||
* @param op transaction type
|
* @param reversedeps handles the backward dependencies
|
||||||
* @param packages an alpm_list_t* of packages to be checked
|
* @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.
|
* @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 SYMEXPORT *alpm_checkdeps(pmdb_t *db, int reversedeps,
|
||||||
alpm_list_t *packages)
|
alpm_list_t *remove, alpm_list_t *upgrade)
|
||||||
{
|
|
||||||
return(_alpm_checkdeps(db, op, packages));
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|
||||||
alpm_list_t *packages)
|
|
||||||
{
|
{
|
||||||
alpm_list_t *i, *j, *k, *l;
|
alpm_list_t *i, *j, *k, *l;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
@ -256,130 +251,38 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(op == PM_TRANS_TYPE_UPGRADE) {
|
/* look for unsatisfied dependencies of the upgrade list */
|
||||||
/* PM_TRANS_TYPE_UPGRADE handles the backwards dependencies, ie,
|
for(i = upgrade; i; i = i->next) {
|
||||||
* the packages listed in the requiredby field.
|
|
||||||
*/
|
|
||||||
for(i = packages; i; i = i->next) {
|
|
||||||
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");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
|
|
||||||
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
|
||||||
|
|
||||||
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));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
requiredby = alpm_pkg_compute_requiredby(oldpkg);
|
|
||||||
for(j = requiredby; j; j = j->next) {
|
|
||||||
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 */
|
|
||||||
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) {
|
|
||||||
/* don't break any existing dependencies (possible provides) */
|
|
||||||
pmdepend_t *depend = k->data;
|
|
||||||
|
|
||||||
/* 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(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
pmpkg_t *tp = i->data;
|
||||||
if(tp == NULL) {
|
if(tp == NULL) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "null package found in package list\n");
|
_alpm_log(PM_LOG_DEBUG, "null package found in upgrade list\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
|
||||||
alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));
|
alpm_pkg_get_name(tp), alpm_pkg_get_version(tp));
|
||||||
|
|
||||||
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
|
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
|
||||||
|
/* split into name/version pairs */
|
||||||
pmdepend_t *depend = j->data;
|
pmdepend_t *depend = j->data;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
/* check other targets */
|
/* 1. we check the upgrade list */
|
||||||
for(k = packages; k && !found; k = k->next) {
|
for(k = upgrade; k && !found; k = k->next) {
|
||||||
pmpkg_t *p = k->data;
|
pmpkg_t *p = k->data;
|
||||||
found = alpm_depcmp(p, depend);
|
found = p && alpm_depcmp(p, depend);
|
||||||
}
|
}
|
||||||
|
/* 2. we check database for untouched satisfying packages */
|
||||||
/* 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) {
|
for(k = _alpm_db_get_pkgcache(db); k && !found; k = k->next) {
|
||||||
pmpkg_t *p = k->data;
|
pmpkg_t *p = k->data;
|
||||||
found = alpm_depcmp(p, depend)
|
found = p && alpm_depcmp(p, depend)
|
||||||
&& !_alpm_pkg_find(alpm_pkg_get_name(p), packages);
|
&& !_alpm_pkg_find(alpm_pkg_get_name(p), upgrade)
|
||||||
|
&& !_alpm_pkg_find(alpm_pkg_get_name(p), remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* else if still not found... */
|
/* else if still not found... */
|
||||||
if(!found) {
|
if(!found) {
|
||||||
char *depstring = alpm_dep_get_string(depend);
|
char *missdepstring = alpm_dep_get_string(depend);
|
||||||
_alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n",
|
_alpm_log(PM_LOG_DEBUG, "missing dependency '%s' for package '%s'\n",
|
||||||
depstring, alpm_pkg_get_name(tp));
|
missdepstring, alpm_pkg_get_name(tp));
|
||||||
free(depstring);
|
free(missdepstring);
|
||||||
miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod,
|
miss = _alpm_depmiss_new(alpm_pkg_get_name(tp), depend->mod,
|
||||||
depend->name, depend->version);
|
depend->name, depend->version);
|
||||||
if(!_alpm_depmiss_isin(miss, baddeps)) {
|
if(!_alpm_depmiss_isin(miss, baddeps)) {
|
||||||
@ -390,54 +293,107 @@ 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) {
|
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");
|
_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",
|
||||||
|
alpm_pkg_get_name(newpkg), alpm_pkg_get_version(newpkg));
|
||||||
|
|
||||||
|
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));
|
||||||
|
i = i->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
requiredby = alpm_pkg_compute_requiredby(rmpkg);
|
requiredby = alpm_pkg_compute_requiredby(oldpkg);
|
||||||
for(j = requiredby; j; j = j->next) {
|
for(j = requiredby; j; j = j->next) {
|
||||||
pmpkg_t *p;
|
pmpkg_t *p;
|
||||||
found = 0;
|
found = 0;
|
||||||
if(_alpm_pkg_find(j->data, packages)) {
|
|
||||||
/* package also in the remove 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) {
|
||||||
|
/* hmmm... package isn't installed.. */
|
||||||
continue;
|
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) {
|
for(k = alpm_pkg_get_depends(p); k; k = k->next) {
|
||||||
pmdepend_t *depend = k->data;
|
pmdepend_t *depend = k->data;
|
||||||
|
char *missdepstring = alpm_dep_get_string(depend);
|
||||||
|
|
||||||
/* if rmpkg satisfied this dep, try to find an other satisfier
|
if(!alpm_depcmp(oldpkg, depend)) {
|
||||||
* (which won't be removed)*/
|
continue;
|
||||||
if(alpm_depcmp(rmpkg, depend)) {
|
}
|
||||||
|
/* OK, we don't want to break this depend */
|
||||||
|
|
||||||
|
/* 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;
|
int satisfied = 0;
|
||||||
for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
|
for(l = upgrade; l; l = l->next) {
|
||||||
pmpkg_t *pkg = l->data;
|
pmpkg_t *pkg = l->data;
|
||||||
if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) {
|
if(pkg && alpm_depcmp(pkg, depend)) {
|
||||||
char *depstring = alpm_dep_get_string(depend);
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by '%s' from the upgrade list\n",
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n",
|
missdepstring, alpm_pkg_get_name(pkg));
|
||||||
depstring, alpm_pkg_get_name(pkg));
|
free(missdepstring);
|
||||||
free(depstring);
|
|
||||||
satisfied = 1;
|
satisfied = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
if(!satisfied) {
|
if(pkg && alpm_depcmp(pkg, depend)
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: found %s which requires %s\n",
|
&& !_alpm_pkg_find(alpm_pkg_get_name(pkg), upgrade)
|
||||||
alpm_pkg_get_name(p), alpm_pkg_get_name(rmpkg));
|
&& !_alpm_pkg_find(alpm_pkg_get_name(pkg), remove)) {
|
||||||
miss = _alpm_depmiss_new(alpm_pkg_get_name(p),
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by installed package '%s'\n",
|
||||||
depend->mod, depend->name, depend->version);
|
missdepstring, alpm_pkg_get_name(pkg));
|
||||||
|
free(missdepstring);
|
||||||
|
satisfied = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(satisfied) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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)) {
|
if(!_alpm_depmiss_isin(miss, baddeps)) {
|
||||||
baddeps = alpm_list_add(baddeps, miss);
|
baddeps = alpm_list_add(baddeps, miss);
|
||||||
} else {
|
} else {
|
||||||
@ -445,9 +401,8 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
FREELIST(requiredby);
|
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
|
/* populates *list with packages that need to be installed to satisfy all
|
||||||
* dependencies (recursive) for syncpkg
|
* dependencies (recursive) for syncpkg
|
||||||
*
|
*
|
||||||
|
* @param remove contains packages elected for removal
|
||||||
* make sure **list is already initialized
|
* make sure **list is already initialized
|
||||||
*/
|
*/
|
||||||
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
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 *i, *j, *k;
|
||||||
alpm_list_t *targ;
|
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");
|
_alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n");
|
||||||
targ = alpm_list_add(NULL, syncpkg);
|
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);
|
alpm_list_free(targ);
|
||||||
|
|
||||||
if(deps == NULL) {
|
if(deps == NULL) {
|
||||||
@ -694,7 +650,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
|||||||
if(!sync) {
|
if(!sync) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
found = alpm_depcmp(sync, missdep);
|
found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove);
|
||||||
if(!found) {
|
if(!found) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -715,6 +671,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
found = alpm_depcmp(sync, missdep);
|
found = alpm_depcmp(sync, missdep);
|
||||||
|
found = alpm_depcmp(sync, missdep) && !_alpm_pkg_find(alpm_pkg_get_name(sync), remove);
|
||||||
if(!found) {
|
if(!found) {
|
||||||
continue;
|
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_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
|
||||||
alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg));
|
alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg));
|
||||||
*list = alpm_list_add(*list, sync);
|
*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;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,9 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepmod_t depmod,
|
|||||||
const char *depname, const char *depversion);
|
const char *depname, const char *depversion);
|
||||||
int _alpm_depmiss_isin(pmdepmissing_t *needle, alpm_list_t *haystack);
|
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_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);
|
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,
|
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 */
|
#endif /* _ALPM_DEPS_H */
|
||||||
|
|
||||||
|
@ -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)) {
|
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "looking for unsatisfied dependencies\n");
|
_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(lp != NULL) {
|
||||||
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
|
if(trans->flags & PM_TRANS_FLAG_CASCADE) {
|
||||||
while(lp) {
|
while(lp) {
|
||||||
@ -123,7 +123,7 @@ int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FREELIST(lp);
|
FREELIST(lp);
|
||||||
lp = _alpm_checkdeps(db, trans->type, trans->packages);
|
lp = alpm_checkdeps(db, 1, trans->packages, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(data) {
|
if(data) {
|
||||||
|
@ -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)
|
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 *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;
|
alpm_list_t *i, *j;
|
||||||
int ret = 0;
|
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 */
|
/* Resolve targets dependencies */
|
||||||
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
|
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
|
||||||
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
|
_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) {
|
for(i = trans->packages; i; i = i->next) {
|
||||||
pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg;
|
pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg;
|
||||||
if(_alpm_resolvedeps(db_local, dbs_sync, spkg, &list,
|
if(_alpm_resolvedeps(db_local, dbs_sync, spkg, &list,
|
||||||
trans, data) == -1) {
|
remove, trans, data) == -1) {
|
||||||
/* pm_errno is set by resolvedeps */
|
/* pm_errno is set by resolvedeps */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
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;
|
trans->packages = newpkgs;
|
||||||
|
|
||||||
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
|
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 */
|
/* 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);
|
EVENT(trans, PM_TRANS_EVT_INTERCONFLICTS_DONE, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
|
||||||
|
/* rebuild remove and list */
|
||||||
alpm_list_free(list);
|
alpm_list_free(list);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
|
for(i = trans->packages; i; i = i->next) {
|
||||||
/* XXX: this fails for cases where a requested package wants
|
pmsyncpkg_t *sync = i->data;
|
||||||
* a dependency that conflicts with an older version of
|
list = alpm_list_add(list, sync->pkg);
|
||||||
* the package. It will be removed from final, and the user
|
}
|
||||||
* has to re-request it to get it installed properly.
|
alpm_list_free(remove);
|
||||||
*
|
remove = NULL;
|
||||||
* 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);*/
|
|
||||||
for(i = trans->packages; i; i = i->next) {
|
for(i = trans->packages; i; i = i->next) {
|
||||||
pmsyncpkg_t *sync = i->data;
|
pmsyncpkg_t *sync = i->data;
|
||||||
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
||||||
for(j = sync->data; j; j = j->next) {
|
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;
|
_alpm_log(PM_LOG_DEBUG, "checking dependencies\n");
|
||||||
int satisfied = 0;
|
deps = alpm_checkdeps(db_local, 1, remove, list);
|
||||||
for(l = trans->packages; l && !satisfied; l = l->next) {
|
if(deps) {
|
||||||
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;
|
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
FREELIST(deps);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
FREELIST(deps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
alpm_list_free(list);
|
alpm_list_free(list);
|
||||||
|
alpm_list_free(remove);
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,13 @@ sp2 = pmpkg("pkg2")
|
|||||||
|
|
||||||
sp3 = pmpkg("pkg3")
|
sp3 = pmpkg("pkg3")
|
||||||
sp3.conflicts = ["pkg2"]
|
sp3.conflicts = ["pkg2"]
|
||||||
sp3.provides = ["pkg2"]
|
|
||||||
|
|
||||||
for p in sp1, sp2, sp3:
|
for p in sp1, sp2, sp3:
|
||||||
self.addpkg2db("sync", p)
|
self.addpkg2db("sync", p)
|
||||||
|
|
||||||
self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
|
self.args = "-S %s" % " ".join([p.name for p in sp1, sp2])
|
||||||
|
|
||||||
self.addrule("PACMAN_RETCODE=0")
|
self.addrule("PACMAN_RETCODE=1")
|
||||||
self.addrule("PKG_EXIST=pkg1")
|
self.addrule("!PKG_EXIST=pkg1")
|
||||||
self.addrule("PKG_EXIST=pkg2")
|
self.addrule("!PKG_EXIST=pkg2")
|
||||||
self.addrule("!PKG_EXIST=pkg3")
|
self.addrule("!PKG_EXIST=pkg3")
|
||||||
|
@ -140,7 +140,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* check dependencies */
|
/* check dependencies */
|
||||||
alpm_list_t *data;
|
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)) {
|
for(i = data; i; i = alpm_list_next(i)) {
|
||||||
pmdepmissing_t *miss = alpm_list_getdata(i);
|
pmdepmissing_t *miss = alpm_list_getdata(i);
|
||||||
pmdepend_t *dep = alpm_miss_get_dep(miss);
|
pmdepend_t *dep = alpm_miss_get_dep(miss);
|
||||||
|
Loading…
Reference in New Issue
Block a user