diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -68,14 +68,13 @@
 [GHC](https://www.haskell.org/ghc/download.html) and install with
 
 ```bash
+cabal update
 cabal new-install ats-pkg --symlink-bindir ~/.local/bin --happy-options='-gcsa' --alex-options='-g'
 ```
 
 Note that `$HOME/.local/bin` will need to be on your `PATH`.
 
-## Examples
-
-### Quick Start
+## Quick Start
 
 Install [pi](http://github.com/vmchale/project-init) with
 
@@ -96,7 +95,7 @@
 atspkg run
 ```
 
-### Further Documentation
+## Examples
 
 You can find several examples with explanation
 [here](https://github.com/vmchale/atspkg/blob/master/EXAMPLES.md)
@@ -104,16 +103,14 @@
 ## Global Configuration
 
 `atspkg` is configured via a file in `~/.config/atspkg/config.dhall`. You can
-set custom package set as follows:
+set a custom package set as follows:
 
 ```
 let cfg = 
   { defaultPkgs = "https://raw.githubusercontent.com/vmchale/atspkg/master/dhall/pkg-set.dhall"
   , path = ([] : Optional Text)
+  , githubUsername = "YOUR_USERNAME"
   }
 
 in cfg
 ```
-
-Package sets are simply sets of packages, so you can also use Dhall to
-concatenate custom package sets with the above.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,8 +1,10 @@
 {-# OPTIONS_GHC -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat #-}
 
+import           Data.Bool                       (bool)
 import           Distribution.CommandLine
+import           Distribution.PackageDescription
 import           Distribution.Simple
-import           Distribution.Types.HookedBuildInfo
+import           Distribution.Simple.Setup
 
 installActions :: IO ()
 installActions = sequence_
@@ -11,6 +13,12 @@
     , writeBashCompletions "atspkg"
     ]
 
+maybeInstallActions :: ConfigFlags -> IO ()
+maybeInstallActions cfs = bool nothing act cond
+    where act = installActions
+          nothing = pure mempty
+          cond = (mkFlagName "no-executable", True) `elem` configConfigurationsFlags cfs
+
 main :: IO ()
 main = defaultMainWithHooks $
-    simpleUserHooks { preConf = \_ _ -> installActions >> pure emptyHookedBuildInfo }
+    simpleUserHooks { preConf = \_ flags -> maybeInstallActions flags >> pure emptyHookedBuildInfo }
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -1,6 +1,177 @@
-module Main where
+{-# LANGUAGE OverloadedStrings #-}
 
-import           Language.ATS.Package.Exec (exec)
+module Main ( main
+            ) where
 
+import           Control.Composition
+import           Control.Lens               hiding (List, argument)
+import           Data.Bool                  (bool)
+import           Data.Maybe                 (fromMaybe)
+import           Data.Semigroup             (Semigroup (..))
+import qualified Data.Text.Lazy             as TL
+import           Data.Version               hiding (Version (..))
+import           Development.Shake.ATS
+import           Development.Shake.FilePath
+import           Language.ATS.Package
+import           Options.Applicative
+import qualified Paths_ats_pkg              as P
+import           System.Directory
+import           System.IO.Temp             (withSystemTempDirectory)
+
+-- TODO command to list available packages.
+wrapper :: ParserInfo Command
+wrapper = info (helper <*> versionInfo <*> command')
+    (fullDesc
+    <> progDesc "The atspkg build tool for ATS-Postiats."
+    <> header "atspkg - a build tool for ATS\nsee 'man atspkg' for more detailed help")
+
+versionInfo :: Parser (a -> a)
+versionInfo = infoOption ("atspkg version: " ++ showVersion P.version) (short 'V' <> long "version" <> help "Show version")
+
+data Command = Install
+             | Build { _targets    :: [String]
+                     , _archTarget :: Maybe String
+                     , _rebuildAll :: Bool
+                     , _verbosity  :: Int
+                     , _lint       :: Bool
+                     }
+             | Clean
+             | Test { _targets    :: [String]
+                    , _rebuildAll :: Bool
+                    , _lint       :: Bool
+                    }
+             | Fetch { _url :: String }
+             | Nuke
+             | Upgrade
+             | Valgrind { _targets :: [String] }
+             | Run { _targets    :: [String]
+                   , _rebuildAll :: Bool
+                   , _lint       :: Bool
+                   }
+             | Check { _filePath :: String, _details :: Bool }
+             | List
+
+command' :: Parser Command
+command' = hsubparser
+    (command "install" (info (pure Install) (progDesc "Install all binaries to $HOME/.local/bin"))
+    <> command "clean" (info (pure Clean) (progDesc "Clean current project directory"))
+    <> command "remote" (info fetch (progDesc "Fetch and install a binary package"))
+    <> command "build" (info build' (progDesc "Build current package targets"))
+    <> command "test" (info test' (progDesc "Test current package"))
+    <> command "nuke" (info (pure Nuke) (progDesc "Uninstall all globally installed libraries"))
+    <> command "upgrade" (info (pure Upgrade) (progDesc "Upgrade to the latest version of atspkg"))
+    <> command "valgrind" (info valgrind (progDesc "Run generated binaries through valgrind"))
+    <> command "run" (info run' (progDesc "Run generated binaries"))
+    <> command "check" (info check' (progDesc "Check pkg.dhall file to ensure it is well-typed."))
+    <> command "list" (info (pure List) (progDesc "List available packages"))
+    )
+
+check' :: Parser Command
+check' = Check
+    <$> targetP dhallCompletions id "check"
+    <*> switch
+    (long "detailed"
+    <> short 'd'
+    <> help "Enable detailed error messages")
+
+ftypeCompletions :: String -> Mod ArgumentFields a
+ftypeCompletions ext = completer . bashCompleter $ "file -X '!*." ++ ext ++ "' -o plusdirs"
+
+dhallCompletions :: Mod ArgumentFields a
+dhallCompletions = ftypeCompletions "dhall"
+
+run' :: Parser Command
+run' = Run <$> targets "run"
+    <*> rebuild
+    <*> noLint
+
+test' :: Parser Command
+test' = Test
+    <$> targets "test"
+    <*> rebuild
+    <*> noLint
+
+valgrind :: Parser Command
+valgrind = Valgrind <$> targets "run with valgrind"
+
+targets :: String -> Parser [String]
+targets = targetP mempty many
+
+targetP :: Mod ArgumentFields String -> (Parser String -> a) -> String -> a
+targetP completions' f s = f
+    (argument str
+    (metavar "TARGET"
+    <> help ("Targets to " <> s)
+    <> completions'))
+
+rebuild :: Parser Bool
+rebuild = switch
+    (long "rebuild"
+    <> short 'r'
+    <> help "Force rebuild of all targets")
+
+triple :: Parser (Maybe String)
+triple = optional
+    (strOption
+    (long "target"
+    <> short 't'
+    <> help "Set target by using its triple"))
+
+verbosity :: Parser Int
+verbosity = length <$>
+    many (flag' () (short 'v' <> long "verbose" <> help "Turn up verbosity"))
+
+build' :: Parser Command
+build' = Build
+    <$> targets "build"
+    <*> triple
+    <*> rebuild
+    <*> verbosity
+    <*> noLint
+
+noLint :: Parser Bool
+noLint = fmap not
+    (switch
+    (long "no-lint"
+    <> short 'l'
+    <> help "Disable the shake linter"))
+
+fetch :: Parser Command
+fetch = Fetch <$>
+    argument str
+    (metavar "URL"
+    <> help "URL pointing to a tarball containing the package to be installed.")
+
+fetchPkg :: String -> IO ()
+fetchPkg pkg = withSystemTempDirectory "atspkg" $ \p -> do
+    let (lib, dirName, url') = (mempty, p, pkg) & each %~ TL.pack
+    buildHelper True (ATSDependency lib dirName url' undefined undefined mempty mempty)
+    ps <- getSubdirs p
+    pkgDir <- fromMaybe p <$> findFile (p:ps) "atspkg.dhall"
+    let a = withCurrentDirectory (takeDirectory pkgDir) (mkPkg False False mempty ["install"] Nothing 0)
+    bool (buildAll (Just pkgDir) >> a) a =<< check (Just pkgDir)
+
 main :: IO ()
-main = exec
+main = execParser wrapper >>= run
+
+runHelper :: Bool -> Bool -> [String] -> Maybe String -> Int -> IO ()
+runHelper rba lint rs tgt v = g . bool x y =<< check Nothing
+    where g xs = mkPkg rba lint xs rs tgt v
+          y = mempty
+          x = [buildAll Nothing]
+
+run :: Command -> IO ()
+run List = displayList "https://raw.githubusercontent.com/vmchale/atspkg/master/pkgs/pkg-set.dhall"
+run (Check p b) = print =<< checkPkg p b
+run Upgrade = upgradeBin "vmchale" "atspkg"
+run Nuke = cleanAll
+run (Fetch u) = fetchPkg u
+run Clean = mkPkg False True mempty ["clean"] Nothing 0
+run (Build rs tgt rba v lint) = runHelper rba lint rs tgt v
+run (Test ts rba lint) = runHelper rba lint ("test" : ts) Nothing 0
+run (Run ts rba lint) = runHelper rba lint ("run" : ts) Nothing 0
+run c = runHelper False True rs Nothing 0
+    where rs = g c
+          g Install       = ["install"]
+          g (Valgrind ts) = "valgrind" : ts
+          g _             = undefined
diff --git a/ats-pkg.cabal b/ats-pkg.cabal
--- a/ats-pkg.cabal
+++ b/ats-pkg.cabal
@@ -1,95 +1,120 @@
-name:                ats-pkg
-version:             2.5.0.3
-synopsis:            A build tool for ATS
-description:         A collection of scripts to simplify building ATS projects.
-homepage:            https://github.com/vmchale/atspkg#readme
-license:             BSD3
-license-file:        LICENSE
-author:              Vanessa McHale
-maintainer:          vamchale@gmail.com
-copyright:           Copyright: (c) 2018 Vanessa McHale
-category:            Development, ATS
-build-type:          Custom
-extra-doc-files:     README.md
-                   , docs/manual.tex
-extra-source-files:  stack.yaml
-                   , man/atspkg.1
-                   , config.dhall
-cabal-version:       1.18
+cabal-version: 1.18
+name: ats-pkg
+version: 2.6.0.0
+license: BSD3
+license-file: LICENSE
+copyright: Copyright: (c) 2018 Vanessa McHale
+maintainer: vamchale@gmail.com
+author: Vanessa McHale
+homepage: https://github.com/vmchale/atspkg#readme
+synopsis: A build tool for ATS
+description:
+    A collection of scripts to simplify building ATS projects.
+category: Development, ATS
+build-type: Custom
+extra-source-files:
+    stack.yaml
+    man/atspkg.1
+    config.dhall
+extra-doc-files: README.md
+                 docs/manual.tex
 
-Flag development {
-  Description: Enable `-Werror`
-  manual: True
-  default: False
-}
+source-repository head
+    type: git
+    location: git@github.com:vmchale/atspkg.git
 
 custom-setup
-  setup-depends:     base
-                   , Cabal >= 2.0
-                   , cli-setup >= 0.2.0.1
+    setup-depends: base,
+                   Cabal >=2.0,
+                   cli-setup >=0.2.0.1
 
+flag development
+    description:
+        Enable `-Werror`
+    default: False
+    manual: True
+
+flag no-executable
+    description:
+        Enable `-Werror`
+    default: False
+
 library
-  hs-source-dirs:      src
-  exposed-modules:     Language.ATS.Package.Exec
-                     , Language.ATS.Package
-  other-modules:       Paths_ats_pkg
-                     , Language.ATS.Package.Error
-                     , Language.ATS.Package.Type
-                     , Language.ATS.Package.Dependency
-                     , Language.ATS.Package.Compiler
-                     , Language.ATS.Package.Build
-                     , Language.ATS.Package.Build.IO
-                     , Language.ATS.Package.Upgrade
-                     , Language.ATS.Package.Config
-                     , Language.ATS.Package.PackageSet
-                     , Language.ATS.Package.Dhall
-                     , Quaalude
-  build-depends:       base >= 4.7 && < 5
-                     , http-client
-                     , bytestring
-                     , file-embed
-                     , shake
-                     , bzlib
-                     , lzma
-                     , tar
-                     , zlib
-                     , http-client-tls
-                     , text
-                     , directory
-                     , process
-                     , containers
-                     , parallel-io
-                     , unix
-                     , lens
-                     , dhall
-                     , ansi-wl-pprint
-                     , shake-ats >= 1.3.0.0
-                     , shake-ext >= 2.3.0.0
-                     , composition-prelude >= 1.3.0.0
-                     , optparse-applicative
-                     , zip-archive
-                     , temporary
-                     , ansi-wl-pprint
-                     , binary
-                     , dependency
-                     , ats-setup >= 0.3.1.1
-  build-tools:         cpphs
-  default-language:    Haskell2010
-  if flag(development)
-    ghc-options: -Werror
-  ghc-options:         -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat
+    exposed-modules:
+        Language.ATS.Package
+    build-tools: cpphs
+    hs-source-dirs: src
+    other-modules:
+        Paths_ats_pkg
+        Language.ATS.Package.Error
+        Language.ATS.Package.Type
+        Language.ATS.Package.Dependency
+        Language.ATS.Package.Compiler
+        Language.ATS.Package.Build
+        Language.ATS.Package.Build.IO
+        Language.ATS.Package.Upgrade
+        Language.ATS.Package.Config
+        Language.ATS.Package.PackageSet
+        Language.ATS.Package.Dhall
+        Quaalude
+    default-language: Haskell2010
+    ghc-options: -Wall -Wincomplete-uni-patterns
+                 -Wincomplete-record-updates -Wcompat
+    build-depends:
+        base >=4.7 && <5,
+        http-client,
+        bytestring,
+        file-embed,
+        shake,
+        bzlib,
+        Cabal >=2.0.0.0,
+        lzma,
+        tar,
+        zlib,
+        http-client-tls,
+        text,
+        directory,
+        process,
+        containers,
+        parallel-io,
+        unix,
+        lens,
+        dhall,
+        ansi-wl-pprint,
+        shake-ats >=1.3.0.0,
+        shake-ext >=2.3.0.0,
+        composition-prelude >=1.3.0.0,
+        zip-archive,
+        ansi-wl-pprint,
+        binary,
+        dependency,
+        ats-setup >=0.3.1.1
+    
+    if flag(development)
+        ghc-options: -Werror
 
 executable atspkg
-  hs-source-dirs:      app
-  main-is:             Main.hs
-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
-  build-depends:       base
-                     , ats-pkg
-  default-language:    Haskell2010
-  if flag(development)
-    ghc-options: -Werror
-  ghc-options:         -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat
-
-source-repository head
-  type:     git
-  location: git@github.com:vmchale/atspkg.git
+    main-is: Main.hs
+    hs-source-dirs: app
+    other-modules:
+        Paths_ats_pkg
+    default-language: Haskell2010
+    ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+                 -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat
+    build-depends:
+        base,
+        ats-pkg,
+        optparse-applicative,
+        lens,
+        shake-ats,
+        temporary,
+        directory,
+        composition-prelude,
+        text,
+        shake
+    
+    if flag(no-executable)
+        buildable: False
+    
+    if flag(development)
+        ghc-options: -Werror
diff --git a/man/atspkg.1 b/man/atspkg.1
--- a/man/atspkg.1
+++ b/man/atspkg.1
@@ -67,7 +67,7 @@
 .RE
 .TP
 .B \f[B]\-l\f[], \f[B]\-\-no\-lint\f[]
-Disable the shake linter
+Disable the build system linter
 .RS
 .RE
 .TP
@@ -89,12 +89,16 @@
 .PP
 \f[B]atspkg\f[] is configured with Dhall, in an atspkg.dhall file.
 \f[B]atspkg\f[] can be configured to produce binary targets (possibly
-linked against Haskell libraries), as well as plain C targets.
+linked against Haskell libraries), static library targets, and as plain
+C targets.
+.PP
+There is also a file $HOME/.config/atspkg/config.dhall which can be used
+to configure all builds.
 .SS TEMPLATES
 .PP
-There are several template avaiable for \f[B]pi\f[] as well (see
+There are several templates available for \f[B]pi\f[] (see
 https://crates.io/crates/project_init for more details).
-A couple examples:
+Several examples:
 .IP
 .nf
 \f[C]
diff --git a/src/Language/ATS/Package.hs b/src/Language/ATS/Package.hs
--- a/src/Language/ATS/Package.hs
+++ b/src/Language/ATS/Package.hs
@@ -1,17 +1,17 @@
 module Language.ATS.Package ( pkgToAction
-                            , fetchCompiler
-                            , setupCompiler
                             , build
                             , buildAll
                             , check
                             , mkPkg
                             , cleanAll
                             , fetchDeps
-                            , mkBuildPlan
                             , buildHelper
                             , checkPkg
+                            -- * Ecosystem functionality
                             , displayList
                             , upgradeBin
+                            -- * Cabal helper functions
+                            , cabalHooks
                             -- * Types
                             , Version (..)
                             , Pkg (..)
diff --git a/src/Language/ATS/Package/Build.hs b/src/Language/ATS/Package/Build.hs
--- a/src/Language/ATS/Package/Build.hs
+++ b/src/Language/ATS/Package/Build.hs
@@ -7,24 +7,30 @@
 module Language.ATS.Package.Build ( mkPkg
                                   , pkgToAction
                                   , build
+                                  , cabalHooks
                                   , buildAll
                                   , check
                                   ) where
 
 import           Control.Concurrent.ParallelIO.Global
-import qualified Data.ByteString                      as BS
-import qualified Data.ByteString.Lazy                 as BSL
-import           Data.List                            (nub)
-import           Data.Version                         (showVersion)
+import qualified Data.ByteString                        as BS
+import qualified Data.ByteString.Lazy                   as BSL
+import           Data.List                              (nub)
+import qualified Data.Map                               as M
+import           Data.Version                           (showVersion)
 import           Development.Shake.ATS
 import           Development.Shake.Check
 import           Development.Shake.Clean
 import           Development.Shake.Man
+import           Distribution.PackageDescription        hiding (Executable, includes, options)
+import           Distribution.Simple                    hiding (Version, showVersion)
+import           Distribution.Simple.Setup
+import           Distribution.Types.UnqualComponentName
 import           Language.ATS.Package.Compiler
 import           Language.ATS.Package.Config
 import           Language.ATS.Package.Dependency
-import           Language.ATS.Package.Type            hiding (Version)
-import qualified Paths_ats_pkg                        as P
+import           Language.ATS.Package.Type              hiding (Version)
+import qualified Paths_ats_pkg                          as P
 import           Quaalude
 
 check :: Maybe FilePath -> IO Bool
@@ -39,6 +45,21 @@
 -- | Build in current directory or indicated directory
 buildAll :: Maybe FilePath -> IO ()
 buildAll p = on (>>) (=<< wants p) fetchCompiler setupCompiler
+
+buildCabal :: String -> Args -> BuildFlags -> IO HookedBuildInfo
+buildCabal libName _ _ = do
+    build mempty
+    libDir <- (<> "/") <$> getCurrentDirectory
+    pure (modifyLib libDir (mkUnqualComponentName libName) emptyHookedBuildInfo)
+
+modifyLib :: String -> UnqualComponentName -> HookedBuildInfo -> HookedBuildInfo
+modifyLib libDir key = second (M.toList . M.alter (fmap modify) key . M.fromList)
+    where modify bi = let olds = extraLibDirs bi
+            in bi { extraLibDirs = (libDir <>) <$> olds }
+
+cabalHooks :: String -- ^ Haskell library name
+           -> UserHooks
+cabalHooks libName = simpleUserHooks { preBuild = buildCabal libName }
 
 -- | Build a set of targets
 build :: [String] -- ^ Targets
diff --git a/src/Language/ATS/Package/Dependency.hs b/src/Language/ATS/Package/Dependency.hs
--- a/src/Language/ATS/Package/Dependency.hs
+++ b/src/Language/ATS/Package/Dependency.hs
@@ -46,17 +46,18 @@
             unpacked = fmap (over dirLens (pack d <>)) <$> cdeps'
             clibs = fmap (buildHelper False) (join unpacked)
             atsLibs = fmap (buildHelper False) (join atsDeps')
+            cBuild = mapM_ (setup cc') <$> transpose unpacked
+            atsBuild = mapM_ atsPkgSetup <$> transpose atsDeps'
 
-        -- Fetch all packages
+        -- Fetch all packages & build compiler
         parallel' $ join [ setup', libs', clibs, atsLibs ]
 
-        -- Build C dependencies
-        unless (null unpacked) $
-            mapM_ (setup cc') (join unpacked)
+        let tagBuild str bld =
+                unless (null bld) $
+                    putStrLn (mconcat ["Building ", str, " dependencies..."]) >>
+                    parallel' bld
 
-        -- Build ATS Dependencies
-        unless (null atsDeps') $
-            parallel_ (extraWorkerWhileBlocked <$> (mapM_ atsPkgSetup <$> atsDeps'))
+        zipWithM_ tagBuild [ "C", "ATS" ] [ cBuild, atsBuild ]
 
 parallel' :: [IO ()] -> IO ()
 parallel' = parallel_ . fmap extraWorkerWhileBlocked
diff --git a/src/Language/ATS/Package/Exec.hs b/src/Language/ATS/Package/Exec.hs
deleted file mode 100644
--- a/src/Language/ATS/Package/Exec.hs
+++ /dev/null
@@ -1,172 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-module Language.ATS.Package.Exec ( exec
-                                 ) where
-
-import           Control.Composition
-import           Control.Lens               hiding (List, argument)
-import           Data.Bool                  (bool)
-import           Data.Maybe                 (fromMaybe)
-import           Data.Semigroup             (Semigroup (..))
-import qualified Data.Text.Lazy             as TL
-import           Data.Version               hiding (Version (..))
-import           Development.Shake.ATS
-import           Development.Shake.FilePath
-import           Language.ATS.Package
-import           Options.Applicative        hiding (auto)
-import qualified Paths_ats_pkg              as P
-import           System.Directory
-import           System.IO.Temp             (withSystemTempDirectory)
-
--- TODO command to list available packages.
-wrapper :: ParserInfo Command
-wrapper = info (helper <*> versionInfo <*> command')
-    (fullDesc
-    <> progDesc "The atspkg build tool for ATS-Postiats."
-    <> header "atspkg - a build tool for ATS\nsee 'man atspkg' for more detailed help")
-
-versionInfo :: Parser (a -> a)
-versionInfo = infoOption ("atspkg version: " ++ showVersion P.version) (short 'V' <> long "version" <> help "Show version")
-
-data Command = Install
-             | Build { _targets    :: [String]
-                     , _archTarget :: Maybe String
-                     , _rebuildAll :: Bool
-                     , _verbosity  :: Int
-                     , _lint       :: Bool
-                     }
-             | Clean
-             | Test { _targets    :: [String]
-                    , _rebuildAll :: Bool
-                    , _lint       :: Bool
-                    }
-             | Fetch { _url :: String }
-             | Nuke
-             | Upgrade
-             | Valgrind { _targets :: [String] }
-             | Run { _targets :: [String] }
-             | Check { _filePath :: String, _details :: Bool }
-             | List
-
-command' :: Parser Command
-command' = hsubparser
-    (command "install" (info (pure Install) (progDesc "Install all binaries to $HOME/.local/bin"))
-    <> command "clean" (info (pure Clean) (progDesc "Clean current project directory"))
-    <> command "remote" (info fetch (progDesc "Fetch and install a binary package"))
-    <> command "build" (info build' (progDesc "Build current package targets"))
-    <> command "test" (info test' (progDesc "Test current package"))
-    <> command "nuke" (info (pure Nuke) (progDesc "Uninstall all globally installed libraries"))
-    <> command "upgrade" (info (pure Upgrade) (progDesc "Upgrade to the latest version of atspkg"))
-    <> command "valgrind" (info valgrind (progDesc "Run generated binaries through valgrind"))
-    <> command "run" (info run' (progDesc "Run generated binaries"))
-    <> command "check" (info check' (progDesc "Check pkg.dhall file to ensure it is well-typed."))
-    <> command "list" (info (pure List) (progDesc "List available packages"))
-    )
-
-check' :: Parser Command
-check' = Check
-    <$> targetP dhallCompletions id "check"
-    <*> switch
-    (long "detailed"
-    <> short 'd'
-    <> help "Enable detailed error messages")
-
-ftypeCompletions :: String -> Mod ArgumentFields a
-ftypeCompletions ext = completer . bashCompleter $ "file -X '!*." ++ ext ++ "' -o plusdirs"
-
-dhallCompletions :: Mod ArgumentFields a
-dhallCompletions = ftypeCompletions "dhall"
-
-run' :: Parser Command
-run' = Run <$> targets "run"
-
-test' :: Parser Command
-test' = Test
-    <$> targets "test"
-    <*> rebuild
-    <*> noLint
-
-valgrind :: Parser Command
-valgrind = Valgrind <$> targets "run with valgrind"
-
-targets :: String -> Parser [String]
-targets = targetP mempty many
-
-targetP :: Mod ArgumentFields String -> (Parser String -> a) -> String -> a
-targetP completions' f s = f
-    (argument str
-    (metavar "TARGET"
-    <> help ("Targets to " <> s)
-    <> completions'))
-
-rebuild :: Parser Bool
-rebuild = switch
-    (long "rebuild"
-    <> short 'r'
-    <> help "Force rebuild of all targets")
-
-triple :: Parser (Maybe String)
-triple = optional
-    (strOption
-    (long "target"
-    <> short 't'
-    <> help "Set target by using its triple"))
-
-verbosity :: Parser Int
-verbosity = length <$>
-    many (flag' () (short 'v' <> long "verbose" <> help "Turn up verbosity"))
-
-build' :: Parser Command
-build' = Build
-    <$> targets "build"
-    <*> triple
-    <*> rebuild
-    <*> verbosity
-    <*> noLint
-
-noLint :: Parser Bool
-noLint = fmap not
-    (switch
-    (long "no-lint"
-    <> short 'l'
-    <> help "Disable the shake linter"))
-
-fetch :: Parser Command
-fetch = Fetch <$>
-    argument str
-    (metavar "URL"
-    <> help "URL pointing to a tarball containing the package to be installed.")
-
-fetchPkg :: String -> IO ()
-fetchPkg pkg = withSystemTempDirectory "atspkg" $ \p -> do
-    let (lib, dirName, url') = (mempty, p, pkg) & each %~ TL.pack
-    buildHelper True (ATSDependency lib dirName url' undefined undefined mempty mempty)
-    ps <- getSubdirs p
-    pkgDir <- fromMaybe p <$> findFile (p:ps) "atspkg.dhall"
-    let a = withCurrentDirectory (takeDirectory pkgDir) (mkPkg False False mempty ["install"] Nothing 0)
-    bool (buildAll (Just pkgDir) >> a) a =<< check (Just pkgDir)
-
-exec :: IO ()
-exec = execParser wrapper >>= run
-
-runHelper :: Bool -> Bool -> [String] -> Maybe String -> Int -> IO ()
-runHelper rba lint rs tgt v = g . bool x y =<< check Nothing
-    where g xs = mkPkg rba lint xs rs tgt v
-          y = mempty
-          x = [buildAll Nothing]
-
-run :: Command -> IO ()
-run List = displayList "https://raw.githubusercontent.com/vmchale/atspkg/master/pkgs/pkg-set.dhall"
-run (Check p b) = print =<< checkPkg p b
-run Upgrade = upgradeBin "vmchale" "atspkg"
-run Nuke = cleanAll
-run (Fetch u) = fetchPkg u
-run Clean = mkPkg False True mempty ["clean"] Nothing 0
-run (Build rs tgt rba v lint) = runHelper rba lint rs tgt v
-run (Test ts rba lint) = runHelper rba lint ("test" : ts) Nothing 0
-run c = runHelper False True rs Nothing 0
-    where rs = g c
-          g Install       = ["install"]
-          g (Valgrind ts) = "valgrind" : ts
-          g (Run ts)      = "run" : ts
-          g _             = undefined
diff --git a/src/Quaalude.hs b/src/Quaalude.hs
--- a/src/Quaalude.hs
+++ b/src/Quaalude.hs
@@ -2,6 +2,7 @@
 
 module Quaalude ( bool
                 , intersperse
+                , transpose
                 , sortBy
                 , void
                 , unless
@@ -122,7 +123,7 @@
 import           Control.Monad
 import           Data.Binary
 import           Data.Bool                    (bool)
-import           Data.List                    (intersperse, isPrefixOf, isSuffixOf, sortBy)
+import           Data.List
 import           Data.Maybe                   (fromMaybe)
 import           Data.Text.Lazy               (pack, unpack)
 import           Development.Shake            hiding (getEnv)
