index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | lib/libalpm/alpm.h | 1 | ||||
-rw-r--r-- | lib/libalpm/deps.c | 38 | ||||
-rw-r--r-- | src/pacman/callback.c | 13 | ||||
-rw-r--r-- | src/pacman/util.c | 55 | ||||
-rw-r--r-- | src/pacman/util.h | 2 | ||||
-rw-r--r-- | test/pacman/tests/provision002.py | 2 | ||||
-rw-r--r-- | test/pacman/tests/provision003.py | 2 |
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 95482f07..6724bf78 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -383,6 +383,7 @@ typedef enum _pmtransconv_t { PM_TRANS_CONV_CORRUPTED_PKG = (1 << 3), PM_TRANS_CONV_LOCAL_NEWER = (1 << 4), PM_TRANS_CONV_REMOVE_PKGS = (1 << 5), + PM_TRANS_CONV_SELECT_PROVIDER = (1 << 6), } pmtransconv_t; /* Transaction Progress */ diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index a7203b4b..28a51bcf 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -511,6 +511,10 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, { alpm_list_t *i, *j; int ignored = 0; + + alpm_list_t *providers = NULL; + int count; + /* 1. literals */ for(i = dbs; i; i = i->next) { pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); @@ -550,12 +554,40 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, continue; } } - _alpm_log(PM_LOG_WARNING, _("provider package was selected (%s provides %s)\n"), - pkg->name, dep->name); - return(pkg); + _alpm_log(PM_LOG_DEBUG, "provider found (%s provides %s)\n", + pkg->name, dep->name); + providers = alpm_list_add(providers, pkg); + /* keep looking for other providers in the all dbs */ } } } + + /* first check if one provider is already installed locally */ + for(i = providers; i; i = i->next) { + pmpkg_t *pkg = i->data; + if (_alpm_pkg_find(_alpm_db_get_pkgcache(handle->db_local), pkg->name)) { + alpm_list_free(providers); + return(pkg); + } + } + count = alpm_list_count(providers); + if (count >= 1) { + /* default to first provider if there is no QUESTION callback */ + int index = 0; + if(count > 1) { + /* if there is more than one provider, we ask the user */ + QUESTION(handle->trans, PM_TRANS_CONV_SELECT_PROVIDER, + providers, dep, NULL, &index); + } + if(index >= 0 && index < count) { + pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index)); + alpm_list_free(providers); + return(pkg); + } + alpm_list_free(providers); + providers = NULL; + } + if(ignored) { /* resolvedeps will override these */ pm_errno = PM_ERR_PKG_IGNORED; } else { diff --git a/src/pacman/callback.c b/src/pacman/callback.c index e3feea16..43c56d00 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -302,6 +302,19 @@ void cb_trans_conv(pmtransconv_t event, void *data1, void *data2, alpm_list_free(namelist); } break; + case PM_TRANS_CONV_SELECT_PROVIDER: + { + alpm_list_t *providers = (alpm_list_t *)data1; + int count = alpm_list_count(providers); + char *depstring = alpm_dep_compute_string((pmdepend_t *)data2); + printf(_(":: There are %d providers available for %s:\n"), count, + depstring); + free(depstring); + select_display(providers); + printf("\n"); + *response = select_question(count); + } + break; case PM_TRANS_CONV_LOCAL_NEWER: if(!config->op_s_downloadonly) { *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), diff --git a/src/pacman/util.c b/src/pacman/util.c index 0377bf79..133dccc2 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -677,6 +677,61 @@ void display_optdepends(pmpkg_t *pkg) } } +void select_display(const alpm_list_t *pkglist) +{ + const alpm_list_t *i; + int nth = 1; + alpm_list_t *list = NULL; + char *string = NULL; + + for (i = pkglist; i; i = i->next) { + string = NULL; + pm_asprintf(&string, "%d) %s", nth, alpm_pkg_get_name(i->data)); + list = alpm_list_add(list, string); + nth++; + } + list_display(" ", list); + FREELIST(list); +} + +int select_question(int count) +{ + char response[32]; + FILE *stream; + int preset = 1; + + if(config->noconfirm) { + stream = stdout; + } else { + /* Use stderr so questions are always displayed when redirecting output */ + stream = stderr; + } + + fprintf(stream, _("Enter a number (default=%d)"), preset); + fprintf(stream, ": "); + + if(config->noconfirm) { + fprintf(stream, "\n"); + return(preset-1); + } + + if(fgets(response, sizeof(response), stdin)) { + strtrim(response); + if(strlen(response) > 0) { + char *endptr = NULL; + int n = strtol(response, &endptr, 10); + if(*endptr == '\0' && n >= 1 && n <= count) { + return(n-1); + } else { + fprintf(stream, _("Invalid number: %s\n"), response); + return(-1); + } + } + } + return(preset-1); +} + + /* presents a prompt and gets a Y/N answer */ static int question(short preset, char *fmt, va_list args) { diff --git a/src/pacman/util.h b/src/pacman/util.h index 78fe5b59..399f9bc8 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -59,6 +59,8 @@ int str_cmp(const void *s1, const void *s2); void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg); void display_optdepends(pmpkg_t *pkg); void print_packages(const alpm_list_t *packages); +void select_display(const alpm_list_t *pkglist); +int select_question(int count); int yesno(char *fmt, ...); int noyes(char *fmt, ...); int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3))); diff --git a/test/pacman/tests/provision002.py b/test/pacman/tests/provision002.py index 49b88a18..46deb1da 100644 --- a/test/pacman/tests/provision002.py +++ b/test/pacman/tests/provision002.py @@ -18,5 +18,3 @@ self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") self.addrule("PKG_VERSION=pkg2|1.0-2") - -self.expectfailure = True diff --git a/test/pacman/tests/provision003.py b/test/pacman/tests/provision003.py index 9308be6e..08647501 100644 --- a/test/pacman/tests/provision003.py +++ b/test/pacman/tests/provision003.py @@ -19,5 +19,3 @@ self.addrule("PACMAN_RETCODE=0") self.addrule("!PKG_EXIST=pkg1") self.addrule("PKG_EXIST=pkg2") self.addrule("PKG_VERSION=pkg2|1.0-2") - -self.expectfailure = True |