1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-12-22 15:58:50 -05:00

Reorganize code for one-at-a-time resolving

This change reorganizes the internal code so that packages are
resolved one at a time instead of all at once from a list.  This will
allow a future checkin to prompt the user to see if they'd rather
remove unresolvable packages from the transaction and continue, or
fail the transaction.  This change does not affect the actual behavior
of libalpm and all tests pass without changes.

Signed-off-by: Bryan Ischo <bryan@ischo.com>
Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Bryan Ischo 2009-01-27 01:48:39 +13:00 committed by Dan McGee
parent e515d89969
commit 6c4d702cb1
3 changed files with 78 additions and 23 deletions

View File

@ -546,17 +546,33 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
return(NULL); return(NULL);
} }
/* populates list with packages that need to be installed to satisfy all /* Computes resolvable dependencies for a given package and adds that package
* dependencies of packages in list * and those resolvable dependencies to a list.
* *
* @param remove contains packages elected for removal * @param local is the local database
* @param dbs_sync are the sync databases
* @param pkg is the package to resolve
* @param packages is a pointer to a list of packages which will be
* searched first for any dependency packages needed to complete the
* resolve, and to which will be added any [pkg] and all of its
* dependencies not already on the list
* @param remove is the set of packages which will be removed in this
* transaction
* @param data returns the dependency which could not be satisfied in the
* event of an error
* @return 0 on success, with [pkg] and all of its dependencies not already on
* the [*packages] list added to that list, or -1 on failure due to an
* unresolvable dependency, in which case the [*packages] list will be
* unmodified by this function
*/ */
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list, int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
alpm_list_t *remove, alpm_list_t **data) alpm_list_t **packages, alpm_list_t *remove,
alpm_list_t **data)
{ {
alpm_list_t *i, *j; alpm_list_t *i, *j;
alpm_list_t *targ; alpm_list_t *targ;
alpm_list_t *deps = NULL; alpm_list_t *deps = NULL;
alpm_list_t *packages_copy;
ALPM_LOG_FUNC; ALPM_LOG_FUNC;
@ -564,8 +580,19 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
return(-1); return(-1);
} }
if(_alpm_pkg_find(*packages, pkg->name) != NULL) {
return(0);
}
/* Create a copy of the packages list, so that it can be restored
on error */
packages_copy = alpm_list_copy(*packages);
/* [pkg] has not already been resolved into the packages list, so put it
on that list */
*packages = alpm_list_add(*packages, pkg);
_alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n"); _alpm_log(PM_LOG_DEBUG, "started resolving dependencies\n");
for(i = list; i; i = i->next) { for(i = alpm_list_last(*packages); i; i = i->next) {
pmpkg_t *tpkg = i->data; pmpkg_t *tpkg = i->data;
targ = alpm_list_add(NULL, tpkg); targ = alpm_list_add(NULL, tpkg);
deps = alpm_checkdeps(_alpm_db_get_pkgcache(local), 0, remove, targ); deps = alpm_checkdeps(_alpm_db_get_pkgcache(local), 0, remove, targ);
@ -573,12 +600,12 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
for(j = deps; j; j = j->next) { for(j = deps; j; j = j->next) {
pmdepmissing_t *miss = j->data; pmdepmissing_t *miss = j->data;
pmdepend_t *missdep = alpm_miss_get_dep(miss); pmdepend_t *missdep = alpm_miss_get_dep(miss);
/* check if one of the packages in list already satisfies this dependency */ /* check if one of the packages in the [*packages] list already satisfies this dependency */
if(_alpm_find_dep_satisfier(list, missdep)) { if(_alpm_find_dep_satisfier(*packages, missdep)) {
continue; continue;
} }
/* find a satisfier package in the given repositories */ /* find a satisfier package in the given repositories */
pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, list, tpkg); pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, tpkg);
if(!spkg) { if(!spkg) {
pm_errno = PM_ERR_UNSATISFIED_DEPS; pm_errno = PM_ERR_UNSATISFIED_DEPS;
char *missdepstring = alpm_dep_compute_string(missdep); char *missdepstring = alpm_dep_compute_string(missdep);
@ -592,18 +619,21 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
*data = alpm_list_add(*data, missd); *data = alpm_list_add(*data, missd);
} }
} }
alpm_list_free(*packages);
*packages = packages_copy;
alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free); alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(deps); alpm_list_free(deps);
return(-1); return(-1);
} else { } else {
_alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n", _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg)); alpm_pkg_get_name(spkg), alpm_pkg_get_name(tpkg));
list = alpm_list_add(list, spkg); *packages = alpm_list_add(*packages, spkg);
} }
} }
alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free); alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
alpm_list_free(deps); alpm_list_free(deps);
} }
alpm_list_free(packages_copy);
_alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n"); _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
return(0); return(0);
} }

