[pacman-dev] [PATCH 13/14] Add option to ask which optdeps to install
Benedikt Morbach
benedikt.morbach at googlemail.com
Wed Nov 23 10:51:27 EST 2011
Signed-off-by: Benedikt Morbach <benedikt.morbach at googlemail.com>
---
doc/pacman.conf.5.txt | 7 ++++-
etc/pacman.conf.in | 2 +-
src/pacman/conf.c | 2 +
src/pacman/conf.h | 3 +-
src/pacman/sync.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++-
src/pacman/util.c | 59 ++++++++++++++++++++++++++++------------
src/pacman/util.h | 1 +
7 files changed, 122 insertions(+), 22 deletions(-)
diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index 985f22d..7e9017a 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -160,11 +160,16 @@ Options
packages are only cleaned if not installed locally and not present in any
known sync database.
-*HandleOptdeps =* ShowAll &| Install::
+*HandleOptdeps =* ShowAll &| Install &| Ask::
If set to `ShowAll`, show all optional dependencies on install.
The default is to just show uninstalled optional dependencies.
If set to `Install`, the optional dependencies of all targets are
automatically installed.
+ If set to `Ask`, display a prompt for each target, where the user can select
+ which of the optional dependencies of that target will be installed.
+ Also, the optional dependencies of the targets won't be shown during installation.
+ If `ShowAll` and `Ask` are set, the prompt also shows optional dependencies
+ which are already installed.
*SigLevel =* ...::
Set the default signature verification level. For more information, see
diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in
index bf9f200..889afc3 100644
--- a/etc/pacman.conf.in
+++ b/etc/pacman.conf.in
@@ -36,7 +36,7 @@ Architecture = auto
CheckSpace
#VerbosePkgLists
-#HandleOptdeps = ShowAll Install
+#HandleOptdeps = ShowAll Install Ask
# PGP signature checking
#SigLevel = Optional
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 4d06bfc..1c45a80 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -369,6 +369,8 @@ static int process_handleoptdeps(alpm_list_t *actions) {
config->handleoptdeps |= PM_OPTDEPS_SHOWALL;
} else if(strcmp(action, "Install") == 0) {
config->handleoptdeps |= PM_OPTDEPS_INSTALL;
+ } else if(strcmp(action, "Ask") == 0) {
+ config->handleoptdeps |= PM_OPTDEPS_ASK;
} else {
pm_printf(ALPM_LOG_ERROR, _("invalid action for 'HandleOptdeps' : '%s'\n"),
action);
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 9128c48..71f049e 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -144,7 +144,8 @@ enum {
/* optdepends handling */
enum {
PM_OPTDEPS_SHOWALL = 1,
- PM_OPTDEPS_INSTALL = (1 << 1)
+ PM_OPTDEPS_INSTALL = (1 << 1),
+ PM_OPTDEPS_ASK = (1 << 2)
};
/* global config variable */
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index b9c1901..8fbdf78 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -623,7 +623,75 @@ static int process_pkg(alpm_pkg_t *pkg, int as_dep)
static int process_optdeps(alpm_list_t *dblist, alpm_pkg_t *pkg)
{
- if(config->handleoptdeps & PM_OPTDEPS_INSTALL) {
+ if(config->print == 0 && (config->handleoptdeps & PM_OPTDEPS_ASK)) {
+ alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
+ int retval = 0;
+
+ if(optdeps) {
+ alpm_list_t *i, *depstrings, *optstrings;
+ depstrings = optstrings = NULL;
+
+ if((config->handleoptdeps & PM_OPTDEPS_SHOWALL) == 0) {
+ alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_list_t *pkgcache = alpm_db_get_pkgcache(db_local);
+
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_optdepend_t *optdep = i->data;
+ char *depstring = alpm_dep_compute_string(optdep->depend);
+ if(alpm_find_satisfier(pkgcache, depstring) == NULL) {
+ depstrings = alpm_list_add(depstrings, depstring);
+ optstrings = alpm_list_add(optstrings, alpm_optdep_compute_string(optdep));
+ } else {
+ free(depstring);
+ }
+ }
+ } else {
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_optdepend_t *optdep = i->data;
+ depstrings = alpm_list_add(depstrings, alpm_dep_compute_string(optdep->depend));
+ optstrings = alpm_list_add(optstrings, alpm_optdep_compute_string(optdep));
+ }
+ }
+
+ int count = alpm_list_count(optstrings);
+
+ if(count) {
+ printf(_(":: %s has %d optional dependencies:\n"), alpm_pkg_get_name(pkg), count);
+ select_optdep_display(optstrings);
+
+ char *array = malloc(count);
+ if(!array) {
+ retval = 1;
+ goto cleanup;
+ }
+
+ if(multiselect_question(array, count)) {
+ retval = 1;
+ goto cleanup;
+ }
+
+ int n = 0;
+ for(i = depstrings; i; i = alpm_list_next(i)) {
+ if(array[n++] == 0) { continue; }
+
+ char *depstring = i->data;
+ alpm_pkg_t *pkg = alpm_find_dbs_satisfier(config->handle, dblist, depstring);
+
+ if(process_pkg(pkg, 1) == 1) {
+ retval = 1;
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ free(array);
+ }
+
+ FREELIST(depstrings);
+ FREELIST(optstrings);
+ return retval;
+ }
+ } else if(config->handleoptdeps & PM_OPTDEPS_INSTALL) {
alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
alpm_list_t *i;
diff --git a/src/pacman/util.c b/src/pacman/util.c
index c54975e..8e5e480 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -1235,35 +1235,43 @@ alpm_list_t *optdep_string_list(const alpm_list_t *optlist, int include_installe
void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
{
- alpm_list_t *old, *new, *optdeps, *optstrings;
+ /* don't show optdepends if we already asked for them. '*/
+ if(!((config->handleoptdeps & PM_OPTDEPS_ASK) &&
+ alpm_find_satisfier(alpm_trans_get_add(config->handle), alpm_pkg_get_name(newpkg)))) {
+ alpm_list_t *old, *new, *optdeps, *optstrings;
- old = alpm_pkg_get_optdepends(oldpkg);
- new = alpm_pkg_get_optdepends(newpkg);
- optdeps = alpm_list_diff(new, old, opt_cmp);
+ old = alpm_pkg_get_optdepends(oldpkg);
+ new = alpm_pkg_get_optdepends(newpkg);
+ optdeps = alpm_list_diff(new, old, opt_cmp);
- optstrings = optdep_string_list(optdeps, config->handleoptdeps & PM_OPTDEPS_SHOWALL);
+ optstrings = optdep_string_list(optdeps, config->handleoptdeps & PM_OPTDEPS_SHOWALL);
- if(optstrings) {
- printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
- list_display_linebreak(" ", optstrings);
+ if(optstrings) {
+ printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
+ list_display_linebreak(" ", optstrings);
+ }
+
+ alpm_list_free(optdeps);
+ FREELIST(optstrings);
}
-
- alpm_list_free(optdeps);
- FREELIST(optstrings);
}
void display_optdepends(alpm_pkg_t *pkg)
{
- alpm_list_t *optstrings;
+ /* don't show optdepends if we already asked for them. '*/
+ if(!((config->handleoptdeps & PM_OPTDEPS_ASK) &&
+ alpm_find_satisfier(alpm_trans_get_add(config->handle), alpm_pkg_get_name(pkg)))) {
+ alpm_list_t *optstrings;
- optstrings = optdep_string_list(alpm_pkg_get_optdepends(pkg), config->handleoptdeps & PM_OPTDEPS_SHOWALL);
+ optstrings = optdep_string_list(alpm_pkg_get_optdepends(pkg), config->handleoptdeps & PM_OPTDEPS_SHOWALL);
- if(optstrings) {
- printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
- list_display_linebreak(" ", optstrings);
+ if(optstrings) {
+ printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
+ list_display_linebreak(" ", optstrings);
+ }
+
+ FREELIST(optstrings);
}
-
- FREELIST(optstrings);
}
static void display_repo_list(const char *dbname, alpm_list_t *list)
@@ -1303,6 +1311,21 @@ void select_display(const alpm_list_t *pkglist)
FREELIST(list);
}
+void select_optdep_display(alpm_list_t *optstrings)
+{
+ const alpm_list_t *i;
+ int nth = 1;
+ char number[8]; /* 2 padding left, 2 number, 1 ')', 2 padding right, 1 '\0' */
+
+ for(i = optstrings; i; i = i->next, nth++) {
+ char *str = i->data;
+ if(str) {
+ snprintf(number, 8, " %2d) ", nth);
+ string_display(number, str);
+ }
+ }
+}
+
static int parseindex(char *s, int *val, int min, int max)
{
char *endptr = NULL;
diff --git a/src/pacman/util.h b/src/pacman/util.h
index ffff4b5..0fbc6b9 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -73,6 +73,7 @@ void display_optdepends(alpm_pkg_t *pkg);
alpm_list_t *optdep_string_list(const alpm_list_t *optdeps, int include_installed);
void print_packages(const alpm_list_t *packages);
void select_display(const alpm_list_t *pkglist);
+void select_optdep_display(alpm_list_t *optstrings);
int select_question(int count);
int multiselect_question(char *array, int count);
int yesno(char *fmt, ...);
--
1.7.7.3
More information about the pacman-dev
mailing list