[pacman-dev] [PATCH 04/14] Add option for showing all optdeps again

Benedikt Morbach benedikt.morbach at googlemail.com
Wed Nov 23 10:51:18 EST 2011


This also shows [installing] after the optdep, if it is part of the same
transaction but isn't yet installed

Signed-off-by: Benedikt Morbach <benedikt.morbach at googlemail.com>
---
 doc/pacman.conf.5.txt                        |    4 +++
 etc/pacman.conf.in                           |    2 +
 src/pacman/conf.c                            |   23 +++++++++++++++++
 src/pacman/conf.h                            |    7 +++++
 src/pacman/util.c                            |   35 ++++++++++++++++++++++---
 src/pacman/util.h                            |    1 +
 test/pacman/tests/{sync061.py => sync062.py} |    8 +++--
 7 files changed, 72 insertions(+), 8 deletions(-)
 copy test/pacman/tests/{sync061.py => sync062.py} (65%)

diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index 2c1a24b..7232c8b 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -160,6 +160,10 @@ Options
 	packages are only cleaned if not installed locally and not present in any
 	known sync database.
 
+*HandleOptdeps =* ShowAll::
+	If set to `ShowAll`, show all optional dependencies on install.
+	The default is to just show uninstalled optional dependencies.
+
 *SigLevel =* ...::
 	Set the default signature verification level. For more information, see
 	<<SC,Package and Database Signature Checking>> below.
diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in
index 932140f..a905757 100644
--- a/etc/pacman.conf.in
+++ b/etc/pacman.conf.in
@@ -36,6 +36,8 @@ Architecture = auto
 CheckSpace
 #VerbosePkgLists
 
+#HandleOptdeps = ShowAll
+
 # PGP signature checking
 #SigLevel = Optional
 
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index 5328e7c..715399e 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -361,6 +361,21 @@ static int process_cleanmethods(alpm_list_t *values,
 	return 0;
 }
 
+static int process_handleoptdeps(alpm_list_t *actions) {
+	alpm_list_t *i;
+	for(i = actions; i; i = alpm_list_next(i)) {
+		const char *action = i->data;
+		if(strcmp(action, "ShowAll") == 0) {
+			config->handleoptdeps |= PM_OPTDEPS_SHOWALL;
+		} else {
+			pm_printf(ALPM_LOG_ERROR, _("invalid action for 'HandleOptdeps' : '%s'\n"),
+					action);
+			return 1;
+		}
+	}
+	return 0;
+}
+
 /** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
  * settings. Refactored out of the parseconfig code since all of them did
  * the exact same thing and duplicated code.
@@ -464,6 +479,14 @@ static int _parse_options(const char *key, char *value,
 				return 1;
 			}
 			FREELIST(methods);
+		} else if(strcmp(key, "HandleOptdeps") == 0) {
+			alpm_list_t *actions = NULL;
+			setrepeatingoption(value, "HandleOptdeps", &actions);
+			if(process_handleoptdeps(actions)) {
+				FREELIST(actions);
+				return 1;
+			}
+			FREELIST(actions);
 		} else if(strcmp(key, "SigLevel") == 0) {
 			alpm_list_t *values = NULL;
 			setrepeatingoption(value, "SigLevel", &values);
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index 325fbb6..7ff37ff 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -83,6 +83,8 @@ typedef struct __config_t {
 	unsigned short totaldownload;
 	/* select -Sc behavior */
 	unsigned short cleanmethod;
+	/* wether and how to handle optdeps */
+	unsigned short handleoptdeps;
 	alpm_list_t *holdpkg;
 	alpm_list_t *syncfirst;
 	alpm_list_t *ignorepkg;
@@ -138,6 +140,11 @@ enum {
 	PM_CLEAN_KEEPCUR = (1 << 1)
 };
 
+/* optdepends handling */
+enum {
+	PM_OPTDEPS_SHOWALL = 1
+};
+
 /* global config variable */
 extern config_t *config;
 
diff --git a/src/pacman/util.c b/src/pacman/util.c
index be4647a..1f89663 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -1176,20 +1176,45 @@ static int opt_cmp(const void *o1, const void *o2)
 /** Creates a newly-allocated list of optdepend strings from a list of optdepends.
  * The list must be freed!
  * @param optlist an alpm_list_t of optdepends to turn into a strings
+ * @param include_installed if false, installed packages are excluded from the list.
  * @return an alpm_list_t of optdepend formatted strings with description
  */
