Repository: spack/spack

Issue:
Can't uninstall all packages
I would like to be able to uninstall all packages. The following doesn't work:

```
$ spack uninstall -a
==> Error: uninstall requires at least one package argument.
```



Discussion:
P.S.  I know I can manually delete everything and run `spack reindex`. I just think `spack uninstall -a` should be valid.

came across this today, would be nice to have!


Resolving patch:
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -54,9 +54,10 @@ def setup_parser(subparser):
     subparser.add_argument(
         '-a', '--all', action='store_true', dest='all',
         help="USE CAREFULLY. Remove ALL installed packages that match each "
-             "supplied spec. i.e., if you say uninstall libelf, ALL versions "
-             "of libelf are uninstalled. This is both useful and dangerous, "
-             "like rm -r.")
+             "supplied spec. i.e., if you say uninstall `libelf`,"
+             " ALL versions of `libelf` are uninstalled. If no spec is "
+             "supplied all installed software will be uninstalled. This "
+             "is both useful and dangerous, like rm -r.")
 
     subparser.add_argument(
         '-d', '--dependents', action='store_true', dest='dependents',
@@ -157,37 +158,44 @@ def num_installed_deps(pkg):
         item.do_uninstall(force=force)
 
 
+def get_uninstall_list(args):
+    specs = [any]
+    if args.packages:
+        specs = spack.cmd.parse_specs(args.packages)
+    # Gets the list of installed specs that match the ones give via cli
+    # takes care of '-a' is given in the cli
+    uninstall_list = concretize_specs(specs, args.all, args.force)
+    # Takes care of '-d'
+    dependent_list = installed_dependents(uninstall_list)
+    # Process dependent_list and update uninstall_list
+    has_error = False
+    if dependent_list and not args.dependents and not args.force:
+        for spec, lst in dependent_list.items():
+            tty.error("Will not uninstall %s" %
+                      spec.format("$_$@$%@$#", color=True))
+            print('')
+            print("The following packages depend on it:")
+            spack.cmd.display_specs(lst, **display_args)
+            print('')
+            has_error = True
+    elif args.dependents:
+        for key, lst in dependent_list.items():
+            uninstall_list.extend(lst)
+        uninstall_list = list(set(uninstall_list))
+    if has_error:
+        tty.die('You can use spack uninstall --dependents '
+                'to uninstall these dependencies as well')
+
+    return uninstall_list
+
+
 def uninstall(parser, args):
-    if not args.packages:
+    if not args.packages and not args.all:
         tty.die("uninstall requires at least one package argument.")
 
     with spack.installed_db.write_transaction():
-        specs = spack.cmd.parse_specs(args.packages)
-        # Gets the list of installed specs that match the ones give via cli
-        # takes care of '-a' is given in the cli
-        uninstall_list = concretize_specs(specs, args.all, args.force)
-        dependent_list = installed_dependents(
-            uninstall_list)  # takes care of '-d'
-
-        # Process dependent_list and update uninstall_list
-        has_error = False
-        if dependent_list and not args.dependents and not args.force:
-            for spec, lst in dependent_list.items():
-                tty.error("Will not uninstall %s" %
-                          spec.format("$_$@$%@$#", color=True))
-                print('')
-                print("The following packages depend on it:")
-                spack.cmd.display_specs(lst, **display_args)
-                print('')
-                has_error = True
-        elif args.dependents:
-            for key, lst in dependent_list.items():
-                uninstall_list.extend(lst)
-            uninstall_list = list(set(uninstall_list))
-
-        if has_error:
-            tty.die('You can use spack uninstall --dependents '
-                    'to uninstall these dependencies as well')
+
+        uninstall_list = get_uninstall_list(args)
 
         if not args.yes_to_all:
             tty.msg("The following packages will be uninstalled : ")


Test patch: