Signed-off-by: Benedikt Morbach <[email protected]>
---
 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 ++++
 6 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 45386c7..4d84f7d 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 1093d5e..868a98b 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -993,7 +993,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 407e279..54a0d3a 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -553,7 +553,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;
 
@@ -582,7 +582,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;
                }
        }
@@ -602,7 +602,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;
 
@@ -615,7 +615,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 3293713..9e65767 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 3a19619..02504c4 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -131,6 +131,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
@@ -608,6 +611,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'},
-- 
1.7.6.1


Reply via email to