first steps to support REPLACES feature

This commit is contained in:
Aurelien Foret 2005-04-20 20:50:49 +00:00
parent 447885fdc3
commit 4fcec8f03f

View file

@ -56,12 +56,7 @@ pmsyncpkg_t *sync_new(int type, pmpkg_t *spkg, void *data)
sync->type = type; sync->type = type;
sync->pkg = spkg; sync->pkg = spkg;
sync->data = data;
if(sync->type == PM_SYNC_TYPE_REPLACE) {
sync->data = pm_list_add(NULL, data);
} else {
sync->data = data;
}
return(sync); return(sync);
} }
@ -152,15 +147,36 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
if(pm_list_is_strin(lpkg->name, handle->ignorepkg)) { if(pm_list_is_strin(lpkg->name, handle->ignorepkg)) {
_alpm_log(PM_LOG_WARNING, "%s-%s: ignoring package upgrade (to be replaced by %s-%s)", _alpm_log(PM_LOG_WARNING, "%s-%s: ignoring package upgrade (to be replaced by %s-%s)",
lpkg->name, lpkg->version, spkg->name, spkg->version); lpkg->name, lpkg->version, spkg->name, spkg->version);
} else { } else /* ORE if(yesno(":: Replace %s with %s from \"%s\"? [Y/n] ", lpkg->name, spkg->name, ((pmdb_t *)i->data)->treename)) */ {
pmsyncpkg_t *sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, lpkg); /* if confirmed, add this to the 'final' list, designating 'lpkg' as
if(sync == NULL) { * the package to replace.
*/
pmsyncpkg_t *sync;
pmpkg_t *dummy = pkg_new();
if(dummy == NULL) {
pm_errno = PM_ERR_MEMORY; pm_errno = PM_ERR_MEMORY;
goto error; goto error;
} }
STRNCPY(dummy->name, lpkg->name, PKG_NAME_LEN);
dummy->requiredby = _alpm_list_strdup(lpkg->requiredby);
/* check if spkg->name is already in the packages list. */
sync = find_pkginsync(spkg->name, trans->packages);
if(sync) {
/* found it -- just append to the replaces list */
sync->data = pm_list_add(sync->data, dummy);
} else {
/* none found -- enter pkg into the final sync list */
sync = sync_new(PM_SYNC_TYPE_REPLACE, spkg, NULL);
if(sync == NULL) {
FREEPKG(dummy);
pm_errno = PM_ERR_MEMORY;
goto error;
}
sync->data = pm_list_add(sync->data, dummy);
trans->packages = pm_list_add(trans->packages, sync);
}
_alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)", _alpm_log(PM_LOG_DEBUG, "%s-%s elected for upgrade (to be replaced by %s-%s)",
lpkg->name, lpkg->version, spkg->name, spkg->version); lpkg->name, lpkg->version, spkg->name, spkg->version);
trans->packages = pm_list_add(trans->packages, sync);
} }
} }
} }
@ -184,7 +200,7 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
} }
} }
if(spkg == NULL) { if(spkg == NULL) {
/*fprintf(stderr, "%s: not found in sync db. skipping.", local->name);*/ /*_alpm_logf(PM_LOG_ERROR, "%s: not found in sync db -- skipping.", local->name);*/
continue; continue;
} }
@ -201,8 +217,12 @@ int sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync)
_alpm_log(PM_LOG_FLOW1, "%s-%s: ignoring package upgrade (%s)", _alpm_log(PM_LOG_FLOW1, "%s-%s: ignoring package upgrade (%s)",
local->name, local->version, spkg->version); local->name, local->version, spkg->version);
} else { } else {
sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local); pmpkg_t *dummy = pkg_new();
STRNCPY(dummy->name, local->name, PKG_NAME_LEN);
STRNCPY(dummy->version, local->version, PKG_VERSION_LEN);
sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy);
if(sync == NULL) { if(sync == NULL) {
FREEPKG(dummy);
pm_errno = PM_ERR_MEMORY; pm_errno = PM_ERR_MEMORY;
goto error; goto error;
} }
@ -279,8 +299,18 @@ int sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, char *n
/* add the package to the transaction */ /* add the package to the transaction */
if(!find_pkginsync(spkg->name, trans->packages)) { if(!find_pkginsync(spkg->name, trans->packages)) {
sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, local); pmpkg_t *dummy = NULL;
if(local) {
dummy = pkg_new();
if(dummy == NULL) {
RET_ERR(PM_ERR_MEMORY, -1);
}
STRNCPY(dummy->name, local->name, PKG_NAME_LEN);
STRNCPY(dummy->version, local->version, PKG_VERSION_LEN);
}
sync = sync_new(PM_SYNC_TYPE_UPGRADE, spkg, dummy);
if(sync == NULL) { if(sync == NULL) {
FREEPKG(dummy);
RET_ERR(PM_ERR_MEMORY, -1); RET_ERR(PM_ERR_MEMORY, -1);
} }
trans->packages = pm_list_add(trans->packages, sync); trans->packages = pm_list_add(trans->packages, sync);
@ -302,10 +332,6 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
*data = NULL; *data = NULL;
if(trans->packages == NULL) {
return(0);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
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;
@ -342,6 +368,8 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
TRANS_CB(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL); TRANS_CB(trans, PM_TRANS_EVT_INTERCONFLICTS_START, NULL, NULL);
deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list); deps = checkdeps(db_local, PM_TRANS_TYPE_UPGRADE, list);
if(deps) { if(deps) {
int found;
PMList *j, *k, *exfinal = NULL;
int errorout = 0; int errorout = 0;
_alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies"); _alpm_log(PM_LOG_FLOW1, "looking for unresolvable dependencies");
for(i = deps; i; i = i->next) { for(i = deps; i; i = i->next) {
@ -363,17 +391,40 @@ int sync_prepare(pmtrans_t *trans, pmdb_t *db_local, PMList *dbs_sync, PMList **
FREELIST(deps); FREELIST(deps);
RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1); RET_ERR(PM_ERR_UNSATISFIED_DEPS, -1);
} }
/* no unresolvable deps, so look for conflicts */ /* no unresolvable deps, so look for conflicts */
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
errorout = 0; errorout = 0;
_alpm_log(PM_LOG_FLOW1, "looking for conflicts");
for(i = deps; i && !errorout; i = i->next) {
pmdepmissing_t *miss = i->data;
if(miss->type != PM_DEP_TYPE_CONFLICT) {
continue;
}
/* make sure this package wasn't already removed from the final list */
if(pm_list_is_ptrin(miss->target, exfinal)) {
continue;
}
/* ORE /* check if the conflicting package is one that's 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 */
*/ found = 0;
for(j = trans->packages; j && !found; j = j->next) {
pmsyncpkg_t *sync = j->data;
if(sync->type != PM_SYNC_TYPE_REPLACE) {
continue;
}
for(k = sync->data; k && !found; k = k->next) {
pmpkg_t *p = k->data;
if(!strcmp(p->name, miss->depend.name)) {
found = 1;
}
}
}
/* ORE /* ORE
if we didn't find it in any sync->replaces lists, then it's a conflict */ if we didn't find it in any sync->replaces lists, then it's a conflict */
}
if(errorout) { if(errorout) {
FREELIST(deps); FREELIST(deps);
@ -420,34 +471,43 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
PMList *i; PMList *i;
PMList *data; PMList *data;
pmtrans_t *tr; pmtrans_t *tr;
char ldir[PATH_MAX];
ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1)); ASSERT(db_local != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
snprintf(ldir, PATH_MAX, "%s" PM_CACHEDIR, handle->root);
/* remove any conflicting packages (WITHOUT dep checks) */ /* remove any conflicting packages (WITHOUT dep checks) */
/* ORE - alpm does not handle removal of conflicting pkgs for now */ /* ORE - alpm does not handle removal of conflicting pkgs for now */
/* remove to-be-replaced packages */ /* remove to-be-replaced packages */
_alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages");
tr = trans_new(PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS); tr = trans_new(PM_TRANS_TYPE_REMOVE, PM_TRANS_FLAG_NODEPS);
/* ORE */ /* ORE */
if(tr == NULL) { if(tr == NULL) {
_alpm_log(PM_LOG_ERROR, "could not create transaction");
pm_errno = PM_ERR_XXX;
goto error; goto error;
} }
/*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) {
pmpkg_t *pkg = sync->lpkg; pmpkg_t *pkg = sync->pkg;
if(trans_addtarget(tr, pkg->name)) { if(trans_addtarget(tr, pkg->name)) {
goto error; goto error;
} }
} }
} }
trans_prepare(tr, &data); if(tr->packages) {
trans_commit(tr);*/ _alpm_log(PM_LOG_FLOW1, "removing to-be-replaced packages");
if(trans_prepare(tr, &data) == -1) {
_alpm_log(PM_LOG_ERROR, "could not prepare transaction");
pm_errno = PM_ERR_XXX;
goto error;
}
if(trans_commit(tr) == -1) {
_alpm_log(PM_LOG_ERROR, "could not commit transaction");
pm_errno = PM_ERR_XXX;
goto error;
}
}
trans_free(tr); trans_free(tr);
/* install targets */ /* install targets */
@ -468,7 +528,7 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
if(sync->type != PM_SYNC_TYPE_REPLACE) { if(sync->type != PM_SYNC_TYPE_REPLACE) {
pmpkg_t *spkg = sync->pkg; pmpkg_t *spkg = sync->pkg;
char str[PATH_MAX]; char str[PATH_MAX];
snprintf(str, PATH_MAX, "%s/%s-%s" PM_EXT_PKG, ldir, spkg->name, spkg->version); snprintf(str, PATH_MAX, "%s" PM_CACHEDIR "/%s-%s" PM_EXT_PKG, handle->root, spkg->name, spkg->version);
if(trans_addtarget(tr, str) == -1) { if(trans_addtarget(tr, str) == -1) {
goto error; goto error;
} }
@ -487,36 +547,40 @@ int sync_commit(pmtrans_t *trans, pmdb_t *db_local)
trans_free(tr); trans_free(tr);
/* propagate replaced packages' requiredby fields to their new owners */ /* propagate replaced packages' requiredby fields to their new owners */
/* ORE
won't work because if replaced packages are already removed, the sync(REPLACES)
structures data field will point to unexisting data... */
_alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies"); _alpm_log(PM_LOG_FLOW1, "updating database for replaced packages dependencies");
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->replaces) { if(sync->type == PM_SYNC_TYPE_REPLACE && sync->data) {
PMList *j; PMList *j;
pkginfo_t *new = db_get_pkgfromcache(db_local, sync->pkg->name); pmpkg_t *new = db_get_pkgfromcache(db_local, sync->pkg->name);
for(j = sync->replaces; j; j = j->next) { for(j = sync->data; j; j = j->next) {
pkginfo_t *old = j->data; PMList *k;
// merge lists pmpkg_t *old = j->data;
/* merge lists */
for(k = old->requiredby; k; k = k->next) { for(k = old->requiredby; k; k = k->next) {
if(!list_is_strin(k->data, new->requiredby)) { if(!pm_list_is_strin(k->data, new->requiredby)) {
// replace old's name with new's name in the requiredby's dependency list /* replace old's name with new's name in the requiredby's dependency list */
PMList *m; PMList *m;
pkginfo_t *depender = db_get_pkgfromcache(db_local, k->data); pmpkg_t *depender = db_get_pkgfromcache(db_local, k->data);
for(m = depender->depends; m; m = m->next) { for(m = depender->depends; m; m = m->next) {
if(!strcmp(m->data, old->name)) { if(!strcmp(m->data, old->name)) {
FREE(m->data); FREE(m->data);
m->data = strdup(new->name); m->data = strdup(new->name);
} }
} }
db_write(db, depender, INFRQ_DEPENDS); db_write(db_local, depender, INFRQ_DEPENDS);
// add the new requiredby /* add the new requiredby */
new->requiredby = list_add(new->requiredby, strdup(k->data)); new->requiredby = pm_list_add(new->requiredby, strdup(k->data));
} }
} }
} }
db_write(db, new, INFRQ_DEPENDS); db_write(db_local, new, INFRQ_DEPENDS);
FREEPKG(new); FREEPKG(new);
}*/ }
} }
/* cache needs to be rebuilt */ /* cache needs to be rebuilt */