-alpm_list_t *optdep_string_list(const alpm_list_t *optlist)
+alpm_list_t *optdep_string_list(const alpm_list_t *optlist, int include_installed)
 {
 	alpm_list_t *optstrings = NULL;
 	alpm_optdepend_t *optdep;
 	alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
 
+	/* calculate these outside the loop. */
+	alpm_list_t *pkgcache = alpm_db_get_pkgcache(db_local);
+	alpm_list_t *remove = alpm_trans_get_remove(config->handle);
+	alpm_list_t *add = alpm_trans_get_add(config->handle);
+
 	/* turn optdepends list into a text list. */
 	for( ; optlist; optlist = alpm_list_next(optlist)) {
 		optdep = optlist->data;
-		if(alpm_db_get_pkg(db_local, optdep->depend->name) == NULL) {
-			optstrings = alpm_list_add(optstrings, alpm_optdep_compute_string(optdep));
+		char *depstr = alpm_dep_compute_string(optdep->depend);
+		char *tmp, *str = alpm_optdep_compute_string(optdep);
+		const char *state = NULL;
+
+		if(alpm_find_satisfier(pkgcache, depstr) && alpm_find_satisfier(remove, depstr) == NULL) {
+			state = include_installed ? _(" [installed]") : NULL;
+		} else if(alpm_find_satisfier(add, depstr)) {
+			state = include_installed ? _(" [installing]") : NULL;
+		} else if(alpm_find_satisfier(remove, depstr)) {
+			state = _(" [removing]");
+		} else {
+			optstrings = alpm_list_add(optstrings, str);
 		}
+
+		if(state) {
+			if((tmp = realloc(str, strlen(str) + strlen(state) + 1)) != NULL) {
+				strcpy(tmp + strlen(tmp), state);
+				str = tmp;
+			} /* if realloc fails, we only loose the state information, which is nonfatal. */
+			optstrings = alpm_list_add(optstrings, str);
+		}
+		free(depstr);
 	}
 
 	return optstrings;
@@ -1203,7 +1228,7 @@ void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
 	new = alpm_pkg_get_optdepends(newpkg);
 	optdeps = alpm_list_diff(new, old, opt_cmp);
 
-	optstrings = optdep_string_list(optdeps);
+	optstrings = optdep_string_list(optdeps, config->handleoptdeps & PM_OPTDEPS_SHOWALL);
 
 	if(optstrings) {
 		printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
@@ -1218,7 +1243,7 @@ void display_optdepends(alpm_pkg_t *pkg)
 {
 	alpm_list_t *optstrings;
 
-	optstrings = optdep_string_list(alpm_pkg_get_optdepends(pkg));
+	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));
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 6ec962f..ca33752 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -69,6 +69,7 @@ void display_targets(void);
 int str_cmp(const void *s1, const void *s2);
 void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg);
 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);
 int select_question(int count);
diff --git a/test/pacman/tests/sync061.py b/test/pacman/tests/sync062.py
similarity index 65%
copy from test/pacman/tests/sync061.py
copy to test/pacman/tests/sync062.py
index cb5a892..dc90002 100644
--- a/test/pacman/tests/sync061.py
+++ b/test/pacman/tests/sync062.py
@@ -1,4 +1,6 @@
-self.description = "Install a package from a sync db with installed optdepend and no optdepend output"
+self.description = "Install a package from a sync db with installed optdepend and forced optdepend output"
+
+self.option["HandleOptdeps"] = ["ShowAll"]
 
 p1 = pmpkg("dummy")
 p1.optdepends = ["dep: for foobar"]
@@ -10,6 +12,6 @@
 self.args = "-S %s" % p1.name
 
 self.addrule("PACMAN_RETCODE=0")
-self.addrule("!PACMAN_OUTPUT=dep: for foobar")
-self.addrule("PKG_EXISTS=dummy")
+self.addrule("PACMAN_OUTPUT=dep: for foobar")
+self.addrule("PKG_EXIST=dummy")
 self.addrule("PKG_OPTDEPENDS=dummy|dep: for foobar")
-- 
1.7.7.3



More information about the pacman-dev mailing list