[pacman-dev] [PATCH 11/14] Add flag to recurse through optdepends

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


Signed-off-by: Benedikt Morbach <benedikt.morbach at googlemail.com>
---
 doc/pacman.8.txt                                 |    5 +++++
 lib/libalpm/alpm.h                               |    4 +++-
 lib/libalpm/deps.c                               |    8 ++++----
 lib/libalpm/deps.h                               |    2 +-
 lib/libalpm/remove.c                             |    6 ++++--
 src/pacman/pacman.c                              |    4 ++++
 test/pacman/tests/{remove055.py => remove056.py} |    6 +++---
 7 files changed, 24 insertions(+), 11 deletions(-)
 copy test/pacman/tests/{remove055.py => remove056.py} (69%)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 62dd908..2c1748a 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -340,6 +340,11 @@ Remove Options[[RO]]
 	to a backwards '\--sync' operation, and helps keep a clean system without
 	orphans. If you want to omit condition (B), pass this option twice.
 
+*-o, \--recursive-optdeps*::
+	When recursively removing packages, also remove optional dependencies that
+	might still be in use by other packages. You will be warned which packages
+	might still optionally use the removed ones.
+
 *-u, \--unneeded*::
 	Removes targets that are not required by any other packages.
 	This is mostly useful when removing a group without using the '-c' option,
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 34dbaa1..5df833a 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -1006,7 +1006,9 @@ typedef enum _alpm_transflag_t {
 	/** Remove also explicitly installed unneeded deps (use with ALPM_TRANS_FLAG_RECURSE). */
 	ALPM_TRANS_FLAG_RECURSEALL = (1 << 16),
 	/** Do not lock the database during the operation. */
-	ALPM_TRANS_FLAG_NOLOCK = (1 << 17)
+	ALPM_TRANS_FLAG_NOLOCK = (1 << 17),
+	/** Recurse through optdepends, even if needed by other packages. */
+	ALPM_TRANS_FLAG_RECURSE_OPTDEPS = (1 << 18)
 } alpm_transflag_t;
 
 /** Returns the bitfield of flags for the current transaction.
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index c9efce4..ee13ed9 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -555,7 +555,7 @@ alpm_optdepend_t *_alpm_optdep_dup(const alpm_optdepend_t *optdep)
  * target list, or if if the package was explictly installed and
  * include_explicit == 0 */
 static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
-		alpm_list_t *targets, int include_explicit)
+		alpm_list_t *targets, int include_explicit, int include_optdeps)
 {
 	alpm_list_t *i;
 
@@ -584,7 +584,7 @@ static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
 		if(_alpm_dep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) {
 			return 0;
 		}
-		if(_alpm_optdep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) {
+		if(!include_optdeps && _alpm_optdep_edge(lpkg, pkg) && !_alpm_pkg_find(targets, lpkg->name)) {
 			return 0;
 		}
 	}
@@ -604,7 +604,7 @@ static int can_remove_package(alpm_db_t *db, alpm_pkg_t *pkg,
  * @param include_explicit if 0, explicitly installed packages are not included
  * @return 0 on success, -1 on errors
  */
-int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit)
+int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit, int include_optdeps)
 {
 	alpm_list_t *i, *j;
 
@@ -617,7 +617,7 @@ int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit)
 		for(j = _alpm_db_get_pkgcache(db); j; j = j->next) {
 			alpm_pkg_t *deppkg = j->data;
 			if((_alpm_dep_edge(pkg, deppkg) || _alpm_optdep_edge(pkg, deppkg))
-					&& can_remove_package(db, deppkg, targs, include_explicit)) {
+					&& can_remove_package(db, deppkg, targs, include_explicit, include_optdeps)) {
 				alpm_pkg_t *copy;
 				_alpm_log(db->handle, ALPM_LOG_DEBUG, "adding '%s' to the targets\n",
 						deppkg->name);
diff --git a/lib/libalpm/deps.h b/lib/libalpm/deps.h
index 69b65df..13e92b8 100644
--- a/lib/libalpm/deps.h
+++ b/lib/libalpm/deps.h
@@ -33,7 +33,7 @@ alpm_depend_t *_alpm_dep_dup(const alpm_depend_t *dep);
 alpm_optdepend_t *_alpm_optdep_dup(const alpm_optdepend_t *optdep);
 void _alpm_depmiss_free(alpm_depmissing_t *miss);
 alpm_list_t *_alpm_sortbydeps(alpm_handle_t *handle, alpm_list_t *targets, int reverse);
-int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit);
+int _alpm_recursedeps(alpm_db_t *db, alpm_list_t *targs, int include_explicit, int include_optdeps);
 int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs, alpm_pkg_t *pkg,
 		alpm_list_t *preferred, alpm_list_t **packages, alpm_list_t *remove,
 		alpm_list_t **data);
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 012f9c8..704bc69 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -155,7 +155,8 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data)
 			&& !(trans->flags & ALPM_TRANS_FLAG_CASCADE)) {
 		_alpm_log(handle, ALPM_LOG_DEBUG, "finding removable dependencies\n");
 		if(_alpm_recursedeps(db, trans->remove,
-				trans->flags & ALPM_TRANS_FLAG_RECURSEALL)) {
+				trans->flags & ALPM_TRANS_FLAG_RECURSEALL,
+				trans->flags & ALPM_TRANS_FLAG_RECURSE_OPTDEPS)) {
 			return -1;
 		}
 	}