View File

@ -48,8 +48,8 @@ void _alpm_depmiss_free(pmdepmissing_t *miss);
alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse); alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse);
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);
pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg); pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, pmpkg_t *tpkg);
int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list, int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
alpm_list_t *remove, alpm_list_t **data); alpm_list_t **packages, alpm_list_t *remove, alpm_list_t **data);
int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2); int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2);
pmdepend_t *_alpm_splitdep(const char *depstring); pmdepend_t *_alpm_splitdep(const char *depstring);
pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep); pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep);

View File

@ -399,6 +399,7 @@ 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, *remove = NULL; /* allow checkdeps usage with trans->packages */ alpm_list_t *list = NULL, *remove = NULL; /* allow checkdeps usage with trans->packages */
alpm_list_t *unresolvable = NULL;
alpm_list_t *i, *j; alpm_list_t *i, *j;
int ret = 0; int ret = 0;
@ -411,15 +412,13 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
*data = NULL; *data = NULL;
} }
for(i = trans->packages; i; i = i->next) { if(trans->flags & PM_TRANS_FLAG_NODEPS) {
pmsyncpkg_t *sync = i->data; for(i = trans->packages; i; i = i->next) {
list = alpm_list_add(list, sync->pkg); pmsyncpkg_t *sync = i->data;
} list = alpm_list_add(list, sync->pkg);
}
if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) { } else {
/* store a pointer to the last original target so we can tell what was /* Build up list by repeatedly resolving each transaction package */
* pulled by resolvedeps */
alpm_list_t *pulled = alpm_list_last(list);
/* Resolve targets dependencies */ /* Resolve targets dependencies */
EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL); EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
_alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n"); _alpm_log(PM_LOG_DEBUG, "resolving target's dependencies\n");
@ -432,14 +431,39 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
} }
} }
if(_alpm_resolvedeps(db_local, dbs_sync, list, remove, data) == -1) { /* Resolve packages in the transaction one at a time, in addtion
building up a list of packages which could not be resolved. */
for(i = trans->packages; i; i = i->next) {
pmpkg_t *pkg = ((pmsyncpkg_t *) i->data)->pkg;
if(_alpm_resolvedeps(db_local, dbs_sync, pkg, &list, remove, data) == -1) {
unresolvable = alpm_list_add(unresolvable, pkg);
}
/* Else, [list] now additionally contains [pkg] and all of its
dependencies not already on the list */
}
/* If there were unresolvable top-level packages, fail the
transaction. */
if(unresolvable != NULL) {
/* pm_errno is set by resolvedeps */ /* pm_errno is set by resolvedeps */
ret = -1; ret = -1;
goto cleanup; goto cleanup;
} }
for(i = pulled->next; i; i = i->next) { /* Add all packages which were "pulled" (i.e. weren't already in the
transaction) to the transaction in pmsyncpkg_t structures */
for(i = list; i; i = i->next) {
pmpkg_t *spkg = i->data; pmpkg_t *spkg = i->data;
for(j = trans->packages; j; j = j->next) {
if(_alpm_pkg_cmp(spkg, ((pmsyncpkg_t *) j->data)->pkg) == 0) {
spkg = NULL;
break;
}
}
if (spkg == NULL) {
continue;
}
pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_DEPEND, spkg, NULL); pmsyncpkg_t *sync = _alpm_sync_new(PM_PKG_REASON_DEPEND, spkg, NULL);
if(sync == NULL) { if(sync == NULL) {
ret = -1; ret = -1;
@ -627,6 +651,7 @@ 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(remove); alpm_list_free(remove);
alpm_list_free(unresolvable);
return(ret); return(ret);
} }