[pacman-dev] [PATCH] Add "Optional for" to package information output

Allan McRae allan at archlinux.org
Sun Aug 12 02:32:12 EDT 2012


Much like packages that require a give package are displayed in the
"Required by" field of its information output, alos display packages
that optionally require the package.

Inspired-by: Benedikt Morbach <benedikt.morbach at googlemail.com>
Signed-off-by: Allan McRae <allan at archlinux.org>
---

Example output: 

> ./src/pacman/pacman -Qi tk
Name           : tk
...
Required By    : None
Optional For   : git  python  python2  r


 lib/libalpm/alpm.h    |  8 ++++++++
 lib/libalpm/package.c | 34 +++++++++++++++++++++++++++-------
 src/pacman/package.c  |  4 +++-
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index f8928b9..5b4eb6d 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -721,6 +721,14 @@ int alpm_pkg_vercmp(const char *a, const char *b);
  */
 alpm_list_t *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg);
 
+/** Computes the list of packages optionally requiring a given package.
+ * The return value of this function is a newly allocated
+ * list of package names (char*), it should be freed by the caller.
+ * @param pkg a package
+ * @return the list of packages optionally requiring pkg
+ */
+alpm_list_t *alpm_pkg_compute_optionalfor(alpm_pkg_t *pkg);
+
 /** @name Package Property Accessors
  * Any pointer returned by these functions points to internal structures
  * allocated by libalpm. They should not be freed nor modified in any
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 4887e21..f3e0b7f 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -389,7 +389,8 @@ int SYMEXPORT alpm_pkg_has_scriptlet(alpm_pkg_t *pkg)
 	return pkg->ops->has_scriptlet(pkg);
 }
 
-static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
+static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs,
+		int optional)
 {
 	const alpm_list_t *i;
 	pkg->handle->pm_errno = 0;
@@ -397,7 +398,14 @@ static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
 	for(i = _alpm_db_get_pkgcache(db); i; i = i->next) {
 		alpm_pkg_t *cachepkg = i->data;
 		alpm_list_t *j;
-		for(j = alpm_pkg_get_depends(cachepkg); j; j = j->next) {
+
+		if(optional == 0) {
+			j = alpm_pkg_get_depends(cachepkg);
+		} else {
+			j = alpm_pkg_get_optdepends(cachepkg);
+		}
+
+		for(; j; j = j->next) {
 			if(_alpm_depcmp(pkg, j->data)) {
 				const char *cachepkgname = cachepkg->name;
 				if(alpm_list_find_str(*reqs, cachepkgname) == NULL) {
@@ -408,8 +416,7 @@ static void find_requiredby(alpm_pkg_t *pkg, alpm_db_t *db, alpm_list_t **reqs)
 	}
 }
 
-/** Compute the packages requiring a given package. */
-alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
+static alpm_list_t *compute_requiredby(alpm_pkg_t *pkg, int optional)
 {
 	const alpm_list_t *i;
 	alpm_list_t *reqs = NULL;
@@ -420,17 +427,17 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
 
 	if(pkg->origin == ALPM_PKG_FROM_FILE) {
 		/* The sane option; search locally for things that require this. */
-		find_requiredby(pkg, pkg->handle->db_local, &reqs);
+		find_requiredby(pkg, pkg->handle->db_local, &reqs, optional);
 	} else {
 		/* We have a DB package. if it is a local package, then we should
 		 * only search the local DB; else search all known sync databases. */
 		db = pkg->origin_data.db;
 		if(db->status & DB_STATUS_LOCAL) {
-			find_requiredby(pkg, db, &reqs);
+			find_requiredby(pkg, db, &reqs, optional);
 		} else {
 			for(i = pkg->handle->dbs_sync; i; i = i->next) {
 				db = i->data;
-				find_requiredby(pkg, db, &reqs);
+				find_requiredby(pkg, db, &reqs, optional);
 			}
 			reqs = alpm_list_msort(reqs, alpm_list_count(reqs), _alpm_str_cmp);
 		}
@@ -438,6 +445,19 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
 	return reqs;
 }
 
+/** Compute the packages requiring a given package. */
+alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
+{
+	return compute_requiredby(pkg, 0);
+}
+
+/** Compute the packages optionally requiring a given package. */
+alpm_list_t SYMEXPORT *alpm_pkg_compute_optionalfor(alpm_pkg_t *pkg)
+{
+	return compute_requiredby(pkg, 1);
+}
+
+
 /** @} */
 
 alpm_file_t *_alpm_file_copy(alpm_file_t *dest,
diff --git a/src/pacman/package.c b/src/pacman/package.c
index ce7de7f..a8f322c 100644
--- a/src/pacman/package.c
+++ b/src/pacman/package.c
@@ -89,7 +89,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
 	double size;
 	char bdatestr[50] = "", idatestr[50] = "";
 	const char *label, *reason;
-	alpm_list_t *validation = NULL, *requiredby = NULL;
+	alpm_list_t *validation = NULL, *requiredby = NULL, *optionalfor = NULL;
 
 	from = alpm_pkg_get_origin(pkg);
 
@@ -137,6 +137,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
 	if(extra || from == ALPM_PKG_FROM_LOCALDB) {
 		/* compute this here so we don't get a pause in the middle of output */
 		requiredby = alpm_pkg_compute_requiredby(pkg);
+		optionalfor = alpm_pkg_compute_optionalfor(pkg);
 	}
 
 	cols = getcols(fileno(stdout));
@@ -159,6 +160,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
 
 	if(extra || from == ALPM_PKG_FROM_LOCALDB) {
 		list_display(_("Required By    :"), requiredby, cols);
+		list_display(_("Optional For   :"), optionalfor, cols);
 	}
 	deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols);
 	deplist_display(_("Replaces       :"), alpm_pkg_get_replaces(pkg), cols);
-- 
1.7.11.4



More information about the pacman-dev mailing list