[pacman-dev] [PATCH 1/3] Internal code reorganization in preparation for changes to package
Dan McGee
dpmcgee at gmail.com
Wed Feb 18 21:55:59 EST 2009
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo
<bji-keyword-pacman.3644cb at www.ischo.com> wrote:
> From: Bryan Ischo <bryan at ischo.com>
>
> 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 tranasaction 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 at ischo.com>
As an FYI, you had trailing whitespace in all three of your patches.
Please enable the pre-commit git hook to catch this on your end.
This one is (finally) applied, thanks.
> ---
> lib/libalpm/deps.c | 52 +++++++++++++++++++++++++++++++++++++++++-----------
> lib/libalpm/deps.h | 4 ++--
> lib/libalpm/sync.c | 47 ++++++++++++++++++++++++++++++++++++-----------
> 3 files changed, 79 insertions(+), 24 deletions(-)
>
> diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
> index 940f12c..da21087 100644
> --- a/lib/libalpm/deps.c
> +++ b/lib/libalpm/deps.c
> @@ -546,17 +546,33 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud
> return(NULL);
> }
>
> -/* populates list with packages that need to be installed to satisfy all
> - * dependencies of packages in list
> - *
> - * @param remove contains packages elected for removal
> +/* Computes resolvable dependencies for a given package and adds that package
> + * and those resolvable dependencies to a list.
> + *
> + * @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,
> - alpm_list_t *remove, alpm_list_t **data)
> +int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
> + alpm_list_t **packages, alpm_list_t *remove,
> + alpm_list_t **data)
> {
> alpm_list_t *i, *j;
> alpm_list_t *targ;
> alpm_list_t *deps = NULL;
> + alpm_list_t *packages_copy;
>
> ALPM_LOG_FUNC;
>
> @@ -564,8 +580,19 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
> 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");
> - for(i = list; i; i = i->next) {
> + for(i = alpm_list_last(*packages); i; i = i->next) {
> pmpkg_t *tpkg = i->data;
> targ = alpm_list_add(NULL, tpkg);
> 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) {
> pmdepmissing_t *miss = j->data;
> pmdepend_t *missdep = alpm_miss_get_dep(miss);
> - /* check if one of the packages in list already satisfies this dependency */
> - if(_alpm_find_dep_satisfier(list, missdep)) {
> + /* check if one of the packages in the [*packages] list already satisfies this dependency */
> + if(_alpm_find_dep_satisfier(*packages, missdep)) {
> continue;
> }
> /* 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) {
> pm_errno = PM_ERR_UNSATISFIED_DEPS;
> 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);
> }
> }
> + alpm_list_free(*packages);
> + *packages = packages_copy;
> alpm_list_free_inner(deps, (alpm_list_fn_free)_alpm_depmiss_free);
> alpm_list_free(deps);
> return(-1);
> } else {
> _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)\n",
> 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(deps);
> }
> + alpm_list_free(packages_copy);
> _alpm_log(PM_LOG_DEBUG, "finished resolving dependencies\n");
> return(0);
> }
> diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
> index 2f3c450..0727095 100644
> --- a/lib/libalpm/deps.h
> +++ b/lib/libalpm/deps.h
> @@ -48,8 +48,8 @@ void _alpm_depmiss_free(pmdepmissing_t *miss);
> alpm_list_t *_alpm_sortbydeps(alpm_list_t *targets, int reverse);
> 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);
> -int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, alpm_list_t *list,
> - alpm_list_t *remove, alpm_list_t **data);
> +int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg,
> + alpm_list_t **packages, alpm_list_t *remove, alpm_list_t **data);
> int _alpm_dep_edge(pmpkg_t *pkg1, pmpkg_t *pkg2);
> pmdepend_t *_alpm_splitdep(const char *depstring);
> pmpkg_t *_alpm_find_dep_satisfier(alpm_list_t *pkgs, pmdepend_t *dep);
> diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c
> index b458874..5e5ca92 100644
> --- a/lib/libalpm/sync.c
> +++ b/lib/libalpm/sync.c
> @@ -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 *list = NULL, *remove = NULL; /* allow checkdeps usage with trans->packages */
> + alpm_list_t *unresolvable = NULL;
> alpm_list_t *i, *j;
> 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;
> }
>
> - for(i = trans->packages; i; i = i->next) {
> - pmsyncpkg_t *sync = i->data;
> - list = alpm_list_add(list, sync->pkg);
> - }
> -
> - if(!(trans->flags & PM_TRANS_FLAG_NODEPS)) {
> - /* store a pointer to the last original target so we can tell what was
> - * pulled by resolvedeps */
> - alpm_list_t *pulled = alpm_list_last(list);
> + if(trans->flags & PM_TRANS_FLAG_NODEPS) {
> + for(i = trans->packages; i; i = i->next) {
> + pmsyncpkg_t *sync = i->data;
> + list = alpm_list_add(list, sync->pkg);
> + }
> + } else {
> + /* Build up list by repeatedly resolving each transaction package */
> /* Resolve targets dependencies */
> EVENT(trans, PM_TRANS_EVT_RESOLVEDEPS_START, NULL, NULL);
> _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 */
> ret = -1;
> 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;
> + 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);
> if(sync == NULL) {
> ret = -1;
> @@ -627,6 +651,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync
> cleanup:
> alpm_list_free(list);
> alpm_list_free(remove);
> + alpm_list_free(unresolvable);
>
> return(ret);
> }
> --
> 1.6.1
>
> _______________________________________________
> pacman-dev mailing list
> pacman-dev at archlinux.org
> http://www.archlinux.org/mailman/listinfo/pacman-dev
>
More information about the pacman-dev
mailing list