@@ -199,7 +200,8 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data)
 			&& (trans->flags & ALPM_TRANS_FLAG_RECURSE)) {
 		_alpm_log(handle, ALPM_LOG_DEBUG, "finding removable dependencies\n");
 		if(_alpm_recursedeps(db, trans->remove,
-					trans->flags & ALPM_TRANS_FLAG_RECURSEALL)) {
+					trans->flags & ALPM_TRANS_FLAG_RECURSEALL,
+					trans->flags & ALPM_TRANS_FLAG_RECURSE_OPTDEPS)) {
 			return -1;
 		}
 	}
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index fd93133..ec7a4e2 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -128,6 +128,8 @@ static void usage(int op, const char * const myname)
 			addlist(_("  -n, --nosave         remove configuration files\n"));
 			addlist(_("  -s, --recursive      remove unnecessary dependencies\n"
 			          "                       (-ss includes explicitly installed dependencies)\n"));
+			addlist(_("  -o,                  remove optional dependencies,\n"
+			          "     --recurse-optdeps even if they might be used by other packages\n"));
 			addlist(_("  -u, --unneeded       remove unneeded packages\n"));
 		} else if(op == PM_OP_UPGRADE) {
 			printf("%s:  %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
@@ -510,6 +512,7 @@ static int parsearg_remove(int opt)
 	switch(opt) {
 		case 'c': config->flags |= ALPM_TRANS_FLAG_CASCADE; break;
 		case 'n': config->flags |= ALPM_TRANS_FLAG_NOSAVE; break;
+		case 'o': config->flags |= ALPM_TRANS_FLAG_RECURSE_OPTDEPS; break;
 		case 's':
 		case OP_RECURSIVE:
 			/* 's' is the legacy flag here, but since recursive is used in -S without
@@ -607,6 +610,7 @@ static int parseargs(int argc, char *argv[])
 		{"nosave",     no_argument,       0, 'n'},
 		{"optdeps",    no_argument,       0, 'n'},
 		{"owns",       no_argument,       0, 'o'},
+		{"recurse-optdeps", no_argument,  0, 'o'},
 		{"file",       no_argument,       0, 'p'},
 		{"print",      no_argument,       0, 'p'},
 		{"quiet",      no_argument,       0, 'q'},
diff --git a/test/pacman/tests/remove055.py b/test/pacman/tests/remove056.py
similarity index 69%
copy from test/pacman/tests/remove055.py
copy to test/pacman/tests/remove056.py
index e8134ad..24eb36e 100644
--- a/test/pacman/tests/remove055.py
+++ b/test/pacman/tests/remove056.py
@@ -1,4 +1,4 @@
-self.description = "-Rs test (needed optdeps)"
+self.description = "-Rs test (recurse through needed optdeps)"
 
 p1 = pmpkg("dummy")
 p1.optdepends = ["dep: for foobar"]
@@ -12,9 +12,9 @@
 p3.reason = 1
 self.addpkg2db("local", p3)
 
-self.args = "-Rs %s" % p1.name
+self.args = "-Rs --recurse-optdeps %s" % p1.name
 
 self.addrule("PACMAN_RETCODE=0")
 self.addrule("!PKG_EXIST=dummy")
+self.addrule("!PKG_EXIST=dep")
 self.addrule("PKG_EXIST=keep")
-self.addrule("PKG_EXIST=dep")
-- 
1.7.7.3



More information about the pacman-dev mailing list