Attempt to clean up _alpm_sync_prepare
This function is an absolute disaster, so we'll take it one step at a time here. This was a quick once-over of the whole thing, trying to straighten out some of the spaghetti code and fix some mistakes that others found. We are now down to two failing pactests again: sync300 and upgrade051. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
544bcbe664
commit
dde7b6f87a
1 changed files with 56 additions and 64 deletions
|
@ -380,10 +380,9 @@ 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; /* list allowing checkdeps usage with data from trans->packages */
|
alpm_list_t *list = NULL; /* allow checkdeps usage with trans->packages */
|
||||||
alpm_list_t *trail = NULL; /* breadcrumb list to avoid running into circles */
|
alpm_list_t *trail = NULL; /* breadcrumb list to avoid running in circles */
|
||||||
alpm_list_t *asked = NULL;
|
alpm_list_t *i, *j;
|
||||||
alpm_list_t *i, *j, *k, *l;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
@ -406,7 +405,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
_alpm_log(PM_LOG_DEBUG, _("resolving target's dependencies"));
|
_alpm_log(PM_LOG_DEBUG, _("resolving target's dependencies"));
|
||||||
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, trail, trans, data) == -1) {
|
if(_alpm_resolvedeps(db_local, dbs_sync, spkg, list,
|
||||||
|
trail, trans, data) == -1) {
|
||||||
/* pm_errno is set by resolvedeps */
|
/* pm_errno is set by resolvedeps */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -430,13 +430,11 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
|
if((trans->flags & PM_TRANS_FLAG_DEPENDSONLY)) {
|
||||||
void *vpkg;
|
void *vpkg;
|
||||||
pmsyncpkg_t *sync;
|
pmsyncpkg_t *sync;
|
||||||
const char *pkgname;
|
|
||||||
|
|
||||||
pkgname = alpm_pkg_get_name(spkg);
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "removing package %s-%s from the transaction targets",
|
_alpm_log(PM_LOG_DEBUG, "removing package %s-%s from the transaction targets",
|
||||||
pkgname, alpm_pkg_get_version(spkg));
|
alpm_pkg_get_name(spkg), alpm_pkg_get_version(spkg));
|
||||||
|
|
||||||
sync = _alpm_sync_find(trans->packages, pkgname);
|
sync = _alpm_sync_find(trans->packages, alpm_pkg_get_name(spkg));
|
||||||
trans->packages = alpm_list_remove(trans->packages, sync, syncpkg_cmp, &vpkg);
|
trans->packages = alpm_list_remove(trans->packages, sync, syncpkg_cmp, &vpkg);
|
||||||
_alpm_sync_free(vpkg);
|
_alpm_sync_free(vpkg);
|
||||||
}
|
}
|
||||||
|
@ -444,23 +442,24 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-order w.r.t. dependencies */
|
/* re-order w.r.t. dependencies */
|
||||||
k = l = NULL;
|
alpm_list_t *sortlist = NULL;
|
||||||
|
alpm_list_t *newpkgs = NULL;
|
||||||
for(i = trans->packages; i; i = i->next) {
|
for(i = trans->packages; i; i = i->next) {
|
||||||
pmsyncpkg_t *s = (pmsyncpkg_t*)i->data;
|
pmsyncpkg_t *s = i->data;
|
||||||
k = alpm_list_add(k, s->pkg);
|
sortlist = alpm_list_add(sortlist, s->pkg);
|
||||||
}
|
}
|
||||||
k = _alpm_sortbydeps(k, PM_TRANS_TYPE_ADD);
|
sortlist = _alpm_sortbydeps(sortlist, PM_TRANS_TYPE_ADD);
|
||||||
for(i=k; i; i=i->next) {
|
for(i = sortlist; i; i = i->next) {
|
||||||
for(j = trans->packages; j; j = j->next) {
|
for(j = trans->packages; j; j = j->next) {
|
||||||
pmsyncpkg_t *s = (pmsyncpkg_t*)j->data;
|
pmsyncpkg_t *s = j->data;
|
||||||
if(s->pkg == i->data) {
|
if(s->pkg == i->data) {
|
||||||
l = alpm_list_add(l, s);
|
newpkgs = alpm_list_add(newpkgs, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alpm_list_free(k);
|
alpm_list_free(sortlist);
|
||||||
alpm_list_free(trans->packages);
|
alpm_list_free(trans->packages);
|
||||||
trans->packages = l;
|
trans->packages = newpkgs;
|
||||||
|
|
||||||
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
|
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_DONE, NULL, NULL);
|
||||||
|
|
||||||
|
@ -488,30 +487,26 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
deps = _alpm_checkconflicts(db_local, list);
|
deps = _alpm_checkconflicts(db_local, list);
|
||||||
if(deps) {
|
if(deps) {
|
||||||
int errorout = 0;
|
int errorout = 0;
|
||||||
|
alpm_list_t *asked = NULL;
|
||||||
|
|
||||||
for(i = deps; i && !errorout; i = i->next) {
|
for(i = deps; i && !errorout; i = i->next) {
|
||||||
pmdepmissing_t *miss = i->data;
|
pmdepmissing_t *miss = i->data;
|
||||||
int found = 0;
|
|
||||||
pmsyncpkg_t *sync;
|
pmsyncpkg_t *sync;
|
||||||
pmpkg_t *local;
|
pmpkg_t *found = NULL;
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, _("package '%s' conflicts with '%s'"),
|
_alpm_log(PM_LOG_DEBUG, _("package '%s' conflicts with '%s'"),
|
||||||
miss->target, miss->depend.name);
|
miss->target, miss->depend.name);
|
||||||
|
/* check if the conflicting package is about to be removed/replaced.
|
||||||
/* check if the conflicting package is one that's about to be removed/replaced.
|
* if so, then just ignore it. */
|
||||||
* if so, then just ignore it
|
|
||||||
*/
|
|
||||||
for(j = trans->packages; j && !found; j = j->next) {
|
for(j = trans->packages; j && !found; j = j->next) {
|
||||||
sync = j->data;
|
sync = j->data;
|
||||||
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
if(sync->type == PM_SYNC_TYPE_REPLACE) {
|
||||||
if(_alpm_pkg_find(miss->depend.name, sync->data)) {
|
found = _alpm_pkg_find(miss->depend.name, sync->data);
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(found) {
|
if(found) {
|
||||||
_alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"),
|
_alpm_log(PM_LOG_DEBUG, _("'%s' is already elected for removal -- skipping"),
|
||||||
miss->depend.name);
|
alpm_pkg_get_name(found));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,18 +516,15 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
miss->target);
|
miss->target);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
local = _alpm_db_get_pkgfromcache(db_local, miss->depend.name);
|
pmpkg_t *local = _alpm_db_get_pkgfromcache(db_local, miss->depend.name);
|
||||||
/* check if this package also "provides" the package it's conflicting with
|
/* check if this package provides the package it's conflicting with */
|
||||||
*/
|
if(alpm_list_find_str(alpm_pkg_get_provides(sync->pkg),
|
||||||
if(alpm_list_find_str(alpm_pkg_get_provides(sync->pkg), miss->depend.name)) {
|
miss->depend.name)) {
|
||||||
/* so just treat it like a "replaces" item so the REQUIREDBY
|
/* treat like a replaces item so requiredby fields are
|
||||||
* fields are inherited properly.
|
* inherited properly. */
|
||||||
*/
|
_alpm_log(PM_LOG_DEBUG, _("package '%s' provides its own conflict"),
|
||||||
_alpm_log(PM_LOG_DEBUG, _("package '%s' provides its own conflict"), miss->target);
|
miss->target);
|
||||||
if(local) {
|
if(!local) {
|
||||||
/* nothing to do for now: it will be handled later
|
|
||||||
* (not the same behavior as in pacman 2.x) */
|
|
||||||
} else {
|
|
||||||
char *rmpkg = NULL;
|
char *rmpkg = NULL;
|
||||||
int target, depend;
|
int target, depend;
|
||||||
/* hmmm, depend.name isn't installed, so it must be conflicting
|
/* hmmm, depend.name isn't installed, so it must be conflicting
|
||||||
|
@ -546,8 +538,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
* opting for xfree86 instead.
|
* opting for xfree86 instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* figure out which one was requested in targets. If they both were,
|
/* figure out which one was requested in targets. If they both
|
||||||
* then it's still an unresolvable conflict. */
|
* were, then it's still an unresolvable conflict. */
|
||||||
target = alpm_list_find_str(trans->targets, miss->target);
|
target = alpm_list_find_str(trans->targets, miss->target);
|
||||||
depend = alpm_list_find_str(trans->targets, miss->depend.name);
|
depend = alpm_list_find_str(trans->targets, miss->depend.name);
|
||||||
if(depend && !target) {
|
if(depend && !target) {
|
||||||
|
@ -568,31 +560,26 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
if(rmpkg) {
|
if(rmpkg) {
|
||||||
pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, rmpkg);
|
pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, rmpkg);
|
||||||
void *vpkg;
|
void *vpkg;
|
||||||
_alpm_log(PM_LOG_DEBUG, _("removing '%s' from target list"), rsync->pkg->name);
|
_alpm_log(PM_LOG_DEBUG, _("removing '%s' from target list"),
|
||||||
trans->packages = alpm_list_remove(trans->packages, rsync, syncpkg_cmp, &vpkg);
|
rsync->pkg->name);
|
||||||
|
trans->packages = alpm_list_remove(trans->packages, rsync,
|
||||||
|
syncpkg_cmp, &vpkg);
|
||||||
_alpm_sync_free(vpkg);
|
_alpm_sync_free(vpkg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* It's a conflict -- see if they want to remove it
|
/* It's a conflict -- see if they want to remove it */
|
||||||
*/
|
_alpm_log(PM_LOG_DEBUG, _("resolving package '%s' conflict"),
|
||||||
_alpm_log(PM_LOG_DEBUG, _("resolving package '%s' conflict"), miss->target);
|
miss->target);
|
||||||
if(local) {
|
if(local) {
|
||||||
int doremove = 0;
|
int doremove = 0;
|
||||||
if(!alpm_list_find_str(asked, miss->depend.name)) {
|
if(!alpm_list_find_str(asked, miss->depend.name)) {
|
||||||
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
|
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target,
|
||||||
|
miss->depend.name, NULL, &doremove);
|
||||||
asked = alpm_list_add(asked, strdup(miss->depend.name));
|
asked = alpm_list_add(asked, strdup(miss->depend.name));
|
||||||
if(doremove) {
|
if(doremove) {
|
||||||
pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages, miss->depend.name);
|
pmpkg_t *q = _alpm_pkg_dup(local);
|
||||||
pmpkg_t *q = _alpm_pkg_new(miss->depend.name, NULL);
|
|
||||||
if(q == NULL) {
|
|
||||||
if(data) {
|
|
||||||
FREELIST(*data);
|
|
||||||
}
|
|
||||||
ret = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
q->requiredby = alpm_list_strdup(alpm_pkg_get_requiredby(local));
|
q->requiredby = alpm_list_strdup(alpm_pkg_get_requiredby(local));
|
||||||
if(sync->type != PM_SYNC_TYPE_REPLACE) {
|
if(sync->type != PM_SYNC_TYPE_REPLACE) {
|
||||||
/* switch this sync type to REPLACE */
|
/* switch this sync type to REPLACE */
|
||||||
|
@ -601,13 +588,19 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
sync->data = NULL;
|
sync->data = NULL;
|
||||||
}
|
}
|
||||||
/* append to the replaces list */
|
/* append to the replaces list */
|
||||||
_alpm_log(PM_LOG_DEBUG, _("electing '%s' for removal"), miss->depend.name);
|
_alpm_log(PM_LOG_DEBUG, _("electing '%s' for removal"),
|
||||||
|
miss->depend.name);
|
||||||
sync->data = alpm_list_add(sync->data, q);
|
sync->data = alpm_list_add(sync->data, q);
|
||||||
|
/* see if the package is in the current target list */
|
||||||
|
pmsyncpkg_t *rsync = _alpm_sync_find(trans->packages,
|
||||||
|
miss->depend.name);
|
||||||
if(rsync) {
|
if(rsync) {
|
||||||
/* remove it from the target list */
|
/* remove it from the target list */
|
||||||
void *vpkg;
|
void *vpkg;
|
||||||
_alpm_log(PM_LOG_DEBUG, _("removing '%s' from target list"), miss->depend.name);
|
_alpm_log(PM_LOG_DEBUG, _("removing '%s' from target list"),
|
||||||
trans->packages = alpm_list_remove(trans->packages, rsync, syncpkg_cmp, &vpkg);
|
miss->depend.name);
|
||||||
|
trans->packages = alpm_list_remove(trans->packages, rsync,
|
||||||
|
syncpkg_cmp, &vpkg);
|
||||||
_alpm_sync_free(vpkg);
|
_alpm_sync_free(vpkg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -719,7 +712,6 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
||||||
cleanup:
|
cleanup:
|
||||||
alpm_list_free(list);
|
alpm_list_free(list);
|
||||||
alpm_list_free(trail);
|
alpm_list_free(trail);
|
||||||
FREELIST(asked);
|
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue