mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-22 15:58: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,16 +251,68 @@ 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.
|
pmpkg_t *tp = i->data;
|
||||||
*/
|
if(tp == NULL) {
|
||||||
for(i = packages; i; i = i->next) {
|
_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 *newpkg = i->data;
|
||||||
pmpkg_t *oldpkg;
|
pmpkg_t *oldpkg;
|
||||||
alpm_list_t *requiredby;
|
alpm_list_t *requiredby;
|
||||||
if(newpkg == NULL) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: package %s-%s\n",
|
_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) {
|
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_log(PM_LOG_DEBUG, "cannot find package installed '%s'\n",
|
||||||
alpm_pkg_get_name(newpkg));
|
alpm_pkg_get_name(newpkg));
|
||||||
|
i = i->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,8 +330,7 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
pmpkg_t *p;
|
pmpkg_t *p;
|
||||||
found = 0;
|
found = 0;
|
||||||
|
|
||||||
if(_alpm_pkg_find(j->data, packages)) {
|
if(_alpm_pkg_find(j->data, upgrade) || _alpm_pkg_find(j->data, remove)) {
|
||||||
/* this package also in the upgrade list, so don't worry about it */
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) {
|
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) {
|
for(k = alpm_pkg_get_depends(p); k; k = k->next) {
|
||||||
/* don't break any existing dependencies (possible provides) */
|
|
||||||
pmdepend_t *depend = k->data;
|
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)) {
|
||||||
if(alpm_depcmp(oldpkg, depend) && !alpm_depcmp(newpkg, depend)) {
|
continue;
|
||||||
/* we've found a dep that was removed... see if any other package
|
}
|
||||||
* still contains/provides the dep */
|
/* OK, we don't want to break this depend */
|
||||||
int satisfied = 0;
|
|
||||||
for(l = packages; l; l = l->next) {
|
|
||||||
pmpkg_t *pkg = l->data;
|
|
||||||
|
|
||||||
if(alpm_depcmp(pkg, depend)) {
|
/* 1. for efficiency we check newpkg first if we are in the upgrade list */
|
||||||
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' has moved from '%s' to '%s'\n",
|
if(upgr && alpm_depcmp(newpkg, depend)) {
|
||||||
depend->name,
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' also satisfied by the upgraded version of '%s'\n",
|
||||||
alpm_pkg_get_name(oldpkg), alpm_pkg_get_name(pkg));
|
missdepstring, alpm_pkg_get_name(newpkg));
|
||||||
satisfied = 1;
|
free(missdepstring);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
/* 2. we check the upgrade targets */
|
||||||
|
int satisfied = 0;
|
||||||
if(!satisfied) {
|
for(l = upgrade; l; l = l->next) {
|
||||||
/* worst case... check installed packages to see if anything else
|
pmpkg_t *pkg = l->data;
|
||||||
* satisfies this... */
|
if(pkg && alpm_depcmp(pkg, depend)) {
|
||||||
for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: dependency '%s' satisfied by '%s' from the upgrade list\n",
|
||||||
pmpkg_t *pkg = l->data;
|
missdepstring, alpm_pkg_get_name(pkg));
|
||||||
|
free(missdepstring);
|
||||||
if(alpm_depcmp(pkg, depend) && !_alpm_pkg_find(alpm_pkg_get_name(pkg), packages)) {
|
satisfied = 1;
|
||||||
/* we ignore packages that will be updated because we know
|
break;
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if(satisfied) {
|
||||||
}
|
continue;
|
||||||
FREELIST(requiredby);
|
}
|
||||||
}
|
/* 3. we check untouched installed packages to see if anything else
|
||||||
}
|
* satisfies this... */
|
||||||
if(op == PM_TRANS_TYPE_ADD || op == PM_TRANS_TYPE_UPGRADE) {
|
for(l = _alpm_db_get_pkgcache(db); l; l = l->next) {
|
||||||
/* DEPENDENCIES -- look for unsatisfied dependencies */
|
pmpkg_t *pkg = l->data;
|
||||||
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));
|
|
||||||
|
|
||||||
for(j = alpm_pkg_get_depends(tp); j; j = j->next) {
|
if(pkg && alpm_depcmp(pkg, depend)
|
||||||
pmdepend_t *depend = j->data;
|
&& !_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;
|
/* The transaction would break this depend, record it */
|
||||||
/* check other targets */
|
_alpm_log(PM_LOG_DEBUG, "checkdeps: the transaction would break '%s' dependency of '%s'\n",
|
||||||
for(k = packages; k && !found; k = k->next) {
|
missdepstring, alpm_pkg_get_name(p));
|
||||||
pmpkg_t *p = k->data;
|
free(missdepstring);
|
||||||
found = alpm_depcmp(p, depend);
|
miss = _alpm_depmiss_new(p->name, depend->mod,
|
||||||
}
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
depend->name, depend->version);
|
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);
|
||||||
@ -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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)) {
|
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
|
||||||
/* Check dependencies of packages in rmtargs and make sure
|
/* rebuild remove and list */
|
||||||
* we won't be breaking anything by removing them.
|
alpm_list_free(list);
|
||||||
* If a broken dep is detected, make sure it's not from a
|
list = NULL;
|
||||||
* package that's in our final (upgrade) list.
|
for(i = trans->packages; i; i = i->next) {
|
||||||
*/
|
pmsyncpkg_t *sync = i->data;
|
||||||
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
|
list = alpm_list_add(list, sync->pkg);
|
||||||
|
}
|
||||||
|
alpm_list_free(remove);
|
||||||
|
remove = 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;
|
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
||||||
pmpkg_t *sppkg = sp->pkg;
|
ret = -1;
|
||||||
if(alpm_depcmp(sppkg, &(miss->depend))) {
|
FREELIST(deps);
|
||||||
char *missdepstring = alpm_dep_get_string(&(miss->depend));
|
goto cleanup;
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*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