- fix for sync conflicts (patch from VMiklos <vmiklos@frugalware.org>)

- sync code cleanup
- added the deps check for targets to be removed in sync_prepare()
This commit is contained in:
Aurelien Foret 2006-01-05 20:53:41 +00:00
parent a6923f9aae
commit 7858f4c9b4
1 changed files with 48 additions and 48 deletions

View File

@ -338,10 +338,10 @@ static int ptr_cmp(const void *s1, const void *s2)
int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **data)
{
PMList *deps = NULL;
PMList *list = NULL;
PMList *trail = NULL;
PMList *list = NULL; /* list allowing checkdeps usage with data from trans->packages */
PMList *trail = NULL; /* breadcrum list to avoid running into circles */
PMList *asked = NULL;
PMList *i;
PMList *i, *j;
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
@ -383,7 +383,6 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
if(deps) {
int found = 0;
PMList *j, *k;
int errorout = 0;
_alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies");
@ -411,6 +410,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
for(i = deps; i && !errorout; i = i->next) {
pmdepmissing_t *miss = i->data;
PMList *k;
if(miss->type != PM_DEP_TYPE_CONFLICT) {
continue;
}
@ -420,7 +420,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
*/
for(j = trans->packages; j && !found; j = j->next) {
pmsyncpkg_t *sync = j->data;
if(sync->type == PM_SYNC_TYPE_REPLACE || sync->type == PM_SYNC_TYPE_REMOVE) {
if(sync->type == PM_SYNC_TYPE_REPLACE) {
for(k = sync->data; k && !found; k = k->next) {
pmpkg_t *p = k->data;
if(!strcmp(p->name, miss->depend.name)) {
@ -441,16 +441,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
* fields are inherited properly.
*/
/* we save the dependency info so we can move p's requiredby stuff
* over to the replacing package
*/
pmpkg_t *q = db_scan(db_local, miss->depend.name, INFRQ_DESC | INFRQ_DEPENDS);
if(q) {
/* append to the replaces list */
pmsyncpkg_t *spkg = sync_new(PM_SYNC_TYPE_REPLACE, q, NULL);
trans->packages = pm_list_add(trans->packages, spkg);
solved = 1;
} else {
if(db_get_pkgfromcache(db_local, miss->depend.name) == NULL) {
char *rmpkg = NULL;
/* hmmm, depend.name isn't installed, so it must be conflicting
* with another package in our final list. For example:
@ -492,16 +483,7 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
if(!solved) {
/* It's a conflict -- see if they want to remove it
*/
pmpkg_t *p,*q = NULL;
int pkgfound = 0;
for(k = db_get_pkgcache(db_local); k; k = k->next) {
p = k->data;
if(!strcmp(p->name, miss->depend.name)) {
pkgfound = 1;
break;
}
}
if(pkgfound) {
if(db_get_pkgfromcache(db_local, miss->depend.name)) {
int doremove = 0;
if(!pm_list_is_strin(miss->depend.name, asked)) {
QUESTION(trans, PM_TRANS_CONV_CONFLICT_PKG, miss->target, miss->depend.name, NULL, &doremove);
@ -512,8 +494,8 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
for(l = trans->packages; l; l = l->next) {
pmsyncpkg_t *s = l->data;
if(!strcmp(s->pkg->name, miss->target)) {
q = pkg_new();
strcpy(q->name, miss->depend.name);
pmpkg_t *q = pkg_new();
STRNCPY(q->name, miss->depend.name, PKG_NAME_LEN);
if(s->type == PM_SYNC_TYPE_REPLACE) {
/* append to the replaces list */
s->data = pm_list_add(s->data, q);
@ -550,27 +532,42 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
FREELISTPTR(list);
FREELISTPTR(trail);
FREELIST(asked);
/* 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...
*/
/* 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) {
pmsyncpkg_t *sync = i->data;
if(sync->type == PM_SYNC_TYPE_REPLACE) {
for(j = sync->data; j; j = j->next) {
list = pm_list_add(list, j->data);
}
}
}
_alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");
deps = checkdeps(db_local, PM_TRANS_TYPE_REMOVE, list);
if(deps) {
*data = deps;
pm_errno = PM_ERR_UNSATISFIED_DEPS;
goto error;
}
FREELISTPTR(list);
/*EVENT(trans, PM_TRANS_EVT_CHECKDEPS_DONE, NULL, NULL);*/
}
/* any packages in rmtargs need to be removed from final. */
/* rather than ripping out nodes from final, we just copy over */
/* our "good" nodes to a new list and reassign. */
/* 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...
*/
/* ORE
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. */
/*_alpm_log(PM_LOG_DEBUG, "checking dependencies of packages designated for removal");*/
return(0);
error:
@ -596,11 +593,14 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
tr = trans_new();
if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, "could not create removal transaction");
pm_errno = PM_ERR_XXX;
pm_errno = PM_ERR_MEMORY;
goto error;
}
trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL);
if(trans_init(tr, PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS, NULL, NULL) == -1) {
_alpm_log(PM_LOG_ERROR, "could not initialize the removal transaction");
goto error;
}
for(i = trans->packages; i; i = i->next) {
pmsyncpkg_t *sync = i->data;