diff --git a/projects/cram/src/python/cram/__init__.py b/projects/cram/src/python/cram/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/projects/cram/src/python/cram/__main__.py b/projects/cram/src/python/cram/__main__.py
index 2098910..fc9f0fd 100644
--- a/projects/cram/src/python/cram/__main__.py
+++ b/projects/cram/src/python/cram/__main__.py
@@ -9,9 +9,10 @@ import re
 import sys
 from typing import NamedTuple
 
+from vfs import Vfs
+
 import click
 from toposort import toposort_flatten
-from vfs import Vfs
 
 
 log = logging.getLogger(__name__)
@@ -68,7 +69,7 @@ class PackageV0(NamedTuple):
 
         return requires
 
-    def install(self, fs: Vfs, dest):
+    def install(self, fs: Vfs, dest: Path):
         """Install this package."""
         buildf = self.root / "BUILD"
         if buildf.exists():
@@ -89,6 +90,26 @@ class PackageV0(NamedTuple):
             fs.exec(self.root, ["bash", str(postf)])
 
 
+class ProfileV0(PackageV0):
+    def install(self, fs: Vfs, dest: Path):
+        """Profiles differ from Packages in that they don't support literal files."""
+        buildf = self.root / "BUILD"
+        if buildf.exists():
+            fs.exec(self.root, ["bash", str(buildf)])
+
+        pref = self.root / "PRE_INSTALL"
+        if pref.exists():
+            fs.exec(self.root, ["bash", str(pref)])
+
+        installf = self.root / "INSTALL"
+        if installf.exists():
+            fs.exec(self.root, ["bash", str(installf)])
+
+        postf = self.root / "POST_INSTALL"
+        if postf.exists():
+            fs.exec(self.root, ["bash", str(postf)])
+
+    
 def load_config(root: Path) -> dict:
     """Load the configured packages."""
 
@@ -109,8 +130,8 @@ def load_config(root: Path) -> dict:
                     p, str(p.relative_to(root))
                 )
 
-        # Register the metapackages themselves
-        packages[str(mp_root.relative_to(root))] = PackageV0(
+        # Register the metapackages themselves using the profile type
+        packages[str(mp_root.relative_to(root))] = ProfileV0(
             mp_root, str(mp_root.relative_to(root)), True
         )
 
@@ -206,13 +227,13 @@ def cli():
     pass
 
 
-@cli.command("apply")
+@cli.command()
 @click.option("--execute/--dry-run", default=False)
-@click.option("--optimize/--no-optimize", default=True)
 @click.option("--state-file", default=".cram.log", type=Path)
+@click.option("--optimize/--no-optimize", default=False)
 @click.argument("confdir", type=Path)
 @click.argument("destdir", type=Path)
-def cmd_apply(confdir, destdir, state_file, execute, optimize):
+def apply(confdir, destdir, state_file, execute, optimize):
     """The entry point of cram."""
 
     # Resolve the two input paths to absolutes
@@ -239,35 +260,49 @@ def cmd_apply(confdir, destdir, state_file, execute, optimize):
 
     else:
         for e in executable_fs._log:
-            print("-", *e)
+            print("-", e)
 
 
-@cli.command("show")
+@cli.command()
 @click.option("--state-file", default=".cram.log", type=Path)
 @click.argument("confdir", type=Path)
-def cmd_show(confdir, state_file):
+def show(confdir, state_file):
     """List out the last `apply` state in the <confdir>/.cram.log or --state-file."""
     root = confdir.resolve()
-
     if not state_file.is_absolute():
         state_file = root / state_file
-
     fs = load_fs(state_file)
-
     for e in fs._log:
         print(*e)
 
 
-@cli.command("list")
+@cli.command()
 @click.argument("confdir", type=Path)
-def cmd_list(confdir):
+@click.argument("list_packages", nargs=-1)
+def list(confdir, list_packages):
     """List out packages, profiles, hosts and subpackages in the <confdir>."""
     packages = load_config(confdir)
-    for pname in sorted(packages.keys()):
-        p = packages[pname]
-        print(f"{pname}:")
-        for d in p.requires():
-            print(f"- {d}")
+
+    if list_packages:
+        dest = Path("~/")
+        for pname in list_packages:
+            fs = Vfs()
+            p = packages[pname]
+            p.install(fs, dest)
+            print(f"{pname}: ({type(p).__name__})")
+            print("requires:")
+            for e in p.requires():
+                print("  -", e)
+            print("log:")
+            for e in fs._log:
+                print("  -", *e)
+
+    else:
+        for pname in sorted(packages.keys()):
+            p = packages[pname]
+            print(f"{pname}: ({type(p).__name__})")
+            for d in p.requires():
+                print(f"- {d}")
 
 
 if __name__ == "__main__" or 1:
diff --git a/projects/vfs/src/python/vfs/impl.py b/projects/vfs/src/python/vfs/impl.py
index b405b75..8c98eb1 100644
--- a/projects/vfs/src/python/vfs/impl.py
+++ b/projects/vfs/src/python/vfs/impl.py
@@ -3,6 +3,7 @@ The implementation.
 """
 
 import logging
+from shutil import rmtree
 from subprocess import run
 
 
@@ -15,14 +16,11 @@ class Vfs(object):
     def __init__(self, log=None):
         self._log = log or []
 
-    def execute(self, execute=False):
+    def execute(self):
         for e in self._log:
             _log.debug(e)
 
-            if not execute:
-                continue
-
-            elif e[0] == "exec":
+            if e[0] == "exec":
                 _, dir, cmd = e
                 run(cmd, cwd=str(dir))
 
@@ -36,6 +34,7 @@ class Vfs(object):
 
                 assert not dest.exists()
                 dest.symlink_to(src)
+                assert dest.exists()
 
             elif e[0] == "copy":
                 raise NotImplementedError()
@@ -50,7 +49,10 @@ class Vfs(object):
 
             elif e[0] == "unlink":
                 _, dest = e
-                dest.unlink()
+                if dest.is_dir():
+                    rmtree(dest)   
+                elif dest.is_file():
+                    dest.unlink()
 
     def _append(self, msg):
         self._log.append(msg)
diff --git a/setup.cfg b/setup.cfg
index e013590..c9a464e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,7 +6,7 @@ multi_line_output = 3
 lines_after_imports = 2
 default_section = THIRDPARTY
 known_localfolder = datalog
-sections = FUTURE,STDLIB,LOCALFOLDER,THIRDPARTY,
+sections = STDLIB,LOCALFOLDER,FIRSTPARTY,THIRDPARTY
 
 force_sort_within_sections = 1
 force_alphabetical_sort_within_sections = 1