[pacman-dev] [PATCH 1/3] Internal code reorganization in preparation for changes to package
From: Bryan Ischo <bryan@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@ischo.com> --- 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
From: Bryan Ischo <bryan@ischo.com> Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/alpm.h | 3 ++- lib/libalpm/deps.c | 2 +- lib/libalpm/sync.c | 23 ++++++++++++++++++----- pactest/tests/provision020.py | 2 +- pactest/tests/provision022.py | 2 +- pactest/tests/sync1008.py | 2 +- pactest/tests/sync300.py | 2 +- src/pacman/callback.c | 25 +++++++++++++++++++++++++ 8 files changed, 50 insertions(+), 11 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7b7ca4e..3836d60 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t; /* Transaction Progress */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index da21087..8bec4c0 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -609,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); - _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), + _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), missdepstring, tpkg->name); free(missdepstring); if(data) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 5e5ca92..ea903f4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -442,12 +442,25 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync dependencies not already on the list */ } - /* If there were unresolvable top-level packages, fail the - transaction. */ + /* If there were unresolvable top-level packages, prompt the user to + see if they'd like to ignore them rather than failing the sync */ if(unresolvable != NULL) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; + int remove_unresolvable = 0; + QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); + if (remove_unresolvable) { + /* User wants to remove the unresolvable packages from the + transaction, so simply drop the unresolvable list. The + packages will be removed from the actual transaction when + the transaction packages are replaced with a + dependency-reordered list below */ + alpm_list_free(unresolvable); + unresolvable = NULL; + } + else { + /* pm_errno is set by resolvedeps */ + ret = -1; + goto cleanup; + } } /* Add all packages which were "pulled" (i.e. weren't already in the diff --git a/pactest/tests/provision020.py b/pactest/tests/provision020.py index 7cb0a01..c9c0ac3 100644 --- a/pactest/tests/provision020.py +++ b/pactest/tests/provision020.py @@ -10,6 +10,6 @@ self.args = "-S %s" % p.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/provision022.py b/pactest/tests/provision022.py index 4883d42..190a8b6 100644 --- a/pactest/tests/provision022.py +++ b/pactest/tests/provision022.py @@ -10,6 +10,6 @@ self.args = "-S %s" % p.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/sync1008.py b/pactest/tests/sync1008.py index a606459..90c61df 100644 --- a/pactest/tests/sync1008.py +++ b/pactest/tests/sync1008.py @@ -14,6 +14,6 @@ self.args = "-S pkg" -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg") self.addrule("!PKG_EXIST=cpkg") diff --git a/pactest/tests/sync300.py b/pactest/tests/sync300.py index 31b520a..36d6758 100644 --- a/pactest/tests/sync300.py +++ b/pactest/tests/sync300.py @@ -9,6 +9,6 @@ self.args = "-S %s" % sp1.name -self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 6e7930c..1e2bff3 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -270,6 +270,31 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, (char *)data2, (char *)data2); break; + case PM_TRANS_CONV_REMOVE_PKGS: + { + /* Allocate a buffer big enough to hold all of the + package names */ + char *packagenames; + alpm_list_t *unresolved = (alpm_list_t *) data1; + alpm_list_t *i; + int len = 1, /* for trailing \0 */ where = 0, count = 0; + for (i = unresolved; i; i = i->next) { + count += 1; + len += 3 /* for \t, comma, and \n */ + + strlen(alpm_pkg_get_name(i->data)); + } + packagenames = (char *) malloc(len); + for (i = unresolved; i; i = i->next) { + where += snprintf(&(packagenames[where]), len - where, "\t%s%s\n", + alpm_pkg_get_name(i->data), (i->next) ? "," : ""); + } + *response = yesno(_(":: the following package%s cannot be upgraded due to unresolvable " + "dependencies:\n%s\nDo you want to skip %s package%s for this upgrade?"), + (count > 1) ? "s" : "", packagenames, (count > 1) ? "these" : "this", + (count > 1) ? "s" : ""); + free(packagenames); + } + break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), -- 1.6.1
From: Bryan Ischo <bryan@ischo.com> This eliminates many unnecessary prompts when IgnorePkg/IgnoreGroup is used. Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/deps.c | 20 +++++++++++------- lib/libalpm/deps.h | 2 +- lib/libalpm/sync.c | 4 +- pactest/tests/ignore001.py | 17 ++++++++++++++++ pactest/tests/ignore002.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore003.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore004.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ pactest/tests/ignore005.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ src/pacman/callback.c | 11 +-------- 9 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 pactest/tests/ignore001.py create mode 100644 pactest/tests/ignore002.py create mode 100644 pactest/tests/ignore003.py create mode 100644 pactest/tests/ignore004.py create mode 100644 pactest/tests/ignore005.py diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 8bec4c0..313100b 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -505,7 +505,7 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) } /* helper function for resolvedeps: search for dep satisfier in dbs */ -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, int prompt_for_unignore) { alpm_list_t *i, *j; /* 1. literals */ @@ -513,9 +513,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); if(pkg && alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + int install = 0; + if (prompt_for_unignore) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + NULL, NULL, &install); + } if(!install) { continue; } @@ -530,9 +532,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + int install = 0; + if (prompt_for_unignore) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + NULL, NULL, &install); + } if(!install) { continue; } @@ -605,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, continue; } /* find a satisfier package in the given repositories */ - pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, tpkg); + pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, 0); if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 0727095..97b0538 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -47,7 +47,7 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep, 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); +pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt_for_unignore); 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); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index ea903f4..6e7c709 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -285,12 +285,12 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1); } dep = _alpm_splitdep(targ); - spkg = _alpm_resolvedep(dep, dbs, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs, NULL, 1); _alpm_dep_free(dep); alpm_list_free(dbs); } else { dep = _alpm_splitdep(targline); - spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1); _alpm_dep_free(dep); } FREE(targline); diff --git a/pactest/tests/ignore001.py b/pactest/tests/ignore001.py new file mode 100644 index 0000000..bf8e8c6 --- /dev/null +++ b/pactest/tests/ignore001.py @@ -0,0 +1,17 @@ +self.description = "Sync with irrelevent ignored packages" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +self.option["IgnorePkg"] = ["irrelevent"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|2.0-1") diff --git a/pactest/tests/ignore002.py b/pactest/tests/ignore002.py new file mode 100644 index 0000000..b64b70a --- /dev/null +++ b/pactest/tests/ignore002.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevent ignored packages" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore003.py b/pactest/tests/ignore003.py new file mode 100644 index 0000000..f7c1658 --- /dev/null +++ b/pactest/tests/ignore003.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevent ignored packages and dependency loop" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1", "package4=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore004.py b/pactest/tests/ignore004.py new file mode 100644 index 0000000..fff12f6 --- /dev/null +++ b/pactest/tests/ignore004.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be ignored" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|1.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|1.0-1") +self.addrule("PKG_VERSION=packageA5|1.0-1") diff --git a/pactest/tests/ignore005.py b/pactest/tests/ignore005.py new file mode 100644 index 0000000..1957ea4 --- /dev/null +++ b/pactest/tests/ignore005.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be included" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2>=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2>=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1 packageA2" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|2.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|2.0-1") +self.addrule("PKG_VERSION=packageA5|2.0-1") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 1e2bff3..65b5ab7 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -248,15 +248,8 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, { switch(event) { case PM_TRANS_CONV_INSTALL_IGNOREPKG: - if(data2) { - /* TODO we take this route based on data2 being not null? WTF */ - *response = yesno(_(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data2), - alpm_pkg_get_name(data1)); - } else { - *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data1)); - } + *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), + alpm_pkg_get_name(data1)); break; case PM_TRANS_CONV_REPLACE_PKG: *response = yesno(_(":: Replace %s with %s/%s?"), -- 1.6.1
From: Bryan Ischo <bryan@ischo.com>
This eliminates many unnecessary prompts when IgnorePkg/IgnoreGroup is used.
Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/deps.c | 20 +++++++++++------- lib/libalpm/deps.h | 2 +- lib/libalpm/sync.c | 4 +- pactest/tests/ignore001.py | 17 ++++++++++++++++ pactest/tests/ignore002.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore003.py | 35 +++++++++++++++++++++++++++++++++ pactest/tests/ignore004.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ pactest/tests/ignore005.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ src/pacman/callback.c | 11 +-------- 9 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 pactest/tests/ignore001.py create mode 100644 pactest/tests/ignore002.py create mode 100644 pactest/tests/ignore003.py create mode 100644 pactest/tests/ignore004.py create mode 100644 pactest/tests/ignore005.py
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 8bec4c0..313100b 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -505,7 +505,7 @@ void _alpm_recursedeps(pmdb_t *db, alpm_list_t *targs, int include_explicit) }
/* helper function for resolvedeps: search for dep satisfier in dbs */ -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, int prompt_for_unignore) It might be helpful if we threw some doxygen block commenting on this guy, and then shortened the last argument to just "prompt", rather
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote: than this rather long variable name. You can wrap the line too. :P
{ alpm_list_t *i, *j; /* 1. literals */ @@ -513,9 +513,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); if(pkg && alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + int install = 0; + if (prompt_for_unignore) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + NULL, NULL, &install); + } if(!install) { continue; } @@ -530,9 +532,11 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *exclud if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { - int install; - QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, - tpkg, NULL, &install); + int install = 0; + if (prompt_for_unignore) { + QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, + NULL, NULL, &install); + } if(!install) { continue; } @@ -605,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, continue; } /* find a satisfier package in the given repositories */ - pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, tpkg); + pmpkg_t *spkg = _alpm_resolvedep(missdep, dbs_sync, *packages, 0); if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h index 0727095..97b0538 100644 --- a/lib/libalpm/deps.h +++ b/lib/libalpm/deps.h @@ -47,7 +47,7 @@ pmdepmissing_t *_alpm_depmiss_new(const char *target, pmdepend_t *dep, 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); +pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt_for_unignore); 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); diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index ea903f4..6e7c709 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -285,12 +285,12 @@ int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sy RET_ERR(PM_ERR_PKG_REPO_NOT_FOUND, -1); } dep = _alpm_splitdep(targ); - spkg = _alpm_resolvedep(dep, dbs, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs, NULL, 1); _alpm_dep_free(dep); alpm_list_free(dbs); } else { dep = _alpm_splitdep(targline); - spkg = _alpm_resolvedep(dep, dbs_sync, NULL, NULL); + spkg = _alpm_resolvedep(dep, dbs_sync, NULL, 1); _alpm_dep_free(dep); } FREE(targline); diff --git a/pactest/tests/ignore001.py b/pactest/tests/ignore001.py new file mode 100644 index 0000000..bf8e8c6 --- /dev/null +++ b/pactest/tests/ignore001.py @@ -0,0 +1,17 @@ +self.description = "Sync with irrelevent ignored packages" s/relevent/relevant/g in your descriptions. Spelling. + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +self.option["IgnorePkg"] = ["irrelevent"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|2.0-1") diff --git a/pactest/tests/ignore002.py b/pactest/tests/ignore002.py new file mode 100644 index 0000000..b64b70a --- /dev/null +++ b/pactest/tests/ignore002.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevent ignored packages" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore003.py b/pactest/tests/ignore003.py new file mode 100644 index 0000000..f7c1658 --- /dev/null +++ b/pactest/tests/ignore003.py @@ -0,0 +1,35 @@ +self.description = "Sync with relevent ignored packages and dependency loop" + +package1 = pmpkg("package1") +self.addpkg2db("local", package1) + +package2 = pmpkg("package2") +self.addpkg2db("local", package2) + +package3 = pmpkg("package3") +package3.depends = ["package2=1.0-1"] +self.addpkg2db("local", package3) + +package4 = pmpkg("package4") +package4.depends = ["package3=1.0-1"] +self.addpkg2db("local", package4) + +package2up = pmpkg("package2", "2.0-1") +self.addpkg2db("sync", package2up) + +package3up = pmpkg("package3", "2.0-1") +package3up.depends = ["package2=2.0-1", "package4=2.0-1"] +self.addpkg2db("sync", package3up) + +package4up = pmpkg("package4", "2.0-1") +package4up.depends = ["package3=2.0-1"] +self.addpkg2db("sync", package4up) + +self.option["IgnorePkg"] = ["package2"] +self.args = "-Su" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=package1|1.0-1") +self.addrule("PKG_VERSION=package2|1.0-1") +self.addrule("PKG_VERSION=package3|1.0-1") +self.addrule("PKG_VERSION=package4|1.0-1") diff --git a/pactest/tests/ignore004.py b/pactest/tests/ignore004.py new file mode 100644 index 0000000..fff12f6 --- /dev/null +++ b/pactest/tests/ignore004.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be ignored" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|1.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|1.0-1") +self.addrule("PKG_VERSION=packageA5|1.0-1") diff --git a/pactest/tests/ignore005.py b/pactest/tests/ignore005.py new file mode 100644 index 0000000..1957ea4 --- /dev/null +++ b/pactest/tests/ignore005.py @@ -0,0 +1,46 @@ +self.description = "Sync with ignore causing top-level to be included" + +packageA1 = pmpkg("packageA1") +packageA1.depends = ["packageA2>=1.0-1", "packageA3=1.0-1"]; +self.addpkg2db("local", packageA1) + +packageA2 = pmpkg("packageA2") +packageA2.depends = ["packageA4=1.0-1", "packageA5=1.0-1"]; +self.addpkg2db("local", packageA2) + +packageA3 = pmpkg("packageA3") +self.addpkg2db("local", packageA3) + +packageA4 = pmpkg("packageA4") +self.addpkg2db("local", packageA4) + +packageA5 = pmpkg("packageA5") +self.addpkg2db("local", packageA5) + +packageA1up = pmpkg("packageA1", "2.0-1") +packageA1up.depends = ["packageA2>=2.0-1", "packageA3=2.0-1"]; +self.addpkg2db("sync", packageA1up) + +packageA2up = pmpkg("packageA2", "2.0-1") +packageA2up.depends = ["packageA4=2.0-1", "packageA5=2.0-1"]; +self.addpkg2db("sync", packageA2up) + +packageA3up = pmpkg("packageA3", "2.0-1") +self.addpkg2db("sync", packageA3up) + +packageA4up = pmpkg("packageA4", "2.0-1") +self.addpkg2db("sync", packageA4up) + +packageA5up = pmpkg("packageA5", "2.0-1") +self.addpkg2db("sync", packageA5up) + + +self.option["IgnorePkg"] = ["packageA3"] +self.args = "-S packageA1 packageA2" + +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|2.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|2.0-1") +self.addrule("PKG_VERSION=packageA5|2.0-1")
Are there any pactests that could be written that have pacman returning 1? Or does that just not happen anymore with this new machinery (or at least isn't pactest-able)?
diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 1e2bff3..65b5ab7 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -248,15 +248,8 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, { switch(event) { case PM_TRANS_CONV_INSTALL_IGNOREPKG: - if(data2) { - /* TODO we take this route based on data2 being not null? WTF */ - *response = yesno(_(":: %s requires installing %s from IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data2), - alpm_pkg_get_name(data1)); - } else { - *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), - alpm_pkg_get_name(data1)); - } + *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), + alpm_pkg_get_name(data1)); Nice, you killed one of my longstanding comments!
break; case PM_TRANS_CONV_REPLACE_PKG: *response = yesno(_(":: Replace %s with %s/%s?"), -- 1.6.1
Dan McGee wrote:
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
/* helper function for resolvedeps: search for dep satisfier in dbs */ -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, int prompt_for_unignore)
It might be helpful if we threw some doxygen block commenting on this guy, and then shortened the last argument to just "prompt", rather than this rather long variable name. You can wrap the line too. :P
OK.
diff --git a/pactest/tests/ignore001.py b/pactest/tests/ignore001.py new file mode 100644 index 0000000..bf8e8c6 --- /dev/null +++ b/pactest/tests/ignore001.py @@ -0,0 +1,17 @@ +self.description = "Sync with irrelevent ignored packages"
s/relevent/relevant/g in your descriptions. Spelling.
Well that seems pretty irrelevant, but I'll do as you ask :) Although I do think that 'irrelevent' makes more sense: ir = not, rel = related to, event = this event, i.e. not related to this event :)
+ +self.addrule("PACMAN_RETCODE=0") +self.addrule("PKG_VERSION=packageA1|1.0-1") +self.addrule("PKG_VERSION=packageA2|2.0-1") +self.addrule("PKG_VERSION=packageA3|1.0-1") +self.addrule("PKG_VERSION=packageA4|2.0-1") +self.addrule("PKG_VERSION=packageA5|2.0-1")
Are there any pactests that could be written that have pacman returning 1? Or does that just not happen anymore with this new machinery (or at least isn't pactest-able)?
Yes, plenty of tests still return pacman error codes. The only ones that don't are the ones that have unresolvable dependencies, and thus have their default "cancel this operation" prompt option chosen. But other kids of failures, will certainly continue to return an error code. One thing that could be done is to make pactest able to answer prompts as instructed by the individual test scripts (maybe there is already a way to do this and I missed it?), and have some/all of these answer the new prompt so as *not* to cancel the transaction, thus instituting the same pacman behavor for all of these tests as before my changes (returning error codes and whatever other side effects). However, I am not a python programmer and I didn't feel like coming up to speed on python just to enhance pactest in this way so I didn't do that ...
- /* TODO we take this route based on data2 being not null? WTF */ Nice, you killed one of my longstanding comments!
Yes, I have to admit, it felt very satisfying ... nothing like obsoleting a WTF?!? Thanks, Bryan
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote: I think your subject got cut off. Git limits you to 76 or so characters, so maybe shorten it up and add something to the body? Anyway, I realized I never really reviewed this guy (really sorry about that), and there are a few minor issues with it...
From: Bryan Ischo <bryan@ischo.com>
Signed-off-by: Bryan Ischo <bryan@ischo.com> --- lib/libalpm/alpm.h | 3 ++- lib/libalpm/deps.c | 2 +- lib/libalpm/sync.c | 23 ++++++++++++++++++----- pactest/tests/provision020.py | 2 +- pactest/tests/provision022.py | 2 +- pactest/tests/sync1008.py | 2 +- pactest/tests/sync300.py | 2 +- src/pacman/callback.c | 25 +++++++++++++++++++++++++ 8 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 7b7ca4e..3836d60 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -371,7 +371,8 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_REPLACE_PKG = 0x02, PM_TRANS_CONV_CONFLICT_PKG = 0x04, PM_TRANS_CONV_CORRUPTED_PKG = 0x08, - PM_TRANS_CONV_LOCAL_NEWER = 0x10 + PM_TRANS_CONV_LOCAL_NEWER = 0x10, + PM_TRANS_CONV_REMOVE_PKGS = 0x20, } pmtransconv_t;
/* Transaction Progress */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index da21087..8bec4c0 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -609,7 +609,7 @@ int _alpm_resolvedeps(pmdb_t *local, alpm_list_t *dbs_sync, pmpkg_t *pkg, if(!spkg) { pm_errno = PM_ERR_UNSATISFIED_DEPS; char *missdepstring = alpm_dep_compute_string(missdep); - _alpm_log(PM_LOG_ERROR, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), + _alpm_log(PM_LOG_WARNING, _("cannot resolve \"%s\", a dependency of \"%s\"\n"), missdepstring, tpkg->name); free(missdepstring); if(data) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 5e5ca92..ea903f4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -442,12 +442,25 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync dependencies not already on the list */ }
- /* If there were unresolvable top-level packages, fail the - transaction. */ + /* If there were unresolvable top-level packages, prompt the user to + see if they'd like to ignore them rather than failing the sync */ if(unresolvable != NULL) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; + int remove_unresolvable = 0; + QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable); You can wrap this if you want, ignore my earlier weird recommendations. + if (remove_unresolvable) { + /* User wants to remove the unresolvable packages from the + transaction, so simply drop the unresolvable list. The + packages will be removed from the actual transaction when + the transaction packages are replaced with a + dependency-reordered list below */ + alpm_list_free(unresolvable); + unresolvable = NULL; + } + else { + /* pm_errno is set by resolvedeps */ + ret = -1; + goto cleanup; + } }
/* Add all packages which were "pulled" (i.e. weren't already in the diff --git a/pactest/tests/provision020.py b/pactest/tests/provision020.py index 7cb0a01..c9c0ac3 100644 --- a/pactest/tests/provision020.py +++ b/pactest/tests/provision020.py @@ -10,6 +10,6 @@
self.args = "-S %s" % p.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") I think I understand why all these changed from 1 to 0, but isn't it a bit odd that some of these "success" codes now result from pacman doing nothing in the --noconfirm case? I guess a little explanation for me might be in order, it might just be me that is confused. Putting a note in the commit message might be helpful, e.g. "The return codes for several pacman commands are now true because <reason>..."
self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/provision022.py b/pactest/tests/provision022.py index 4883d42..190a8b6 100644 --- a/pactest/tests/provision022.py +++ b/pactest/tests/provision022.py @@ -10,6 +10,6 @@
self.args = "-S %s" % p.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") diff --git a/pactest/tests/sync1008.py b/pactest/tests/sync1008.py index a606459..90c61df 100644 --- a/pactest/tests/sync1008.py +++ b/pactest/tests/sync1008.py @@ -14,6 +14,6 @@
self.args = "-S pkg"
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg") self.addrule("!PKG_EXIST=cpkg") diff --git a/pactest/tests/sync300.py b/pactest/tests/sync300.py index 31b520a..36d6758 100644 --- a/pactest/tests/sync300.py +++ b/pactest/tests/sync300.py @@ -9,6 +9,6 @@
self.args = "-S %s" % sp1.name
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("!PKG_EXIST=pkg2") diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 6e7930c..1e2bff3 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -270,6 +270,31 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, (char *)data2, (char *)data2); break; + case PM_TRANS_CONV_REMOVE_PKGS: + { + /* Allocate a buffer big enough to hold all of the + package names */ + char *packagenames; + alpm_list_t *unresolved = (alpm_list_t *) data1; + alpm_list_t *i; + int len = 1, /* for trailing \0 */ where = 0, count = 0; + for (i = unresolved; i; i = i->next) { + count += 1; + len += 3 /* for \t, comma, and \n */ + + strlen(alpm_pkg_get_name(i->data)); + } + packagenames = (char *) malloc(len); + for (i = unresolved; i; i = i->next) { + where += snprintf(&(packagenames[where]), len - where, "\t%s%s\n", You have trailing whitespace here. See my suggestion about enabling the pre-commit hook. + alpm_pkg_get_name(i->data), (i->next) ? "," : ""); + } I really don't like reinventing the wheel here. I realize that list_display() in util.c only takes an alpm_list_t of strings right now, so that doesn't perfectly fit the bill, but I would rather we use that if possible. What about something like the following (psuedo-C):
+ *response = yesno(_(":: the following package%s cannot be upgraded due to unresolvable " + "dependencies:\n%s\nDo you want to skip %s package%s for this upgrade?"), + (count > 1) ? "s" : "", packagenames, (count > 1) ? "these" : "this", + (count > 1) ? "s" : ""); These tricks are cool until translators are involved. You can't do
namelist = NULL; for (i = unresolved; i; i = i->next) { namelist = alpm_list_add(namelist, alpm_pkg_get_name(i->data); } .... list_display(" ", namelist); .... alpm_list_free(namelist); this in an i18n application- you are going to have to switch on the whole word, or something. I'd rather just put the string "package(s)" in there.
+ free(packagenames); + } + break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), -- 1.6.1
If you can't get to these changes, then I will sometime as I feel I owe you one for being so late on reviewing these. -Dan
Dan McGee wrote:
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote: I think your subject got cut off. Git limits you to 76 or so characters, so maybe shorten it up and add something to the body?
OK.
Anyway, I realized I never really reviewed this guy (really sorry about that), and there are a few minor issues with it...
Here we go again :)
if(unresolvable != NULL) { - /* pm_errno is set by resolvedeps */ - ret = -1; - goto cleanup; + int remove_unresolvable = 0; + QUESTION(handle->trans, PM_TRANS_CONV_REMOVE_PKGS, unresolvable, NULL, NULL, &remove_unresolvable);
You can wrap this if you want, ignore my earlier weird recommendations.
Are you talking about the line length issues you pointed out before? And are you saying here that it's OK to wrap the lines to fit 80 columns in my editor, rather than trying to match another environment? I think that's what you're saying. I will henceforth wrap wherever makes the most sense for me. You hadn't commented on my comments before, but I think you agree that the pacman code style guidelines unfortunately cause problems like these. Using tabs for indentation only works for unbroken lines; as soon as a line is broken and the second half needs to be lined up on a non-tab-boundary (with function arguments on the second line lining up with those on the first, for example), then it all goes to pot, since the number of tabs/spaces needed to make these broken lines line up properly is entirely dependent on your tab width. The same problem is true for breaking lines to avoid going over 80 columns; where 80 columns is for a given line depends on your tab width when you use tab indenting. I use width 4 tab stops, which I think is just about as "standard" as you can get with tab widths, but if you're using width 2 tab stops, then you can fit quite a bit more on deeply nested lines than I can.
-self.addrule("PACMAN_RETCODE=1") +self.addrule("PACMAN_RETCODE=0")
I think I understand why all these changed from 1 to 0, but isn't it a bit odd that some of these "success" codes now result from pacman doing nothing in the --noconfirm case? I guess a little explanation for me might be in order, it might just be me that is confused. Putting a note in the commit message might be helpful, e.g. "The return codes for several pacman commands are now true because <reason>..."
What's happening here is that many of the tests used to test what happens when a package is missing and the transaction must fail because of that. Prior to my changes, pacman would issue an error message and exit with an error code because you asked it to do something that it can't do. After my change, pacman issues a prompt asking if you'd like to cancel the transaction, or cull out packages which can't be upgraded from the transaction. Whichever option you choose, pacman returns a success code since it didn't really encounter an error, it encountered additional instructions from the user which resulted in a no-op. That's my reasoning, anyway. If you think that pacman should still return an error in the first case, because the user's "original" intentions were thwarted, even though they interactively chose to cancel the transaction, then I could certainly see the logic there and would make that change. Also, the pactest stuff doesn't seem to have a way that I could find to answer any prompts that pacman issues, so the default response is always taken, which in the case of these tests, is the "cancel" option. The result in terms of what pacman actually does is the same as it used to be before my change, the only difference being that pacman now returns 0 instead of an error code. Like I said, I can make pacman return an error if the user cancels the transaction interactively, which, since this is the choice always taken by the pactest script, will result in an error the same way that these tests used to. Would you like me to do this?
You have trailing whitespace here. See my suggestion about enabling the pre-commit hook.
Thanks ... I looked for the hook but can't find it. Any hints? Is the whitespace functionality included in the pre-commit.sample file? I didn't see it in there, but maybe it's encapsulated in the behavior of the git diff-index --check command run by the script.
+ alpm_pkg_get_name(i->data), (i->next) ? "," : ""); + }
I really don't like reinventing the wheel here. I realize that list_display() in util.c only takes an alpm_list_t of strings right now, so that doesn't perfectly fit the bill, but I would rather we use that if possible. What about something like the following (psuedo-C):
namelist = NULL; for (i = unresolved; i; i = i->next) { namelist = alpm_list_add(namelist, alpm_pkg_get_name(i->data); } .... list_display(" ", namelist); .... alpm_list_free(namelist);
OK, I'll do it.
+ *response = yesno(_(":: the following package%s cannot be upgraded due to unresolvable " + "dependencies:\n%s\nDo you want to skip %s package%s for this upgrade?"), + (count > 1) ? "s" : "", packagenames, (count > 1) ? "these" : "this", + (count > 1) ? "s" : "");
These tricks are cool until translators are involved. You can't do this in an i18n application- you are going to have to switch on the whole word, or something. I'd rather just put the string "package(s)" in there.
OK.
+ free(packagenames); + } + break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), -- 1.6.1
If you can't get to these changes, then I will sometime as I feel I owe you one for being so late on reviewing these.
I will do it. Should have it done soon. I'm assuming that you already took my first patch, and that I only need to fix up patches 2 and 3 ... Thanks, Bryan
Bryan Ischo wrote:
Thanks ... I looked for the hook but can't find it. Any hints? Is the whitespace functionality included in the pre-commit.sample file? I didn't see it in there, but maybe it's encapsulated in the behavior of the git diff-index --check command run by the script.
Eh, forget I asked. I took the 2 seconds necessary to actually consult the man page for 'git diff-index' and found the answer to my question: yes, it tests for whitespace at the end of a line. Thanks, Bryan
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
From: Bryan Ischo <bryan@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@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@archlinux.org http://www.archlinux.org/mailman/listinfo/pacman-dev
Dan McGee wrote:
On Mon, Jan 26, 2009 at 6:48 AM, Bryan Ischo <bji-keyword-pacman.3644cb@www.ischo.com> wrote:
From: Bryan Ischo <bryan@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@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.
Will do. Thanks for taking the patches. Best wishes, Bryan
participants (2)
-
Bryan Ischo
-
Dan McGee