mirror of
https://github.com/moparisthebest/pacman
synced 2025-01-09 04:57:59 -05:00
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 <shiningxc@gmail.com>
This commit is contained in:
parent
17d9122e01
commit
b1808930ce
@ -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 */
|
* looking for packages depending on the package to add */
|
||||||
_alpm_pkg_update_requiredby(newpkg);
|
_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) */
|
/* make an install date (in UTC) */
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
strncpy(newpkg->installdate, asctime(gmtime(&t)), PKG_DATE_LEN);
|
strncpy(newpkg->installdate, asctime(gmtime(&t)), PKG_DATE_LEN);
|
||||||
|
@ -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,
|
/* scan the local db to fill in requiredby field of package,
|
||||||
* used when we want to install or add a 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)
|
void _alpm_pkg_update_requiredby(pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
const alpm_list_t *i, *j;
|
const alpm_list_t *i, *j;
|
||||||
|
@ -428,6 +428,8 @@ int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data)
|
|||||||
return(0);
|
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)
|
int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg)
|
||||||
{
|
{
|
||||||
alpm_list_t *i, *j;
|
alpm_list_t *i, *j;
|
||||||
@ -453,40 +455,22 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg)
|
|||||||
|
|
||||||
localdb = alpm_option_get_localdb();
|
localdb = alpm_option_get_localdb();
|
||||||
for(i = depends; i; i = i->next) {
|
for(i = depends; i; i = i->next) {
|
||||||
|
if(!i->data) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pmdepend_t* dep = alpm_splitdep(i->data);
|
pmdepend_t* dep = alpm_splitdep(i->data);
|
||||||
if(dep == NULL) {
|
if(dep == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
for(j = _alpm_db_get_pkgcache(localdb); j; j = j->next) {
|
||||||
if(trans->packages && trans->type == PM_TRANS_TYPE_REMOVE) {
|
pmpkg_t *deppkg = j->data;
|
||||||
if(_alpm_pkg_find(dep->name, handle->trans->packages)) {
|
if(deppkg && alpm_depcmp(deppkg, dep)) {
|
||||||
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;
|
|
||||||
|
|
||||||
/* this is cheating... we call this function to populate the package */
|
/* this is cheating... we call this function to populate the package */
|
||||||
alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg);
|
alpm_list_t *rqdby = alpm_pkg_get_requiredby(deppkg);
|
||||||
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package '%s'",
|
_alpm_log(PM_LOG_DEBUG, "updating 'requiredby' field for package '%s'",
|
||||||
alpm_pkg_get_name(deppkg));
|
alpm_pkg_get_name(deppkg));
|
||||||
|
|
||||||
if(trans->type == PM_TRANS_TYPE_REMOVE
|
if(trans->type == PM_TRANS_TYPE_REMOVE
|
||||||
|| trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
|
|| trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) {
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
@ -494,48 +478,15 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg)
|
|||||||
FREE(data);
|
FREE(data);
|
||||||
deppkg->requiredby = rqdby;
|
deppkg->requiredby = rqdby;
|
||||||
} else {
|
} 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));
|
rqdby = alpm_list_add(rqdby, strdup(pkgname));
|
||||||
deppkg->requiredby = rqdby;
|
deppkg->requiredby = rqdby;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) {
|
if(_alpm_db_write(localdb, deppkg, INFRQ_DEPENDS)) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"),
|
_alpm_log(PM_LOG_ERROR, _("could not update 'requiredby' database entry %s-%s"),
|
||||||
alpm_pkg_get_name(deppkg), alpm_pkg_get_version(deppkg));
|
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);
|
free(dep);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ self.addpkg2db("local", lp2)
|
|||||||
|
|
||||||
lp3 = pmpkg("pkg3")
|
lp3 = pmpkg("pkg3")
|
||||||
lp3.provides = ["imaginary"]
|
lp3.provides = ["imaginary"]
|
||||||
|
lp3.requiredby = [ "pkg1" ]
|
||||||
self.addpkg2db("local", lp3)
|
self.addpkg2db("local", lp3)
|
||||||
|
|
||||||
p = pmpkg("pkg2", "1.0-2")
|
p = pmpkg("pkg2", "1.0-2")
|
||||||
|
Loading…
Reference in New Issue
Block a user