[pacman-dev] CVS update of pacman-lib/lib/libalpm (6 files)
Date: Thursday, March 1, 2007 @ 02:03:05 Author: aaron Path: /home/cvs-pacman/pacman-lib/lib/libalpm Modified: add.c (1.120 -> 1.121) alpm_list.c (1.6 -> 1.7) alpm_list.h (1.5 -> 1.6) deps.c (1.71 -> 1.72) provide.c (1.11 -> 1.12) versioncmp.c (1.14 -> 1.15) * Switched some functions to alpm_pkg_get_* usage as I came across them * Added some provision switching hackery. This could probably use some refactoring,.. it solves the following case: pkg1 and pkg2 provide 'foo' and are both installed pkg3 depends on 'foo' and so lists 'pkg1' in the REQUIREDBY db section pkg1 is upgraded and no longer provides 'foo' ** This code ensures that the REQUIREDBY of pkg3 is updated to require pkg2 now instead of pkg1 --------------+ add.c | 30 ++++++++++++++++++++++++ alpm_list.c | 27 +++++++++++++++++++++ alpm_list.h | 1 deps.c | 71 ++++++++++++++++++++++++++++++++++++++++++--------------- provide.c | 2 - versioncmp.c | 2 - 6 files changed, 113 insertions(+), 20 deletions(-) Index: pacman-lib/lib/libalpm/add.c diff -u pacman-lib/lib/libalpm/add.c:1.120 pacman-lib/lib/libalpm/add.c:1.121 --- pacman-lib/lib/libalpm/add.c:1.120 Mon Feb 26 03:38:48 2007 +++ pacman-lib/lib/libalpm/add.c Thu Mar 1 02:03:05 2007 @@ -343,6 +343,7 @@ oldpkg = _alpm_pkg_new(local->name, local->version); if(oldpkg) { oldpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(local)); + oldpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(local)); strncpy(oldpkg->name, local->name, PKG_NAME_LEN); strncpy(oldpkg->version, local->version, PKG_VERSION_LEN); } else { @@ -749,6 +750,35 @@ * 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 */ + 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, oldpkg->name, oldpkg->version, newpkg->version); + + 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; + _alpm_log(PM_LOG_DEBUG, _("updating '%s' due to provision change (%s)"), provpkg->name, 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, provpkg->name); + alpm_logaction(_("could not update provision '%s' from '%s'"), provname, provpkg->name); + RET_ERR(PM_ERR_DB_WRITE, -1); + } + } + } + /* make an install date (in UTC) */ time_t t = time(NULL); strncpy(newpkg->installdate, asctime(gmtime(&t)), PKG_DATE_LEN); Index: pacman-lib/lib/libalpm/alpm_list.c diff -u pacman-lib/lib/libalpm/alpm_list.c:1.6 pacman-lib/lib/libalpm/alpm_list.c:1.7 --- pacman-lib/lib/libalpm/alpm_list.c:1.6 Tue Jan 30 02:47:20 2007 +++ pacman-lib/lib/libalpm/alpm_list.c Thu Mar 1 02:03:05 2007 @@ -457,6 +457,33 @@ return(0); } +/** + * Calculate the items in list `lhs` that are not present in list `rhs` + * @note Entries are not duplicated + * @param lhs the first list + * @param rhs the second list + * @param fn the comparisson function + * @return a list containing all items in lhs not present in rhs + */ +alpm_list_t *alpm_list_diff(alpm_list_t *lhs, alpm_list_t *rhs, alpm_list_fn_cmp fn) +{ + alpm_list_t *i, *j, *ret = NULL; + for(i = lhs; i; i = i->next) { + int found = 0; + for(j = rhs; j; j = j->next) { + if(fn(i->data, j->data) == 0) { + found = 1; + break; + } + } + if(!found) { + ret = alpm_list_add(ret, i->data); + } + } + + return(ret); +} + /** @} */ /* vim: set ts=2 sw=2 noet: */ Index: pacman-lib/lib/libalpm/alpm_list.h diff -u pacman-lib/lib/libalpm/alpm_list.h:1.5 pacman-lib/lib/libalpm/alpm_list.h:1.6 --- pacman-lib/lib/libalpm/alpm_list.h:1.5 Fri Feb 16 17:41:51 2007 +++ pacman-lib/lib/libalpm/alpm_list.h Thu Mar 1 02:03:05 2007 @@ -65,6 +65,7 @@ int alpm_list_count(const alpm_list_t *list); int alpm_list_find(alpm_list_t *haystack, const void *needle); int alpm_list_find_str(alpm_list_t *haystack,const char *needle); +alpm_list_t *alpm_list_diff(alpm_list_t *lhs, alpm_list_t *rhs, alpm_list_fn_cmp fn); #endif /* _ALPM_LIST_H */ Index: pacman-lib/lib/libalpm/deps.c diff -u pacman-lib/lib/libalpm/deps.c:1.71 pacman-lib/lib/libalpm/deps.c:1.72 --- pacman-lib/lib/libalpm/deps.c:1.71 Tue Feb 27 23:00:21 2007 +++ pacman-lib/lib/libalpm/deps.c Thu Mar 1 02:03:05 2007 @@ -198,7 +198,7 @@ alpm_list_t *packages) { pmdepend_t depend; - alpm_list_t *i, *j, *k; + alpm_list_t *i, *j, *k, *l; int found = 0; alpm_list_t *baddeps = NULL; pmdepmissing_t *miss = NULL; @@ -214,19 +214,18 @@ * listed in the requiredby field. */ for(i = packages; i; i = i->next) { - pmpkg_t *tp = i->data; + pmpkg_t *newpkg = i->data; pmpkg_t *oldpkg; - if(tp == NULL) { + if(newpkg == NULL) { _alpm_log(PM_LOG_DEBUG, _("null package found in package list")); continue; } - if((oldpkg = _alpm_db_get_pkgfromcache(db, tp->name)) == NULL) { - _alpm_log(PM_LOG_DEBUG, _("cannot find package installed '%s'"), tp->name); + if((oldpkg = _alpm_db_get_pkgfromcache(db, newpkg->name)) == NULL) { + _alpm_log(PM_LOG_DEBUG, _("cannot find package installed '%s'"), newpkg->name); continue; } - _alpm_db_read(db, oldpkg, INFRQ_DEPENDS); - for(j = oldpkg->requiredby; j; j = j->next) { + for(j = alpm_pkg_get_requiredby(oldpkg); j; j = j->next) { pmpkg_t *p; found = 0; if((p = _alpm_db_get_pkgfromcache(db, j->data)) == NULL) { @@ -237,19 +236,55 @@ /* this package also in the upgrade list, so don't worry about it */ continue; } - _alpm_db_read(db, p, INFRQ_DEPENDS); - for(k = p->depends; k; k = k->next) { + for(k = alpm_pkg_get_depends(p); k; k = k->next) { /* don't break any existing dependencies (possible provides) */ _alpm_splitdep(k->data, &depend); - if(_alpm_depcmp(oldpkg, &depend) && !_alpm_depcmp(tp, &depend)) { - _alpm_log(PM_LOG_DEBUG, _("checkdeps: updated '%s' won't satisfy a dependency of '%s'"), - oldpkg->name, p->name); - miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_REQUIRED, depend.mod, - depend.name, depend.version); - if(!_alpm_depmiss_isin(miss, baddeps)) { - baddeps = alpm_list_add(baddeps, miss); - } else { - FREE(miss); + + /* if oldpkg satisfied this dep, and newpkg doesn't */ + if(_alpm_depcmp(oldpkg, &depend) && !_alpm_depcmp(newpkg, &depend)) { + /* we've found a dep that was removed... see if any other package + * still contains/provides the dep */ + int satisfied = 0; + for(l = packages; l; l = l->next) { + pmpkg_t *pkg = l->data; + + if(_alpm_depcmp(pkg, &depend)) { + _alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' has moved from '%s' to '%s'"), + depend.name, oldpkg->name, pkg->name); + satisfied = 1; + break; + } + } + + if(!satisfied) { + /* worst case... check installed packages to see if anything else + * satisfies this... */ + for(l = _alpm_db_get_pkgcache(db, INFRQ_DEPENDS); l; l = l->next) { + pmpkg_t *pkg = l->data; + + if(strcmp(pkg->name, oldpkg->name) == 0) { + /* well, we know this one fails... skip it */ + continue; + } + if(_alpm_depcmp(pkg, &depend)) { + _alpm_log(PM_LOG_DEBUG, _("checkdeps: dependency '%s' satisfied by installed package '%s'"), + depend.name, pkg->name); + satisfied = 1; + break; + } + } + } + + if(!satisfied) { + _alpm_log(PM_LOG_DEBUG, _("checkdeps: updated '%s' won't satisfy a dependency of '%s'"), + oldpkg->name, p->name); + miss = _alpm_depmiss_new(p->name, PM_DEP_TYPE_REQUIRED, depend.mod, + depend.name, depend.version); + if(!_alpm_depmiss_isin(miss, baddeps)) { + baddeps = alpm_list_add(baddeps, miss); + } else { + FREE(miss); + } } } } Index: pacman-lib/lib/libalpm/provide.c diff -u pacman-lib/lib/libalpm/provide.c:1.11 pacman-lib/lib/libalpm/provide.c:1.12 --- pacman-lib/lib/libalpm/provide.c:1.11 Mon Feb 26 03:38:48 2007 +++ pacman-lib/lib/libalpm/provide.c Thu Mar 1 02:03:05 2007 @@ -45,7 +45,7 @@ for(lp = _alpm_db_get_pkgcache(db, INFRQ_DEPENDS); lp; lp = lp->next) { pmpkg_t *info = lp->data; - if(alpm_list_find_str(info->provides, package)) { + if(alpm_list_find_str(alpm_pkg_get_provides(info), package)) { pkgs = alpm_list_add(pkgs, info); } } Index: pacman-lib/lib/libalpm/versioncmp.c diff -u pacman-lib/lib/libalpm/versioncmp.c:1.14 pacman-lib/lib/libalpm/versioncmp.c:1.15 --- pacman-lib/lib/libalpm/versioncmp.c:1.14 Sun Feb 18 13:29:29 2007 +++ pacman-lib/lib/libalpm/versioncmp.c Thu Mar 1 02:03:05 2007 @@ -252,7 +252,7 @@ ALPM_LOG_FUNC; if(strcmp(pkg->name, dep->name) == 0 - || alpm_list_find_str(pkg->provides, dep->name)) { + || alpm_list_find_str(alpm_pkg_get_provides(pkg), dep->name)) { if(dep->mod == PM_DEP_MOD_ANY) { equal = 1; } else {
On 3/1/07, Aaron Griffin <aaron@archlinux.org> wrote:
* Added some provision switching hackery. This could probably use some refactoring,.. it solves the following case:
pkg1 and pkg2 provide 'foo' and are both installed pkg3 depends on 'foo' and so lists 'pkg1' in the REQUIREDBY db section pkg1 is upgraded and no longer provides 'foo' ** This code ensures that the REQUIREDBY of pkg3 is updated to require pkg2 now instead of pkg1
Just a quick note on this one. This also implies that a "pacman -S pkg1" with the 'foo' removal will succeed now as long as foo is still satisfied.
participants (2)
-
Aaron Griffin
-
Aaron Griffin