mirror of
https://github.com/moparisthebest/pacman
synced 2024-08-13 17:03:46 -04:00
libalpm/deps.c : cleanup + little fix for resolvedeps.
The resolvedeps function was a bit negligent, as showed by the sync011 pactest. Reference : http://www.archlinux.org/pipermail/pacman-dev/2007-July/008782.html Signed-off-by: Chantry Xavier <shiningxc@gmail.com>
This commit is contained in:
parent
66b09410b4
commit
c2920033d0
@ -614,19 +614,18 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit)
|
|||||||
/* populates *list with packages that need to be installed to satisfy all
|
/* populates *list with packages that need to be installed to satisfy all
|
||||||
* dependencies (recursive) for syncpkg
|
* dependencies (recursive) for syncpkg
|
||||||
*
|
*
|
||||||
* make sure *list and *trail are already initialized
|
* make sure **list is already initialized
|
||||||
*/
|
*/
|
||||||
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
||||||
alpm_list_t *list, alpm_list_t *trail, pmtrans_t *trans,
|
alpm_list_t **list, pmtrans_t *trans, alpm_list_t **data)
|
||||||
alpm_list_t **data)
|
|
||||||
{
|
{
|
||||||
alpm_list_t *i, *j;
|
alpm_list_t *i, *j, *k;
|
||||||
alpm_list_t *targ;
|
alpm_list_t *targ;
|
||||||
alpm_list_t *deps = NULL;
|
alpm_list_t *deps = NULL;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
|
|
||||||
if(local == NULL || dbs_sync == NULL || syncpkg == NULL) {
|
if(local == NULL || dbs_sync == NULL || syncpkg == NULL || list == NULL) {
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,14 +641,15 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
|||||||
for(i = deps; i; i = i->next) {
|
for(i = deps; i; i = i->next) {
|
||||||
int found = 0;
|
int found = 0;
|
||||||
pmdepmissing_t *miss = i->data;
|
pmdepmissing_t *miss = i->data;
|
||||||
|
pmdepend_t *missdep = &(miss->depend);
|
||||||
pmpkg_t *sync = NULL;
|
pmpkg_t *sync = NULL;
|
||||||
|
|
||||||
/* check if one of the packages in *list already provides this dependency */
|
/* check if one of the packages in *list already satisfies this dependency */
|
||||||
for(j = list; j && !found; j = j->next) {
|
for(j = *list; j && !found; j = j->next) {
|
||||||
pmpkg_t *sp = j->data;
|
pmpkg_t *sp = j->data;
|
||||||
if(alpm_list_find_str(alpm_pkg_get_provides(sp), miss->depend.name)) {
|
if(alpm_depcmp(sp, missdep)) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "%s provides dependency %s -- skipping",
|
_alpm_log(PM_LOG_DEBUG, "%s satisfies dependency %s -- skipping",
|
||||||
alpm_pkg_get_name(sp), miss->depend.name);
|
alpm_pkg_get_name(sp), missdep->name);
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -659,26 +659,24 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
|||||||
|
|
||||||
/* find the package in one of the repositories */
|
/* find the package in one of the repositories */
|
||||||
/* check literals */
|
/* check literals */
|
||||||
for(j = dbs_sync; !sync && j; j = j->next) {
|
for(j = dbs_sync; j && !found; j = j->next) {
|
||||||
sync = _alpm_db_get_pkgfromcache(j->data, miss->depend.name);
|
if((sync = _alpm_db_get_pkgfromcache(j->data, missdep->name))) {
|
||||||
|
found = alpm_depcmp(sync, missdep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*TODO this autoresolves the first 'provides' package... we should fix this
|
/*TODO this autoresolves the first 'satisfier' package... we should fix this
|
||||||
* somehow */
|
* somehow */
|
||||||
/* check provides */
|
/* check provides */
|
||||||
if(!sync) {
|
for(j = dbs_sync; j && !found; j = j->next) {
|
||||||
for(j = dbs_sync; !sync && j; j = j->next) {
|
for(k = _alpm_db_get_pkgcache(j->data); k && !found; k = k->next) {
|
||||||
alpm_list_t *provides;
|
sync = k->data;
|
||||||
provides = _alpm_db_whatprovides(j->data, miss->depend.name);
|
found = alpm_depcmp(sync, missdep);
|
||||||
if(provides) {
|
|
||||||
sync = provides->data;
|
|
||||||
}
|
|
||||||
alpm_list_free(provides);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sync) {
|
if(!found) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("cannot resolve dependencies for \"%s\" (\"%s\" is not in the package set)"),
|
_alpm_log(PM_LOG_ERROR, _("cannot resolve dependencies for \"%s\" (\"%s\" is not in the package set)"),
|
||||||
miss->target, miss->depend.name);
|
miss->target, missdep->name);
|
||||||
if(data) {
|
if(data) {
|
||||||
if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) {
|
if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) {
|
||||||
_alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmdepmissing_t));
|
_alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmdepmissing_t));
|
||||||
@ -692,49 +690,36 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
|||||||
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if(_alpm_pkg_find(alpm_pkg_get_name(sync), list)) {
|
/* check pmo_ignorepkg and pmo_s_ignore to make sure we haven't pulled in
|
||||||
/* this dep is already in the target list */
|
* something we're not supposed to.
|
||||||
_alpm_log(PM_LOG_DEBUG, "dependency %s is already in the target list -- skipping",
|
*/
|
||||||
alpm_pkg_get_name(sync));
|
int usedep = 1;
|
||||||
continue;
|
if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(sync))) {
|
||||||
|
pmpkg_t *dummypkg = _alpm_pkg_new(miss->target, NULL);
|
||||||
|
QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &usedep);
|
||||||
|
_alpm_pkg_free(dummypkg);
|
||||||
}
|
}
|
||||||
|
if(usedep) {
|
||||||
if(!_alpm_pkg_find(alpm_pkg_get_name(sync), trail)) {
|
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)",
|
||||||
/* check pmo_ignorepkg and pmo_s_ignore to make sure we haven't pulled in
|
alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg));
|
||||||
* something we're not supposed to.
|
*list = alpm_list_add(*list, sync);
|
||||||
*/
|
if(_alpm_resolvedeps(local, dbs_sync, sync, list, trans, data)) {
|
||||||
int usedep = 1;
|
|
||||||
if(alpm_list_find_str(handle->ignorepkg, alpm_pkg_get_name(sync))) {
|
|
||||||
pmpkg_t *dummypkg = _alpm_pkg_new(miss->target, NULL);
|
|
||||||
QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &usedep);
|
|
||||||
_alpm_pkg_free(dummypkg);
|
|
||||||
}
|
|
||||||
if(usedep) {
|
|
||||||
trail = alpm_list_add(trail, sync);
|
|
||||||
if(_alpm_resolvedeps(local, dbs_sync, sync, list, trail, trans, data)) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)",
|
|
||||||
alpm_pkg_get_name(sync), alpm_pkg_get_name(syncpkg));
|
|
||||||
list = alpm_list_add(list, sync);
|
|
||||||
} else {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("cannot resolve dependencies for \"%s\""), miss->target);
|
|
||||||
if(data) {
|
|
||||||
if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) {
|
|
||||||
_alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmdepmissing_t));
|
|
||||||
FREELIST(*data);
|
|
||||||
pm_errno = PM_ERR_MEMORY;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
*miss = *(pmdepmissing_t *)i->data;
|
|
||||||
*data = alpm_list_add(*data, miss);
|
|
||||||
}
|
|
||||||
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* cycle detected -- skip it */
|
_alpm_log(PM_LOG_ERROR, _("cannot resolve dependencies for \"%s\""), miss->target);
|
||||||
_alpm_log(PM_LOG_DEBUG, "dependency cycle detected: %s", sync->name);
|
if(data) {
|
||||||
|
if((miss = malloc(sizeof(pmdepmissing_t))) == NULL) {
|
||||||
|
_alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmdepmissing_t));
|
||||||
|
FREELIST(*data);
|
||||||
|
pm_errno = PM_ERR_MEMORY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
*miss = *(pmdepmissing_t *)i->data;
|
||||||
|
*data = alpm_list_add(*data, miss);
|
||||||
|
}
|
||||||
|
pm_errno = PM_ERR_UNSATISFIED_DEPS;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,7 @@ alpm_list_t *_alpm_checkdeps(pmdb_t *db, pmtranstype_t op,
|
|||||||
alpm_list_t *packages);
|
alpm_list_t *packages);
|
||||||
void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit);
|
void _alpm_recursedeps(pmdb_t *db, alpm_list_t **targs, int include_explicit);
|
||||||
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *syncpkg,
|
||||||
alpm_list_t *list, alpm_list_t *trail, pmtrans_t *trans,
|
alpm_list_t **list, pmtrans_t *trans, alpm_list_t **data);
|
||||||
alpm_list_t **data);
|
|
||||||
|
|
||||||
#endif /* _ALPM_DEPS_H */
|
#endif /* _ALPM_DEPS_H */
|
||||||
|
|
||||||
|
@ -380,7 +380,6 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
|||||||
{
|
{
|
||||||
alpm_list_t *deps = NULL;
|
alpm_list_t *deps = NULL;
|
||||||
alpm_list_t *list = NULL; /* allow checkdeps usage with trans->packages */
|
alpm_list_t *list = NULL; /* allow checkdeps usage with trans->packages */
|
||||||
alpm_list_t *trail = NULL; /* breadcrumb list to avoid running in circles */
|
|
||||||
alpm_list_t *i, *j;
|
alpm_list_t *i, *j;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -404,8 +403,8 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
|||||||
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies");
|
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies");
|
||||||
for(i = trans->packages; i; i = i->next) {
|
for(i = trans->packages; i; i = i->next) {
|
||||||
pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg;
|
pmpkg_t *spkg = ((pmsyncpkg_t *)i->data)->pkg;
|
||||||
if(_alpm_resolvedeps(db_local, dbs_sync, spkg, list,
|
if(_alpm_resolvedeps(db_local, dbs_sync, spkg, &list,
|
||||||
trail, trans, data) == -1) {
|
trans, data) == -1) {
|
||||||
/* pm_errno is set by resolvedeps */
|
/* pm_errno is set by resolvedeps */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -474,7 +473,6 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_free(trail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't care about conflicts if we're just printing uris */
|
/* We don't care about conflicts if we're just printing uris */
|
||||||
@ -710,7 +708,6 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
alpm_list_free(list);
|
alpm_list_free(list);
|
||||||
alpm_list_free(trail);
|
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
20
pactest/tests/sync011.py
Normal file
20
pactest/tests/sync011.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
self.description = "Install a package from a sync db with cascaded dependencies + provides"
|
||||||
|
|
||||||
|
sp1 = pmpkg("dummy", "1.0-2")
|
||||||
|
sp1.depends = ["dep1", "dep2=1.0-2"]
|
||||||
|
|
||||||
|
sp2 = pmpkg("dep1")
|
||||||
|
sp2.files = ["bin/dep1"]
|
||||||
|
sp2.provides = ["dep2"]
|
||||||
|
|
||||||
|
sp3 = pmpkg("dep2", "1.0-2")
|
||||||
|
|
||||||
|
for p in sp1, sp2, sp3:
|
||||||
|
self.addpkg2db("sync", p);
|
||||||
|
|
||||||
|
self.args = "-S %s" % sp1.name
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=0")
|
||||||
|
self.addrule("PKG_VERSION=dummy|1.0-2")
|
||||||
|
self.addrule("PKG_EXIST=dep1")
|
||||||
|
self.addrule("PKG_EXIST=dep2")
|
Loading…
Reference in New Issue
Block a user