From b1808930ce45a034981626fc20bbc7920890899e Mon Sep 17 00:00:00 2001 From: Nagy Gabor Date: Mon, 16 Jul 2007 20:58:58 +0200 Subject: libalpm/add.c,trans.c : cleanup of requiredby handling. This patch cleans up and fix the _alpm_trans_update_depends function and ensure that all requiredby fields are filled in case of multiple satisfiers (previously, the handling of mutliple satisfiers in that function was inconsistent). This makes a special case handling of requiredby in commit_single_pkg() obsolete, and so allows cleaning that code as well. Also fixed upgrade056 pactest because : 1) the requiredby fields were wrong, and this wouldn't happen with the fixed _alpm_trans_update_depends(). 2) this is a very unusual case anyway (and handling all corner cases combined to a broken database seems nearly impossible to achieve). References : http://www.archlinux.org/pipermail/pacman-dev/2007-July/008919.html http://www.archlinux.org/pipermail/pacman-dev/2007-July/008920.html Signed-off-by: Chantry Xavier --- lib/libalpm/add.c | 37 ----------------------- lib/libalpm/package.c | 3 ++ lib/libalpm/trans.c | 73 ++++++++------------------------------------- pactest/tests/upgrade056.py | 1 + 4 files changed, 16 insertions(+), 98 deletions(-) diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 9ef83d91..398839a6 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -827,43 +827,6 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, * looking for packages depending on the package to add */ _alpm_pkg_update_requiredby(newpkg); - /* special case: if our provides list has changed from oldpkg to newpkg AND - * we get here, we need to make sure we find the actual provision that - * still satisfies this case, and update its 'requiredby' field... ugh */ - /* TODO this seems really messy and should be taken care of elsewhere */ - alpm_list_t *provdiff, *prov; - provdiff = alpm_list_diff(alpm_pkg_get_provides(oldpkg), - alpm_pkg_get_provides(newpkg), - _alpm_str_cmp); - for(prov = provdiff; prov; prov = prov->next) { - const char *provname = prov->data; - _alpm_log(PM_LOG_DEBUG, "provision '%s' has been removed from package %s (%s => %s)", - provname, alpm_pkg_get_name(oldpkg), - alpm_pkg_get_version(oldpkg), alpm_pkg_get_version(newpkg)); - - alpm_list_t *p = _alpm_db_whatprovides(handle->db_local, provname); - if(p) { - /* we now have all the provisions in the local DB for this virtual - * package... seeing as we can't really determine which is the 'correct' - * provision, we'll use the FIRST for now. - * TODO figure out a way to find a "correct" provision */ - pmpkg_t *provpkg = p->data; - const char *pkgname = alpm_pkg_get_name(provpkg); - _alpm_log(PM_LOG_DEBUG, "updating '%s' due to provision change (%s)", - pkgname, provname); - _alpm_pkg_update_requiredby(provpkg); - - if(_alpm_db_write(db, provpkg, INFRQ_DEPENDS)) { - _alpm_log(PM_LOG_ERROR, _("could not update provision '%s' from '%s'"), - provname, pkgname); - alpm_logaction("error: could not update provision '%s' from '%s'", - provname, pkgname); - RET_ERR(PM_ERR_DB_WRITE, -1); - } - } - } - alpm_list_free(provdiff); - /* make an install date (in UTC) */ time_t t = time(NULL); strncpy(newpkg->installdate, asctime(gmtime(&t)), PKG_DATE_LEN); diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index e11d7476..135a3510 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -1109,6 +1109,9 @@ int _alpm_pkg_splitname(const char *target, char *name, char *version, int witha /* scan the local db to fill in requiredby field of package, * used when we want to install or add a package */ + +/* A depends on B through n depends <=> A listed in B's requiredby n times + * n == 0 or 1 in almost all cases */ void _alpm_pkg_update_requiredby(pmpkg_t *pkg) { const alpm_list_t *i, *j; diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index ca8d6ce9..8c35fa36 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -428,6 +428,8 @@ int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data) return(0); } +/* A depends on B through n depends <=> A listed in B's requiredby n times + * n == 0 or 1 in almost all cases */ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) { alpm_list_t *i, *j; @@ -436,7 +438,7 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) pmdb_t *localdb; ALPM_LOG_FUNC; - + /* Sanity checks */ ASSERT(trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(pkg != NULL, RET_ERR(PM_ERR_PKG_INVALID, -1)); @@ -453,40 +455,22 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) localdb = alpm_option_get_localdb(); for(i = depends; i; i = i->next) { + if(!i->data) { + continue; + } pmdepend_t* dep = alpm_splitdep(i->data); if(dep == NULL) { continue; } - - if(trans->packages && trans->type == PM_TRANS_TYPE_REMOVE) { - if(_alpm_pkg_find(dep->name, handle->trans->packages)) { - continue; - } - } - - pmpkg_t *deppkg = _alpm_db_get_pkgfromcache(localdb, dep->name); - if(!deppkg) { - int found_provides = 0; - /* look for a provides package */ - alpm_list_t *provides = _alpm_db_whatprovides(localdb, dep->name); - for(j = provides; j; j = j->next) { - if(!j->data) { - continue; - } - pmpkg_t *provpkg = j->data; - deppkg = _alpm_db_get_pkgfromcache(localdb, alpm_pkg_get_name(provpkg)); - - if(!deppkg) { - continue; - } - - found_provides = 1; - + for(j = _alpm_db_get_pkgcache(localdb); j; j = j->next) { + pmpkg_t *deppkg = j->data; + if(deppkg && alpm_depcmp(deppkg, dep)) { /* this is cheating... we call this function to populate the package */ alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg); _alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package '%s'", alpm_pkg_get_name(deppkg)); + if(trans->type == PM_TRANS_TYPE_REMOVE || trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) { void *data = NULL; @@ -494,11 +478,8 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) FREE(data); deppkg->requiredby = rqdby; } else { - /* sanity check to make sure package was not already in list */ - if(!alpm_list_find_str(rqdby, pkgname)) { - rqdby = alpm_list_add(rqdby, strdup(pkgname)); - deppkg->requiredby = rqdby; - } + rqdby = alpm_list_add(rqdby, strdup(pkgname)); + deppkg->requiredby = rqdby; } if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) { @@ -506,36 +487,6 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) alpm_pkg_get_name(deppkg), alpm_pkg_get_version(deppkg)); } } - alpm_list_free(provides); - - if(!found_provides) { - _alpm_log(PM_LOG_DEBUG, "could not find dependency '%s'", dep->name); - continue; - } - } - - /* this is cheating... we call this function to populate the package */ - alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg); - - _alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package '%s'", - alpm_pkg_get_name(deppkg)); - if(trans->type == PM_TRANS_TYPE_REMOVE - || trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) { - void *data = NULL; - rqdby = alpm_list_remove(rqdby, pkgname, _alpm_str_cmp, &data); - FREE(data); - deppkg->requiredby = rqdby; - } else { - /* sanity check to make sure package was not already in list */ - if(!alpm_list_find_str(rqdby, pkgname)) { - rqdby = alpm_list_add(rqdby, strdup(pkgname)); - deppkg->requiredby = rqdby; - } - } - - if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) { - _alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"), - alpm_pkg_get_name(deppkg), alpm_pkg_get_version(deppkg)); } free(dep); } diff --git a/pactest/tests/upgrade056.py b/pactest/tests/upgrade056.py index 8419731c..b92c38ac 100644 --- a/pactest/tests/upgrade056.py +++ b/pactest/tests/upgrade056.py @@ -11,6 +11,7 @@ self.addpkg2db("local", lp2) lp3 = pmpkg("pkg3") lp3.provides = ["imaginary"] +lp3.requiredby = [ "pkg1" ] self.addpkg2db("local", lp3) p = pmpkg("pkg2", "1.0-2") -- cgit v1.2.3-70-g09d2