diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,23 +1,36 @@
 The [latest version](https://github.com/blockscope/hpack-dhall/blob/master/changelog.md) of this changelog.
 
-## 0.5.7 - Bump hpack and test versions
-* Require `hpack ^>= 0.35` and pin extra-deps for stack build and tests.
+## 0.6.0 - Add Cabal External Commands
 
-## 0.5.6 - Relax hpack version upper bound
-* Relax hpack bounds to `hpack >= 0.34.7` for stackage build.
+* Replace the README with a user guide.
+* Add cabal external commands, `dpack`, `ypack` and `diy-pack`.
+* Require `hpack ^>= 0.39.6`.
+* Test with GHC in `{9.2.8, 9.4.8, 9.6.7, 9.8.4, 9.10.3, 9.12.4}`.
 
-## 0.5.5 - Bump hpack and test versions
+## 0.5.7 - Bump Hpack and Test Versions
+
+* Require `hpack ^>= 0.35` and pin extra-deps for Stack build and tests.
+
+## 0.5.6 - Relax Hpack Version Upper Bound
+
+* Relax Hpack bounds to `hpack >= 0.34.7` for Stackage build.
+
+## 0.5.5 - Bump Hpack and Test Versions
+
 * Require `hpack ^>= 0.34.7`.
-* Test with GHC `8.8.4`, GHC `8.10.7`, GHC `9.0.2` and GHC `9.2.2`.
+* Test with GHC in `{8.8.4, 8.10.7, 9.0.2, 9.2.2}`.
 
-## 0.5.4 - Bump hpack and test versions
+## 0.5.4 - Bump Hpack and Test Versions
+
 * Require `hpack >= 0.34.6`.
-* Test with GHC `8.8.4`, GHC `8.10.7` and GHC `9.0.1`.
+* Test with GHC in `{8.8.4, 8.10.7, 9.0.1}`.
 
 ## 0.5.3 - Rewrite the README
+
 * Rewrite the README, making it shorter and splitting some details about more
   uses and building into separate docs.
 * Require `hpack >= 0.34.4`:
+
   ```diff
   $ dhall-hpack-cabal --version
   -dhall-hpack-cabal-0.5.2
@@ -25,15 +38,19 @@
   +dhall-hpack-cabal-0.5.3
   +hpack-0.34.4
   ```
+
 * Require `base >= 4.13`, implying `GHC >= 8.8.4`.
 * Test with GHC `8.8.4` and `8.10.4`.
 * Add files for different stack GHC versions.
-  ```
+
+  ```pre
   $ stack build --stack-yaml=stack/stack-8.8.4.yaml
   $ stack build --stack-yaml=stack/stack-8.10.4.yaml
   $ stack build --stack-yaml=stack/stack-9.0.1.yaml
   ```
-* Remove the travis script and update github scripts with:
+
+* Remove the Travis script and update GitHub scripts with:
+
   ```diff
   - - uses: actions/setup-haskell@v1
   + - uses: haskell/actions/setup@v1
@@ -41,25 +58,30 @@
   - - uses: actions/cache@v1
   + - uses: actions/cache@v2
   ```
-* Remove stale nix-related files.
 
+* Remove stale Nix-related files.
+
 ## 0.5.2 - Consistent Golden Tests
+
 * Use explicit dependencies to achieve consistent golden tests in all but
   stack-8.6.3.yaml.
 
-## 0.5.1 - Minor, bump in hpack version 
-* Regenerate golden files for the bump in hpack's version:
+## 0.5.1 - Minor, Bump Hpack Version
 
-```
----- This file has been generated from package.yaml by hpack version 0.31.0.
-++-- This file has been generated from package.yaml by hpack version 0.31.1.
-```
+* Regenerate golden files for the bump in Hpack's version:
 
+  ```diff
+  ---- This file has been generated from package.yaml by hpack version 0.31.0.
+  ++-- This file has been generated from package.yaml by hpack version 0.31.1.
+  ```
+
 ## 0.5.0 - Sorted Fields Pretty Printing
+
 * Sort fields when pretty printing JSON and YAML.
-* Add real world golden tests, using stack and hpack packages.
+* Add real world golden tests, using stack and Hpack packages.
 
 ## 0.4.0 - Split Executables
+
 * Add licence and copyright.
-* Rename hpack-dhall to dhall-hpack-cabal.
-* Add dhall-hpack-* executables for showing dhall, json and yaml.
+* Rename the executable `hpack-dhall` to `dhall-hpack-cabal`.
+* Add `dhall-hpack-*` executables for showing Dhall, JSON and YAML.
diff --git a/exe/Options.hs b/exe/Options.hs
new file mode 100644
--- /dev/null
+++ b/exe/Options.hs
@@ -0,0 +1,123 @@
+{-# LANGUAGE ApplicativeDo #-}
+{-# LANGUAGE RecordWildCards #-}
+
+module Options
+  ( Options (..)
+  , parseNumericVersion
+  , parseVersion
+  , parseOptions
+  , parsePkgYamlFile
+  , parsePkgDhallFile
+  , parseForce
+  , parseQuiet
+  , parserInfo
+  , Command (..)
+
+    -- ** Globs
+  , GlobOptions (..)
+  , parsePkgGlobs
+  , parseIgnoreGlobs
+  , parseGlobOptions
+  ) where
+
+import qualified Hpack.Config as HpackYaml (packageConfig)
+import qualified Hpack.Dhall as HpackDhall (packageConfig)
+import Options.Applicative
+
+newtype Options = Options {pkgDhallFile :: FilePath}
+
+data Command a = NumericVersion | Version | Run a
+
+parserInfo :: Parser a -> String -> String -> ParserInfo (Command a)
+parserInfo parseOpts h d =
+  info parser $
+    fullDesc
+      <> header h
+      <> progDesc d
+  where
+    parser =
+      asum
+        [ NumericVersion <$ parseNumericVersion
+        , Version <$ parseVersion
+        , Run <$> parseOpts
+        ]
+
+data GlobOptions = GlobOptions
+  { force :: Bool
+  , quiet :: Bool
+  , pkgGlobs :: [String]
+  , ignoreGlobs :: [String]
+  }
+
+parseGlobOptions :: String -> Parser GlobOptions
+parseGlobOptions filename =
+  helper <*> do
+    force <- parseForce
+    quiet <- parseQuiet
+    pkgGlobs <- parsePkgGlobs filename
+    ignoreGlobs <- parseIgnoreGlobs filename
+    return GlobOptions{..}
+
+parseOptions :: Parser Options
+parseOptions =
+  helper <*> do
+    pkgDhallFile <- parsePkgDhallFile
+    return Options{..}
+
+parsePkgYamlFile :: Parser FilePath
+parsePkgYamlFile =
+  strOption $
+    long "package-yaml"
+      <> metavar "FILE"
+      <> value HpackYaml.packageConfig
+      <> showDefault
+      <> help "A record of hpack fields"
+
+parsePkgDhallFile :: Parser FilePath
+parsePkgDhallFile =
+  strOption $
+    long "package-dhall"
+      <> metavar "FILE"
+      <> value HpackDhall.packageConfig
+      <> showDefault
+      <> help "A record of hpack fields"
+
+parseNumericVersion :: Parser ()
+parseNumericVersion =
+  flag' () $
+    long "numeric-version"
+      <> help "Show version only"
+
+parseVersion :: Parser ()
+parseVersion =
+  flag' () $
+    long "version"
+      <> help "Show app name and version"
+
+parseForce :: Parser Bool
+parseForce =
+  flag False True $
+    long "force"
+      <> short 'f'
+      <> help "Overwrite of the output .cabal file unnecessarily"
+
+parseQuiet :: Parser Bool
+parseQuiet =
+  flag False True $
+    long "silent"
+      <> help "Suppress logging"
+
+parsePkgGlobs :: String -> Parser [String]
+parsePkgGlobs name =
+  many . strOption $
+    long (map (\c -> if c == '.' then '-' else c) name)
+      <> metavar "GLOB"
+      <> help ("Glob pattern to include when searching for '" ++ name ++ "' (or otherwise named) package files. Can be specified multiple times.")
+
+parseIgnoreGlobs :: String -> Parser [String]
+parseIgnoreGlobs name =
+  many . strOption $
+    long "ignore-glob"
+      <> short 'i'
+      <> metavar "GLOB"
+      <> help ("Glob pattern to ignore when searching for '" ++ name ++ "' files. Can be specified multiple times.")
diff --git a/exe/dhall-hpack-cabal/CabalMain.hs b/exe/dhall-hpack-cabal/CabalMain.hs
--- a/exe/dhall-hpack-cabal/CabalMain.hs
+++ b/exe/dhall-hpack-cabal/CabalMain.hs
@@ -1,68 +1,42 @@
-{-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ApplicativeDo #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE RecordWildCards #-}
 
 module Main (main) where
 
-import Paths_hpack_dhall (version)
 import Data.Version (showVersion)
-import Data.Foldable (asum)
+import qualified Hpack as H (getOptions, hpack, setDecode, version)
+import Hpack.Dhall (dhallFileToJson)
+import Options (Command (..), parseForce, parsePkgDhallFile, parseQuiet, parserInfo)
 import qualified Options.Applicative as O
-import Options
-    ( parsePkgFile, parseNumericVersion, parseVersion
-    , parseForce, parseQuiet
-    )
-import qualified Hpack as H (hpack, version, getOptions, setDecode)
-import Hpack.Dhall (fileToJson)
-
-data Command = NumericVersion | Version | Run Options
+import Paths_hpack_dhall (version)
 
-data Options =
-    Options
-        { pkgFile :: String
-        , force :: Bool
-        , quiet :: Bool
-        }
+data Options = Options
+  { pkgDhallFile :: String
+  , force :: Bool
+  , quiet :: Bool
+  }
 
 parseOptions :: O.Parser Options
-parseOptions = O.helper <*> do
-    pkgFile <- parsePkgFile
+parseOptions =
+  O.helper <*> do
+    pkgDhallFile <- parsePkgDhallFile
     force <- parseForce
     quiet <- parseQuiet
     return Options{..}
 
-parserInfo :: O.ParserInfo Command
-parserInfo =
-    O.info parser $
-        O.fullDesc
-        <> O.header "Hpack's dhalling"
-        <> O.progDesc "Write the .cabal for a .dhall package description, resolving imports."
-    where
-        parser = asum
-            [ NumericVersion <$ parseNumericVersion
-            , Version <$ parseVersion
-            , Run <$> parseOptions
-            ]
-
 main :: IO ()
-main = do
-    command <- O.execParser parserInfo
-
-    case command of
-        NumericVersion ->
-            putStrLn $ showVersion version
-
-        Version -> do
-            putStrLn $ "dhall-hpack-cabal-" ++ showVersion version
-            putStrLn $ "hpack-" ++ showVersion H.version
-
-        Run Options{..} -> do
-            opts <- H.getOptions pkgFile $
-                mconcat
-                    [ [ "--force" | force ]
-                    , [ "--silent" | quiet ]
-                    ]
-            case opts of
-                Just (verbose, options) ->
-                    H.hpack verbose (H.setDecode fileToJson options)
-                Nothing ->
-                    return ()
+main =
+  O.execParser (parserInfo parseOptions header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "dhall-hpack-cabal-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run Options{..} -> do
+      opts <- H.getOptions pkgDhallFile $ ["--force" | force] ++ ["--silent" | quiet]
+      case opts of
+        Just (verbose, options) -> H.hpack verbose (H.setDecode dhallFileToJson options)
+        Nothing -> return ()
+  where
+    header = "Hpack's dhalling"
+    description = "Write the .cabal for a .dhall package description, resolving imports."
diff --git a/exe/dhall-hpack-dhall/DhallMain.hs b/exe/dhall-hpack-dhall/DhallMain.hs
--- a/exe/dhall-hpack-dhall/DhallMain.hs
+++ b/exe/dhall-hpack-dhall/DhallMain.hs
@@ -1,43 +1,23 @@
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Main (main) where
 
-import Paths_hpack_dhall (version)
 import Data.Version (showVersion)
-import Data.Foldable (asum)
-import qualified Options.Applicative as O
-import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)
-import Hpack.Dhall (showDhall)
 import qualified Hpack as H (version)
-
-data Command = NumericVersion | Version | Run Options
-
-parserInfo :: O.ParserInfo Command
-parserInfo =
-    O.info parser $
-        O.fullDesc
-        <> O.header "Hpack as Dhall"
-        <> O.progDesc "Show a package description expression with imports resolved."
-    where
-        parser = asum
-            [ NumericVersion <$ parseNumericVersion
-            , Version <$ parseVersion
-            , Run <$> parseOptions
-            ]
+import Hpack.Dhall (showDhall)
+import Options (Command (..), Options (..), parseOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
 
 main :: IO ()
-main = do
-    command <- O.execParser parserInfo
-
-    case command of
-        NumericVersion ->
-            putStrLn $ showVersion version
-
-        Version -> do
-            putStrLn $ "dhall-hpack-dhall-" ++ showVersion version
-            putStrLn $ "hpack-" ++ showVersion H.version
-
-        Run Options{..} -> do
-            s <- showDhall pkgFile
-            putStrLn s
-            return ()
+main =
+  execParser (parserInfo parseOptions header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "dhall-hpack-dhall-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run Options{..} -> showDhall pkgDhallFile >>= putStrLn
+  where
+    header = "Hpack as Dhall"
+    description = "Show a package description expression with imports resolved."
diff --git a/exe/dhall-hpack-json/JsonMain.hs b/exe/dhall-hpack-json/JsonMain.hs
--- a/exe/dhall-hpack-json/JsonMain.hs
+++ b/exe/dhall-hpack-json/JsonMain.hs
@@ -1,43 +1,23 @@
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Main (main) where
 
-import Paths_hpack_dhall (version)
 import Data.Version (showVersion)
-import Data.Foldable (asum)
-import qualified Options.Applicative as O
-import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)
-import Hpack.Dhall (showJson)
 import qualified Hpack as H (version)
-
-data Command = NumericVersion | Version | Run Options
-
-parserInfo :: O.ParserInfo Command
-parserInfo =
-    O.info parser $
-        O.fullDesc
-        <> O.header "Hpack as JSON"
-        <> O.progDesc "Show a package description as JSON."
-    where
-        parser = asum
-            [ NumericVersion <$ parseNumericVersion
-            , Version <$ parseVersion
-            , Run <$> parseOptions
-            ]
+import Hpack.Dhall (showJson)
+import Options (Command (..), Options (..), parseOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
 
 main :: IO ()
-main = do
-    command <- O.execParser parserInfo
-
-    case command of
-        NumericVersion ->
-            putStrLn $ showVersion version
-
-        Version -> do
-            putStrLn $ "dhall-hpack-json-" ++ showVersion version
-            putStrLn $ "hpack-" ++ showVersion H.version
-
-        Run Options{..} -> do
-            s <- showJson Nothing pkgFile
-            putStrLn s
-            return ()
+main =
+  execParser (parserInfo parseOptions header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "dhall-hpack-json-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run Options{..} -> showJson Nothing pkgDhallFile >>= putStrLn
+  where
+    header = "Hpack as JSON"
+    description = "Show a package description as JSON."
diff --git a/exe/dhall-hpack-yaml/YamlMain.hs b/exe/dhall-hpack-yaml/YamlMain.hs
--- a/exe/dhall-hpack-yaml/YamlMain.hs
+++ b/exe/dhall-hpack-yaml/YamlMain.hs
@@ -1,43 +1,23 @@
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Main (main) where
 
-import Paths_hpack_dhall (version)
 import Data.Version (showVersion)
-import Data.Foldable (asum)
-import qualified Options.Applicative as O
-import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)
-import Hpack.Dhall (showYaml)
 import qualified Hpack as H (version)
-
-data Command = NumericVersion | Version | Run Options
-
-parserInfo :: O.ParserInfo Command
-parserInfo =
-    O.info parser $
-        O.fullDesc
-        <> O.header "Hpack as YAML"
-        <> O.progDesc "Show a package description as YAML."
-    where
-        parser = asum
-            [ NumericVersion <$ parseNumericVersion
-            , Version <$ parseVersion
-            , Run <$> parseOptions
-            ]
+import Hpack.Dhall (showYaml)
+import Options (Command (..), Options (..), parseOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
 
 main :: IO ()
-main = do
-    command <- O.execParser parserInfo
-
-    case command of
-        NumericVersion ->
-            putStrLn $ showVersion version
-
-        Version -> do
-            putStrLn $ "dhall-hpack-yaml-" ++ showVersion version
-            putStrLn $ "hpack-" ++ showVersion H.version
-
-        Run Options{..} -> do
-            s <- showYaml Nothing pkgFile
-            putStrLn s
-            return ()
+main =
+  execParser (parserInfo parseOptions header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "dhall-hpack-yaml-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run Options{..} -> showYaml Nothing pkgDhallFile >>= putStrLn
+  where
+    header = "Hpack as YAML"
+    description = "Show a package description as YAML."
diff --git a/exe/options/Options.hs b/exe/options/Options.hs
deleted file mode 100644
--- a/exe/options/Options.hs
+++ /dev/null
@@ -1,56 +0,0 @@
-{-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE ApplicativeDo #-}
-
-module Options
-    ( Options(..)
-    , parseNumericVersion
-    , parseVersion
-    , parseOptions
-    , parsePkgFile
-    , parseForce
-    , parseQuiet
-    ) where
-
-import Hpack.Dhall (packageConfig)
-import Options.Applicative
-
-newtype Options = Options {pkgFile :: FilePath}
-
-parseOptions :: Parser Options
-parseOptions = helper <*> do
-    pkgFile <- parsePkgFile
-    return Options{..}
-
-parsePkgFile :: Parser FilePath
-parsePkgFile =
-    strOption $
-    long "package-dhall"
-    <> metavar "FILE"
-    <> value packageConfig
-    <> showDefault
-    <> help "A record of hpack fields"
-
-parseNumericVersion :: Parser ()
-parseNumericVersion =
-    flag' () $
-    long "numeric-version"
-    <> help "Show version only"
-
-parseVersion :: Parser ()
-parseVersion =
-    flag' () $
-    long "version"
-    <> help "Show app name and version"
-
-parseForce :: Parser Bool
-parseForce =
-    flag False True $
-    long "force"
-    <> short 'f'
-    <> help "Overwrite of the output .cabal file unnecessarily"
-
-parseQuiet :: Parser Bool
-parseQuiet =
-    flag False True $
-    long "silent"
-    <> help "Suppress logging"
diff --git a/exe/yaml-hpack-cabal/CabalMain.hs b/exe/yaml-hpack-cabal/CabalMain.hs
new file mode 100644
--- /dev/null
+++ b/exe/yaml-hpack-cabal/CabalMain.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE ApplicativeDo #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE RecordWildCards #-}
+
+module Main (main) where
+
+import Data.Foldable (asum)
+import Data.Version (showVersion)
+import qualified Hpack as H (Options (..), getOptions, hpack, version)
+import Hpack.Config (DecodeOptions (..), defaultDecodeOptions)
+import Options
+  ( parseForce
+  , parseNumericVersion
+  , parsePkgYamlFile
+  , parseQuiet
+  , parseVersion
+  )
+import qualified Options.Applicative as O
+import Paths_hpack_dhall (version)
+
+data Command = NumericVersion | Version | Run Options
+
+data Options = Options
+  { pkgYamlFile :: String
+  , force :: Bool
+  , quiet :: Bool
+  }
+
+parseOptions :: O.Parser Options
+parseOptions =
+  O.helper <*> do
+    pkgYamlFile <- parsePkgYamlFile
+    force <- parseForce
+    quiet <- parseQuiet
+    return Options{..}
+
+parserInfo :: O.ParserInfo Command
+parserInfo =
+  O.info parser $
+    O.fullDesc
+      <> O.header "Hpack's dhalling"
+      <> O.progDesc "Write the .cabal for a .yaml package description, same thing hpack does."
+  where
+    parser =
+      asum
+        [ NumericVersion <$ parseNumericVersion
+        , Version <$ parseVersion
+        , Run <$> parseOptions
+        ]
+
+main :: IO ()
+main =
+  O.execParser parserInfo >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "dhall-hpack-cabal-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run Options{..} -> do
+      opts <- H.getOptions pkgYamlFile $ ["--force" | force] ++ ["--silent" | quiet]
+      case opts of
+        Just (verbose, options) ->
+          H.hpack verbose $
+            options
+              { H.optionsDecodeOptions =
+                  defaultDecodeOptions{decodeOptionsTarget = pkgYamlFile}
+              }
+        Nothing -> return ()
diff --git a/hook/RecurseFile.hs b/hook/RecurseFile.hs
new file mode 100644
--- /dev/null
+++ b/hook/RecurseFile.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE TupleSections #-}
+
+module RecurseFile where
+
+import qualified Data.ByteString as BS
+import Data.List.Extra (drop1, isPrefixOf)
+import System.Directory.Extra (doesDirectoryExist, doesFileExist, listFilesInside)
+import System.Exit
+import System.FilePath (isPathSeparator, takeExtension, takeFileName, (</>))
+import System.FilePattern
+import System.IO (hPutStrLn, stderr)
+
+-- | SEE: https://github.com/ndmitchell/hlint/blob/086bf4430362ccced79ba2363840952eec67382a/src/CmdLine.hs#L245
+(<\>) :: String -> FilePath -> FilePath
+"." <\> x = x
+x <\> y = x </> y
+
+-- SEE: https://github.com/ndmitchell/hlint/blob/086bf4430362ccced79ba2363840952eec67382a/src/Util.hs#L30-L33
+exitMessage :: String -> IO a
+exitMessage msg = do
+  hPutStrLn stderr msg
+  exitWith $ ExitFailure 1
+
+-- | SEE: https://github.com/ndmitchell/hlint/blob/086bf4430362ccced79ba2363840952eec67382a/src/CmdLine.hs#L249-L263
+resolveFile :: [FilePattern] -> [FilePattern] -> Maybe FilePath -> FilePath -> IO [FilePath]
+resolveFile includeGlobs ignoreGlobs =
+  getFile
+    (toPredicate includeGlobs)
+    (toPredicate ignoreGlobs)
+    ["."]
+    ["dhall"]
+  where
+    toPredicate :: [FilePattern] -> FilePath -> Bool
+    toPredicate [] = const False
+    toPredicate globs = \x -> not $ null $ m [((), cleanup x)]
+      where
+        m = matchMany (map ((),) globs)
+
+    cleanup :: FilePath -> FilePath
+    cleanup ('.' : x : xs) | isPathSeparator x, not $ null xs = xs
+    cleanup x = x
+
+-- | SEE: https://github.com/ndmitchell/hlint/blob/086bf4430362ccced79ba2363840952eec67382a/src/CmdLine.hs#L266-L288
+getFile :: (FilePath -> Bool) -> (FilePath -> Bool) -> [FilePath] -> [String] -> Maybe FilePath -> FilePath -> IO [FilePath]
+getFile _ _ _ _ (Just tmpfile) "-" =
+  -- make sure we don't reencode any Unicode
+  BS.getContents >>= BS.writeFile tmpfile >> pure [tmpfile]
+getFile _ _ _ _ Nothing "-" = pure ["-"]
+getFile _ _ [] _ _ file = exitMessage $ "Couldn't find file: " ++ file
+getFile include ignore (p : ath) exts t file = do
+  isDir <- doesDirectoryExist $ p <\> file
+  if isDir
+    then do
+      let ignoredDirectories = ["dist", "dist-newstyle"]
+          avoidDir x = let y = takeFileName x in "_" `isPrefixOf` y || ("." `isPrefixOf` y && not (all (== '.') y)) || y `elem` ignoredDirectories || ignore x
+          avoidFile x = let y = takeFileName x in "." `isPrefixOf` y || ignore x
+      xs <- listFilesInside (pure . not . avoidDir) $ p <\> file
+      pure [x | x <- xs, drop1 (takeExtension x) `elem` exts, not $ avoidFile x, include x]
+    else do
+      isFil <- doesFileExist $ p <\> file
+      if isFil
+        then pure [p <\> file | not $ ignore $ p <\> file]
+        else getFile include ignore ath exts t file
diff --git a/hook/cabal-diy-pack/DiyPackMain.hs b/hook/cabal-diy-pack/DiyPackMain.hs
new file mode 100644
--- /dev/null
+++ b/hook/cabal-diy-pack/DiyPackMain.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
+
+module Main (main) where
+
+import Data.Foldable (forM_)
+import Data.Version (showVersion)
+import qualified Hpack as H (getOptions, version)
+import Hpack.Dhall (packageConfig, showYaml)
+import Options (Command (..), GlobOptions (..), parseGlobOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
+import RecurseFile (resolveFile)
+import System.FilePath (replaceExtension)
+
+main :: IO ()
+main =
+  execParser (parserInfo parseOpts header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "cabal-diy-pack-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run GlobOptions{pkgGlobs = pfs, quiet, force, ignoreGlobs} -> do
+      let includeGlobs = if null pfs then ["**/package.dhall"] else pfs
+      pkgFiles <- resolveFile includeGlobs ignoreGlobs Nothing "."
+      forM_ pkgFiles $ \pkgDhallFile -> do
+        opts <- H.getOptions pkgDhallFile $ ["--force" | force] ++ ["--silent" | quiet]
+        case opts of
+          Just{} -> showYaml Nothing pkgDhallFile >>= writeFile (replaceExtension pkgDhallFile ".yaml")
+          Nothing -> return ()
+  where
+    parseOpts = parseGlobOptions packageConfig
+    header = "Cabal Dhall-Into-Yaml hook, for converting package.dhall into package.yaml."
+    description = "Write the .cabal for a .dhall package description, resolving imports."
diff --git a/hook/cabal-dpack/DpackMain.hs b/hook/cabal-dpack/DpackMain.hs
new file mode 100644
--- /dev/null
+++ b/hook/cabal-dpack/DpackMain.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
+
+module Main (main) where
+
+import Data.Foldable (forM_)
+import Data.Version (showVersion)
+import qualified Hpack as H (getOptions, hpack, setDecode, version)
+import Hpack.Dhall (dhallFileToJson, packageConfig)
+import Options (Command (..), GlobOptions (..), parseGlobOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
+import RecurseFile (resolveFile)
+
+main :: IO ()
+main =
+  execParser (parserInfo parseOpts header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "cabal-dpack-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run GlobOptions{pkgGlobs = pfs, quiet, force, ignoreGlobs} -> do
+      let includeGlobs = if null pfs then ["**/package.dhall"] else pfs
+      pkgFiles <- resolveFile includeGlobs ignoreGlobs Nothing "."
+      forM_ pkgFiles $ \pkgFile -> do
+        opts <- H.getOptions pkgFile $ ["--force" | force] ++ ["--silent" | quiet]
+        case opts of
+          Just (verbose, options) -> H.hpack verbose (H.setDecode dhallFileToJson options)
+          Nothing -> return ()
+  where
+    parseOpts = parseGlobOptions packageConfig
+    header = "Cabal hook for converting package.dhall to <package-name>.cabal"
+    description = "Write the .cabal for a .dhall package description, resolving imports."
diff --git a/hook/cabal-ypack/YpackMain.hs b/hook/cabal-ypack/YpackMain.hs
new file mode 100644
--- /dev/null
+++ b/hook/cabal-ypack/YpackMain.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
+
+module Main (main) where
+
+import Data.Foldable (forM_)
+import Data.Version (showVersion)
+import qualified Hpack as H (Options (..), getOptions, hpack, version)
+import Hpack.Config (DecodeOptions (..), defaultDecodeOptions, packageConfig)
+import Options (Command (..), GlobOptions (..), parseGlobOptions, parserInfo)
+import Options.Applicative (execParser)
+import Paths_hpack_dhall (version)
+import RecurseFile (resolveFile)
+
+main :: IO ()
+main =
+  execParser (parserInfo parseOpts header description) >>= \case
+    NumericVersion -> putStrLn $ showVersion version
+    Version -> do
+      putStrLn $ "cabal-ypack-" ++ showVersion version
+      putStrLn $ "hpack-" ++ showVersion H.version
+    Run GlobOptions{pkgGlobs = pfs, quiet, force, ignoreGlobs} -> do
+      let includeGlobs = if null pfs then ["**/package.yaml"] else pfs
+      pkgFiles <- resolveFile includeGlobs ignoreGlobs Nothing "."
+      forM_ pkgFiles $ \pkgYamlFile -> do
+        opts <- H.getOptions pkgYamlFile $ ["--force" | force] ++ ["--silent" | quiet]
+        case opts of
+          Just (verbose, options) ->
+            H.hpack verbose $
+              options
+                { H.optionsDecodeOptions =
+                    defaultDecodeOptions{decodeOptionsTarget = pkgYamlFile}
+                }
+          Nothing -> return ()
+  where
+    parseOpts = parseGlobOptions packageConfig
+    header = "Cabal hook for converting package.yaml to <package-name>.cabal"
+    description = "Write the .cabal for a .dhall package description, resolving imports."
diff --git a/hpack-dhall.cabal b/hpack-dhall.cabal
--- a/hpack-dhall.cabal
+++ b/hpack-dhall.cabal
@@ -1,33 +1,24 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.34.7.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
 name:           hpack-dhall
-version:        0.5.7
-synopsis:       hpack's dhalling
-description:    Use hpack phrasing in dhall to write cabal files.
-                .
-                There are two main reasons why you'd use hpack-dhall, convenience and safety.
-                .
-                Get the convenience of hpack. Don't bother to state what can be inferred or
-                defaulted, easing the burden of completing a package description by hand.  For
-                example `other-modules` can be inferred by taking the set difference between
-                modules on disk and the set of `exposed-modules`.
-                .
-                Get the safety of dhall's programmable configuration: typed fields, safe imports
-                and functions.
+version:        0.6.0
+synopsis:       Hpack with Dhall
+description:    Hpack-Dhall brings functions, types and file imports to Haskell
+                packaging.  It is Hpack with Dhall.
 category:       Development
 homepage:       https://github.com/cabalism/hpack-dhall#readme
 bug-reports:    https://github.com/cabalism/hpack-dhall/issues
 maintainer:     Phil de Joux <phil.dejoux@blockscope.com>
-copyright:      © 2018 - 2022 Phil de Joux, © 2018 - 2022 Block Scope Limited
+copyright:      © 2018 - 2026 Phil de Joux, © 2018 - 2026 Block Scope Limited
 license:        BSD3
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.2
+    GHC == 9.2.8, GHC == 9.4.8, GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.3, GHC == 9.12.4
 extra-source-files:
     package.dhall
     changelog.md
@@ -129,22 +120,124 @@
       library
   ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
   build-depends:
-      aeson
-    , aeson-pretty
+      aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , prettyprinter
-    , text
-    , transformers
-    , yaml
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
   default-language: Haskell2010
 
+executable cabal-diy-pack
+  main-is: DiyPackMain.hs
+  other-modules:
+      Hpack.Dhall
+      Hpack.Fields
+      Options
+      RecurseFile
+      Paths_hpack_dhall
+  hs-source-dirs:
+      library
+      exe
+      hook
+      hook/cabal-diy-pack
+  ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
+  build-depends:
+      aeson <3
+    , aeson-pretty <1
+    , base >=4.13 && <5
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , extra <2
+    , filepath <2
+    , filepattern <1
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
+  default-language: Haskell2010
+
+executable cabal-dpack
+  main-is: DpackMain.hs
+  other-modules:
+      Hpack.Dhall
+      Hpack.Fields
+      Options
+      RecurseFile
+      Paths_hpack_dhall
+  hs-source-dirs:
+      library
+      exe
+      hook
+      hook/cabal-dpack
+  ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
+  build-depends:
+      aeson <3
+    , aeson-pretty <1
+    , base >=4.13 && <5
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , extra <2
+    , filepath <2
+    , filepattern <1
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
+  default-language: Haskell2010
+
+executable cabal-ypack
+  main-is: YpackMain.hs
+  other-modules:
+      Hpack.Dhall
+      Hpack.Fields
+      Options
+      RecurseFile
+      Paths_hpack_dhall
+  hs-source-dirs:
+      library
+      exe
+      hook
+      hook/cabal-ypack
+  ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
+  build-depends:
+      aeson <3
+    , aeson-pretty <1
+    , base >=4.13 && <5
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , extra <2
+    , filepath <2
+    , filepattern <1
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
+  default-language: Haskell2010
+
 executable dhall-hpack-cabal
   main-is: CabalMain.hs
   other-modules:
@@ -154,25 +247,25 @@
       Paths_hpack_dhall
   hs-source-dirs:
       library
-      exe/options
+      exe
       exe/dhall-hpack-cabal
   ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
   build-depends:
-      aeson
-    , aeson-pretty
+      aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , optparse-applicative
-    , prettyprinter
-    , text
-    , transformers
-    , yaml
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
   default-language: Haskell2010
 
 executable dhall-hpack-dhall
@@ -184,25 +277,25 @@
       Paths_hpack_dhall
   hs-source-dirs:
       library
-      exe/options
+      exe
       exe/dhall-hpack-dhall
   ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
   build-depends:
-      aeson
-    , aeson-pretty
+      aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , optparse-applicative
-    , prettyprinter
-    , text
-    , transformers
-    , yaml
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
   default-language: Haskell2010
 
 executable dhall-hpack-json
@@ -214,25 +307,25 @@
       Paths_hpack_dhall
   hs-source-dirs:
       library
-      exe/options
+      exe
       exe/dhall-hpack-json
   ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
   build-depends:
-      aeson
-    , aeson-pretty
+      aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , optparse-applicative
-    , prettyprinter
-    , text
-    , transformers
-    , yaml
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
   default-language: Haskell2010
 
 executable dhall-hpack-yaml
@@ -244,27 +337,57 @@
       Paths_hpack_dhall
   hs-source-dirs:
       library
-      exe/options
+      exe
       exe/dhall-hpack-yaml
   ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
   build-depends:
-      aeson
-    , aeson-pretty
+      aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , optparse-applicative
-    , prettyprinter
-    , text
-    , transformers
-    , yaml
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
   default-language: Haskell2010
 
+executable yaml-hpack-cabal
+  main-is: CabalMain.hs
+  other-modules:
+      Hpack.Dhall
+      Hpack.Fields
+      Options
+      Paths_hpack_dhall
+  hs-source-dirs:
+      library
+      exe
+      exe/yaml-hpack-cabal
+  ghc-options: -Wall -Wincomplete-uni-patterns -Wcompat -Widentities -Wredundant-constraints -fhide-source-paths
+  build-depends:
+      aeson <3
+    , aeson-pretty <1
+    , base >=4.13 && <5
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , optparse-applicative <0.20
+    , prettyprinter <2
+    , text <3
+    , transformers <0.7
+    , yaml <0.12
+  default-language: Haskell2010
+
 test-suite golden
   type: exitcode-stdio-1.0
   main-is: Golden.hs
@@ -279,22 +402,22 @@
   build-depends:
       Cabal
     , Diff
-    , aeson
-    , aeson-pretty
+    , aeson <3
+    , aeson-pretty <1
     , base >=4.13 && <5
-    , bytestring
-    , dhall >=1.41.1
-    , dhall-json >=1.7.10
+    , bytestring <0.13
+    , dhall >=1.41.1 && <2
+    , dhall-json >=1.7.10 && <2
     , directory
-    , filepath
-    , hpack ==0.35.*
-    , megaparsec >=9.2
-    , microlens
-    , prettyprinter
+    , filepath <2
+    , hpack >=0.39.6 && <1
+    , megaparsec >=9.2 && <10
+    , microlens <0.6
+    , prettyprinter <2
     , tasty
     , tasty-golden
-    , text
-    , transformers
+    , text <3
+    , transformers <0.7
     , utf8-string
-    , yaml
+    , yaml <0.12
   default-language: Haskell2010
diff --git a/library/Hpack/Dhall.hs b/library/Hpack/Dhall.hs
--- a/library/Hpack/Dhall.hs
+++ b/library/Hpack/Dhall.hs
@@ -1,71 +1,73 @@
 {-# LANGUAGE TupleSections #-}
 
-{-|
-Module: Hpack.Dhall
-Copyright:
-    © 2018 - 2021 Phil de Joux
-    © 2018 - 2021 Block Scope Limited
-License: BSD3
-Maintainer: Phil de Joux <phil.dejoux@blockscope.com>
-Stability: experimental
-The functions in this module make it possible to configure an
-<https://github.com/sol/hpack#readme hpack>
-package description with
-<https://github.com/dhall-lang/dhall-lang#readme Dhall>
-instead of
-<https://en.wikipedia.org/wiki/YAML YAML>.
-When doing so, note that all functions resolve imports relative to the location
-of the given @.dhall@ input file.
--}
+-- |
+-- Module: Hpack.Dhall
+-- Copyright:
+--     © 2018 - 2021 Phil de Joux
+--     © 2018 - 2021 Block Scope Limited
+-- License: BSD3
+-- Maintainer: Phil de Joux <phil.dejoux@blockscope.com>
+-- Stability: experimental
+-- The functions in this module make it possible to configure an
+-- <https://github.com/sol/hpack#readme hpack>
+-- package description with
+-- <https://github.com/dhall-lang/dhall-lang#readme Dhall>
+-- instead of
+-- <https://en.wikipedia.org/wiki/YAML YAML>.
+-- When doing so, note that all functions resolve imports relative to the location
+-- of the given @.dhall@ input file.
 module Hpack.Dhall
-    ( fileToJson
-    , showJson
-    , showYaml
-    , showDhall
-    , packageConfig
-    ) where
+  ( dhallFileToJson
+  , showJson
+  , showYaml
+  , showDhall
+  , packageConfig
+  ) where
 
-import Data.Void (Void)
-import Data.Maybe (fromMaybe)
-import Data.Function ((&))
-import Lens.Micro ((^.), set)
-import System.FilePath (takeDirectory)
 import Control.Exception (throwIO)
-import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
 import Control.Monad.IO.Class (liftIO)
+import Control.Monad.Trans.Except (ExceptT (..), runExceptT)
 import qualified Control.Monad.Trans.State.Strict as State
-import Data.Bifunctor (first)
 import Data.Aeson (ToJSON, Value)
+import qualified Data.Aeson.Encode.Pretty as A
+import Data.Bifunctor (first)
 import qualified Data.ByteString.Lazy as BSL (toStrict)
-import Data.Text.Encoding (decodeUtf8)
+import Data.Function ((&))
+import Data.Maybe (fromMaybe)
 import qualified Data.Text as T (Text, unpack)
+import Data.Text.Encoding (decodeUtf8)
 import qualified Data.Text.IO as T (readFile)
+import Data.Void (Void)
+import qualified Data.Yaml.Pretty as Y
 import Dhall
-    ( InputSettings, Text
-    , rootDirectory, sourceName, defaultInputSettings
-    )
+  ( InputSettings
+  , Text
+  , defaultInputSettings
+  , rootDirectory
+  , sourceName
+  )
 import Dhall.Core (Expr)
+import Dhall.Import (emptyStatus, loadWith)
+import Dhall.JSON (dhallToJSON, omitNull)
 import Dhall.Parser (Src, exprFromText)
-import Dhall.Import (loadWith, emptyStatus)
+import Dhall.Pretty (layoutOpts, prettyExpr)
 import Dhall.TypeCheck (typeOf)
-import Dhall.JSON (dhallToJSON)
-import Dhall.Pretty (prettyExpr, layoutOpts)
+import Hpack.Fields (cmp)
+import Lens.Micro (set, (^.))
 import qualified Prettyprinter as PP
 import qualified Prettyprinter.Render.Text as PP
-import qualified Data.Yaml.Pretty as Y
-import qualified Data.Aeson.Encode.Pretty as A
-import Hpack.Fields (cmp)
+import System.FilePath (takeDirectory)
 
 -- SEE: http://onoffswitch.net/adventures-pretty-printing-json-haskell/
 getJson :: ToJSON a => (Text -> Text -> Ordering) -> a -> String
 getJson cmp' =
-    let cfg = A.defConfig {A.confCompare = cmp'}
-    in T.unpack . decodeUtf8 . BSL.toStrict . A.encodePretty' cfg
+  let cfg = A.defConfig{A.confCompare = cmp'}
+   in T.unpack . decodeUtf8 . BSL.toStrict . A.encodePretty' cfg
 
 getYaml :: ToJSON a => (Text -> Text -> Ordering) -> a -> String
 getYaml cmp' =
-    let cfg = Y.setConfCompare cmp' Y.defConfig
-    in T.unpack . decodeUtf8 . Y.encodePretty cfg
+  let cfg = Y.setConfCompare cmp' Y.defConfig
+   in T.unpack . decodeUtf8 . Y.encodePretty cfg
 
 -- | The default package file name is @package.dhall@.
 packageConfig :: FilePath
@@ -73,76 +75,78 @@
 
 -- | Pretty prints JSON for the package description.
 showJson
-    :: Maybe (Text -> Text -> Ordering)
-    -- ^ An ordering of JSON fields.
-    -> FilePath
-    -- ^ Path to a @.dhall@ file
-    -> IO String
+  :: Maybe (Text -> Text -> Ordering)
+  -- ^ An ordering of JSON fields.
+  -> FilePath
+  -- ^ Path to a @.dhall@ file
+  -> IO String
 showJson fieldOrdering file = do
-    x <- fileToJson file
-    return $ case x of
-        Left err -> err
-        Right (_, v) -> getJson (fromMaybe cmp fieldOrdering) v
+  x <- dhallFileToJson file
+  return $ case x of
+    Left err -> err
+    Right (_, v) -> getJson (fromMaybe cmp fieldOrdering) v
 
 -- | Pretty prints YAML for the package description.
 showYaml
-    :: Maybe (Text -> Text -> Ordering)
-    -- ^ An ordering of YAML fields.
-    -> FilePath
-    -- ^ Path to a @.dhall@ file
-    -> IO String
+  :: Maybe (Text -> Text -> Ordering)
+  -- ^ An ordering of YAML fields.
+  -> FilePath
+  -- ^ Path to a @.dhall@ file
+  -> IO String
 showYaml fieldOrdering file = do
-    x <- fileToJson file
-    return $ case x of
-        Left err -> err
-        Right (_, v) -> getYaml (fromMaybe cmp fieldOrdering) v
+  x <- dhallFileToJson file
+  return $ case x of
+    Left err -> err
+    Right (_, v) -> getYaml (fromMaybe cmp fieldOrdering) v
 
 -- | Pretty prints the package description Dhall expression, resolving imports
 -- relative to the location of the @.dhall@ file.
 showDhall
-    :: FilePath -- ^ Path to a @.dhall@ file
-    -> IO String
+  :: FilePath
+  -- ^ Path to a @.dhall@ file
+  -> IO String
 showDhall file = do
-    text <- T.readFile file
-    expr <- check (inputSettings file) text
-    return . T.unpack $ renderDhall expr
+  text <- T.readFile file
+  expr <- check (inputSettings file) text
+  return . T.unpack $ renderDhall expr
 
 -- | A file decoder for hpack. This should evaluate to a single record with
 -- hpack's top-level <https://github.com/sol/hpack#top-level-fields fields>.
-fileToJson
-    :: FilePath -- ^ Path to a @.dhall@ file
-    -> IO (Either String ([String], Value))
-fileToJson file =
-    liftIO (T.readFile file)
-    >>= textToJson (inputSettings file)
+dhallFileToJson
+  :: FilePath
+  -- ^ Path to a @.dhall@ file
+  -> IO (Either String ([String], Value))
+dhallFileToJson file =
+  liftIO (T.readFile file)
+    >>= dhallTextToJson (inputSettings file)
 
 inputSettings :: FilePath -> InputSettings
 inputSettings file =
-    Dhall.defaultInputSettings
+  Dhall.defaultInputSettings
     & set rootDirectory (takeDirectory file)
     & set sourceName file
 
-textToJson
-    :: InputSettings
-    -> T.Text
-    -> IO (Either String ([String], Value))
-textToJson settings text = runExceptT $ do
-    expr <- liftIO $ check settings text
-    _ <- liftResult $ typeOf expr
-    liftResult $ ([],) <$> dhallToJSON expr
-    where
-        liftResult :: (Show b, Monad m) => Either b a -> ExceptT String m a
-        liftResult = ExceptT . return . first show
+dhallTextToJson
+  :: InputSettings
+  -> T.Text
+  -> IO (Either String ([String], Value))
+dhallTextToJson settings text = runExceptT $ do
+  expr <- liftIO $ check settings text
+  _ <- liftResult $ typeOf expr
+  liftResult $ ([],) . omitNull <$> dhallToJSON expr
+  where
+    liftResult :: (Show b, Monad m) => Either b a -> ExceptT String m a
+    liftResult = ExceptT . return . first show
 
 check :: InputSettings -> Text -> IO (Expr Src Void)
 check settings text = do
-    expr <- either throwIO return $ exprFromText mempty text
-    State.evalStateT (loadWith expr) (emptyStatus $ settings ^. rootDirectory)
+  expr <- either throwIO return $ exprFromText mempty text
+  State.evalStateT (loadWith expr) (emptyStatus $ settings ^. rootDirectory)
 
 -- SEE: https://github.com/mstksg/hakyll-dhall
 renderDhall :: PP.Pretty a => Expr Src a -> T.Text
 renderDhall =
-    PP.renderStrict
+  PP.renderStrict
     . PP.layoutSmart layoutOpts
     . PP.unAnnotate
     . prettyExpr
diff --git a/library/Hpack/Fields.hs b/library/Hpack/Fields.hs
--- a/library/Hpack/Fields.hs
+++ b/library/Hpack/Fields.hs
@@ -1,44 +1,48 @@
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS_HADDOCK ignore-exports #-}
 
 module Hpack.Fields (cmp) where
 
-import Data.Maybe (fromMaybe)
 import Data.List (elemIndex)
-import Data.String (IsString())
+import Data.Maybe (fromMaybe)
+import Data.String (IsString ())
+#if !MIN_VERSION_base(4,18,0)
 import Control.Applicative (liftA2)
+#endif
 import Data.Foldable (asum)
 
 -- | A default field ordering comparison.
 cmp :: (Ord a, IsString a) => a -> a -> Ordering
 cmp a b =
-    fromMaybe fallback
+  fromMaybe fallback
     . asum
-    $ [ liftA2 compare (elemIndex a xs) (elemIndex b xs) | xs <- fields ]
-    where
-        -- NOTE: There can be short form conditions with no then or else. In
-        -- that case always put condition before the other field name.
-        fallback =
-            if | a == "condition" -> LT
-               | b == "condition" -> GT
-               | elem a topLevelFields -> LT
-               | elem b topLevelFields -> GT
-               | otherwise -> a `compare` b
+    $ [liftA2 compare (elemIndex a xs) (elemIndex b xs) | xs <- fields]
+  where
+    -- NOTE: There can be short form conditions with no then or else. In
+    -- that case always put condition before the other field name.
+    fallback =
+      if
+          | a == "condition" -> LT
+          | b == "condition" -> GT
+          | elem a topLevelFields -> LT
+          | elem b topLevelFields -> GT
+          | otherwise -> a `compare` b
 
-        fields =
-            [ topLevelFields
-            , libraryFields ++ commonFields
-            , runnableFields ++ commonFields
-            , flagFields
-            , conditionalFields
-            , defaultsFields
-            ]
+    fields =
+      [ topLevelFields
+      , libraryFields ++ commonFields
+      , runnableFields ++ commonFields
+      , flagFields
+      , conditionalFields
+      , defaultsFields
+      ]
 
 -- | All <https://github.com/sol/hpack#top-level-fields top-level> fields combined.
 topLevelFields :: IsString a => [a]
 topLevelFields =
-    headerFields
+  headerFields
     ++ repoFields
     ++ packageFields
     ++ commonFields
@@ -48,100 +52,99 @@
 -- <https://github.com/sol/hpack#top-level-fields top-level> fields.
 headerFields :: IsString a => [a]
 headerFields =
-    [ "spec-version"
-    , "name"
-    , "version"
-    , "synopsis"
-    , "description"
-    , "category"
-    , "stability"
-    , "homepage"
-    , "bug-reports"
-    , "author"
-    , "maintainer"
-    , "copyright"
-    , "license"
-    , "license-file"
-    , "license-files"
-    , "tested-with"
-    , "build-type"
-    ]
+  [ "spec-version"
+  , "name"
+  , "version"
+  , "synopsis"
+  , "description"
+  , "category"
+  , "stability"
+  , "homepage"
+  , "bug-reports"
+  , "author"
+  , "maintainer"
+  , "copyright"
+  , "license"
+  , "license-file"
+  , "license-files"
+  , "tested-with"
+  , "build-type"
+  ]
 
 -- | The package subset of
 -- <https://github.com/sol/hpack#top-level-fields top-level> fields.
 packageFields :: IsString a => [a]
 packageFields =
-    [ "extra-source-files"
-    , "extra-doc-files"
-    , "data-files"
-    , "data-dir"
-    ]
+  [ "extra-source-files"
+  , "extra-doc-files"
+  , "data-files"
+  , "data-dir"
+  ]
 
 -- | The source repository subset of
 -- <https://github.com/sol/hpack#top-level-fields top-level> fields.
 repoFields :: IsString a => [a]
 repoFields =
-    [ "github"
-    , "git"
-    ]
+  [ "github"
+  , "git"
+  ]
 
 -- | The stanzas subset of
 -- <https://github.com/sol/hpack#top-level-fields top-level> fields.
 stanzasFields :: IsString a => [a]
 stanzasFields =
-    [ "custom-setup"
-    , "flags"
-    , "library"
-    , "internal-libraries"
-    , "executables"
-    , "executable"
-    , "tests"
-    , "benchmarks"
-    , "defaults"
-    ]
+  [ "custom-setup"
+  , "flags"
+  , "library"
+  , "internal-libraries"
+  , "executables"
+  , "executable"
+  , "tests"
+  , "benchmarks"
+  , "defaults"
+  ]
 
 -- | The <https://github.com/sol/hpack#common-fields common> fields.
 commonFields :: IsString a => [a]
 commonFields =
-    [ "buildable"
-    , "source-dirs"
-    , "default-extensions"
-    , "other-extensions"
-    , "ghc-options"
-    , "ghc-prof-options"
-    , "ghcjs-options"
-    , "cpp-options"
-    , "cc-options"
-    , "c-sources"
-    , "cxx-options"
-    , "cxx-sources"
-    , "js-sources"
-    , "extra-lib-dirs"
-    , "extra-libraries"
-    , "include-dirs"
-    , "install-includes"
-    , "frameworks"
-    , "extra-framework-dirs"
-    , "ld-options"
-    , "dependencies"
-    , "pkg-config-depends"
-    , "build-tools"
-    , "system-build-tools"
-    , "when" -- conditional
-    ]
-
+  [ "buildable"
+  , "source-dirs"
+  , "default-extensions"
+  , "other-extensions"
+  , "ghc-options"
+  , "ghc-prof-options"
+  , "ghcjs-options"
+  , "cpp-options"
+  , "cc-options"
+  , "c-sources"
+  , "cxx-options"
+  , "cxx-sources"
+  , "js-sources"
+  , "extra-lib-dirs"
+  , "extra-libraries"
+  , "include-dirs"
+  , "install-includes"
+  , "frameworks"
+  , "extra-framework-dirs"
+  , "ld-options"
+  , "dependencies"
+  , "pkg-config-depends"
+  , "build-tools"
+  , "system-build-tools"
+  , "when" -- conditional
+  ]
 
 -- | The <https://github.com/sol/hpack#library-fields library> fields.
 libraryFields :: IsString a => [a]
 libraryFields =
-    [ "exposed"
-    , "exposed-modules"
-    , "generated-exposed-modules"
-    , "other-modules"
-    , "generated-other-modules"
-    , "reexported-modules"
-    , "signatures"
-    ]
+  [ "exposed"
+  , "exposed-modules"
+  , "generated-exposed-modules"
+  , "other-modules"
+  , "generated-other-modules"
+  , "reexported-modules"
+  , "signatures"
+  ]
 
 -- | The <https://github.com/sol/hpack#executable-fields executable>,
 -- <https://github.com/sol/hpack#test-fields test> and
@@ -149,32 +152,32 @@
 -- same.
 runnableFields :: IsString a => [a]
 runnableFields =
-    [ "main"
-    , "other-modules"
-    , "generated-other-modules"
-    ]
+  [ "main"
+  , "other-modules"
+  , "generated-other-modules"
+  ]
 
 -- | The <https://github.com/sol/hpack#flags flag> fields.
 flagFields :: IsString a => [a]
 flagFields =
-    [ "description"
-    , "manual"
-    , "default"
-    ]
+  [ "description"
+  , "manual"
+  , "default"
+  ]
 
 -- | The <https://github.com/sol/hpack#-conditionals conditional> fields.
 conditionalFields :: IsString a => [a]
 conditionalFields =
-    [ "condition"
-    , "then"
-    , "else"
-    ]
+  [ "condition"
+  , "then"
+  , "else"
+  ]
 
 -- | The <https://github.com/sol/hpack#defaults defaults> fields.
 defaultsFields :: IsString a => [a]
 defaultsFields =
-    [ "github"
-    , "ref"
-    , "path"
-    , "local"
-    ]
+  [ "github"
+  , "ref"
+  , "path"
+  , "local"
+  ]
diff --git a/package.dhall b/package.dhall
--- a/package.dhall
+++ b/package.dhall
@@ -1,102 +1,109 @@
 let deps =
-      [ "aeson"
-      , "aeson-pretty"
-      , "base >= 4.13 && < 5"
-      , "bytestring"
-      , "dhall >= 1.41.1"
-      , "dhall-json >= 1.7.10"
-      , "filepath"
-      , "hpack ^>= 0.35"
-      , "megaparsec >= 9.2"
-      , "microlens"
-      , "prettyprinter"
-      , "text"
-      , "transformers"
-      , "yaml"
+      [ "aeson <3"
+      , "aeson-pretty <1"
+      , "base >=4.13 && <5"
+      , "bytestring <0.13"
+      , "dhall >=1.41.1 && <2"
+      , "dhall-json >=1.7.10 && <2"
+      , "filepath <2"
+      , "hpack >=0.39.6 && <1"
+      , "megaparsec >=9.2 && <10"
+      , "microlens <0.6"
+      , "prettyprinter <2"
+      , "text <3"
+      , "transformers <0.7"
+      , "yaml <0.12"
       ]
 
-in  let exe-deps = [ "optparse-applicative" ]
-
-    in  { name = "hpack-dhall"
-        , version = "0.5.7"
-        , maintainer = "Phil de Joux <phil.dejoux@blockscope.com>"
-        , copyright =
-            "© 2018 - 2022 Phil de Joux, © 2018 - 2022 Block Scope Limited"
-        , license = "BSD3"
-        , license-file = "LICENSE"
-        , category = "Development"
-        , synopsis = "hpack's dhalling"
-        , description =
-            ''
-            Use hpack phrasing in dhall to write cabal files.
-
-            There are two main reasons why you'd use hpack-dhall, convenience and safety.
+let exe-deps = [ "optparse-applicative <0.20" ]
 
-            Get the convenience of hpack. Don't bother to state what can be inferred or
-            defaulted, easing the burden of completing a package description by hand.  For
-            example `other-modules` can be inferred by taking the set difference between
-            modules on disk and the set of `exposed-modules`.
+let hook-deps = [ "extra <2", "filepattern <1", "optparse-applicative <0.20" ]
 
-            Get the safety of dhall's programmable configuration: typed fields, safe imports
-            and functions.
-            ''
-        , github = "cabalism/hpack-dhall"
-        , tested-with =
-            "GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.2"
-        , extra-source-files =
-          [ "package.dhall"
-          , "changelog.md"
-          , "test-suite-golden/**/*.dhall"
-          , "test-suite-golden/**/*.dhl"
-          , "test-suite-golden/**/*.cabal"
-          , "test-suite-golden/**/*.json"
-          , "test-suite-golden/**/*.yaml"
-          , "test-suite-golden/**/*.golden"
-          ]
-        , ghc-options =
-          [ "-Wall"
-          , "-Wincomplete-uni-patterns"
-          , "-Wcompat"
-          , "-Widentities"
-          , "-Wredundant-constraints"
-          , "-fhide-source-paths"
-          ]
-        , dependencies = deps
-        , source-dirs = "library"
-        , library.exposed-modules = [ "Hpack.Dhall", "Hpack.Fields" ]
-        , executables =
-          { dhall-hpack-cabal =
-            { main = "CabalMain.hs"
-            , source-dirs = [ "exe/options", "exe/dhall-hpack-cabal" ]
-            , dependencies = exe-deps
-            }
-          , dhall-hpack-json =
-            { main = "JsonMain.hs"
-            , source-dirs = [ "exe/options", "exe/dhall-hpack-json" ]
-            , dependencies = exe-deps
-            }
-          , dhall-hpack-yaml =
-            { main = "YamlMain.hs"
-            , source-dirs = [ "exe/options", "exe/dhall-hpack-yaml" ]
-            , dependencies = exe-deps
-            }
-          , dhall-hpack-dhall =
-            { main = "DhallMain.hs"
-            , source-dirs = [ "exe/options", "exe/dhall-hpack-dhall" ]
-            , dependencies = exe-deps
-            }
-          }
-        , tests.golden
-          =
-          { main = "Golden.hs"
-          , source-dirs = [ "test-suite-golden/src" ]
-          , dependencies =
-            [ "Cabal"
-            , "Diff"
-            , "directory"
-            , "tasty"
-            , "tasty-golden"
-            , "utf8-string"
-            ]
-          }
+in  { name = "hpack-dhall"
+    , version = "0.6.0"
+    , maintainer = "Phil de Joux <phil.dejoux@blockscope.com>"
+    , copyright =
+        "© 2018 - 2026 Phil de Joux, © 2018 - 2026 Block Scope Limited"
+    , license = "BSD3"
+    , license-file = "LICENSE"
+    , category = "Development"
+    , synopsis = "Hpack with Dhall"
+    , description =
+        ''
+        Hpack-Dhall brings functions, types and file imports to Haskell
+        packaging.  It is Hpack with Dhall.
+        ''
+    , github = "cabalism/hpack-dhall"
+    , tested-with =
+        "GHC == 9.2.8, GHC == 9.4.8, GHC == 9.6.7, GHC == 9.8.4, GHC == 9.10.3, GHC == 9.12.4"
+    , extra-source-files =
+      [ "package.dhall"
+      , "changelog.md"
+      , "test-suite-golden/**/*.dhall"
+      , "test-suite-golden/**/*.dhl"
+      , "test-suite-golden/**/*.cabal"
+      , "test-suite-golden/**/*.json"
+      , "test-suite-golden/**/*.yaml"
+      , "test-suite-golden/**/*.golden"
+      ]
+    , ghc-options =
+      [ "-Wall"
+      , "-Wincomplete-uni-patterns"
+      , "-Wcompat"
+      , "-Widentities"
+      , "-Wredundant-constraints"
+      , "-fhide-source-paths"
+      ]
+    , dependencies = deps
+    , source-dirs = "library"
+    , library.exposed-modules = [ "Hpack.Dhall", "Hpack.Fields" ]
+    , executables =
+      { cabal-dpack =
+        { main = "DpackMain.hs"
+        , source-dirs = [ "exe", "hook", "hook/cabal-dpack" ]
+        , dependencies = hook-deps
         }
+      , cabal-diy-pack =
+        { main = "DiyPackMain.hs"
+        , source-dirs = [ "exe", "hook", "hook/cabal-diy-pack" ]
+        , dependencies = hook-deps
+        }
+      , cabal-ypack =
+        { main = "YpackMain.hs"
+        , source-dirs = [ "exe", "hook", "hook/cabal-ypack" ]
+        , dependencies = hook-deps
+        }
+      , dhall-hpack-cabal =
+        { main = "CabalMain.hs"
+        , source-dirs = [ "exe", "exe/dhall-hpack-cabal" ]
+        , dependencies = exe-deps
+        }
+      , dhall-hpack-json =
+        { main = "JsonMain.hs"
+        , source-dirs = [ "exe", "exe/dhall-hpack-json" ]
+        , dependencies = exe-deps
+        }
+      , dhall-hpack-yaml =
+        { main = "YamlMain.hs"
+        , source-dirs = [ "exe", "exe/dhall-hpack-yaml" ]
+        , dependencies = exe-deps
+        }
+      , dhall-hpack-dhall =
+        { main = "DhallMain.hs"
+        , source-dirs = [ "exe", "exe/dhall-hpack-dhall" ]
+        , dependencies = exe-deps
+        }
+      , yaml-hpack-cabal =
+        { main = "CabalMain.hs"
+        , source-dirs = [ "exe", "exe/yaml-hpack-cabal" ]
+        , dependencies = exe-deps
+        }
+      }
+    , tests.golden
+      =
+      { main = "Golden.hs"
+      , source-dirs = [ "test-suite-golden/src" ]
+      , dependencies =
+        [ "Cabal", "Diff", "directory", "tasty", "tasty-golden", "utf8-string" ]
+      }
+    }
diff --git a/test-suite-golden/src/Golden.hs b/test-suite-golden/src/Golden.hs
--- a/test-suite-golden/src/Golden.hs
+++ b/test-suite-golden/src/Golden.hs
@@ -1,26 +1,34 @@
-{-# LANGUAGE MultiWayIf, LambdaCase, CPP #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE MultiWayIf #-}
 
 module Main (main) where
 
-import System.FilePath
-    ( (</>), (<.>), (-<.>)
-    , takeBaseName, replaceExtension
-    , takeDirectory, splitDirectories, joinPath
-    )
 import System.Directory (renameFile)
-import Test.Tasty (defaultMain, TestTree, testGroup)
+import System.FilePath
+  ( joinPath
+  , replaceExtension
+  , splitDirectories
+  , takeBaseName
+  , takeDirectory
+  , (-<.>)
+  , (<.>)
+  , (</>)
+  )
+import Test.Tasty (TestTree, defaultMain, testGroup)
 import Test.Tasty.Golden (findByExtension, goldenVsFile, goldenVsString)
 
-import Hpack (Verbose(..), Options(..), hpack, defaultOptions, setDecode)
-import Hpack.Config (DecodeOptions(..))
-import Hpack.Dhall (fileToJson, showDhall, showJson, showYaml)
 import Data.ByteString.Lazy.UTF8 (fromString)
+import Hpack (Options (..), Verbose (..), defaultOptions, hpack, setDecode)
+import Hpack.Config (DecodeOptions (..))
+import Hpack.Dhall (dhallFileToJson, showDhall, showJson, showYaml)
 
 data Out = Cabal | Dhall | Json | Yaml
 
 main :: IO ()
 main = defaultMain =<< goldenTests
 
+{- FOURMOLU_DISABLE -}
 goldExt :: Out -> FilePath
 goldExt =
     \case
@@ -40,126 +48,140 @@
 
         Json -> ".json.golden"
         Yaml -> ".yaml.golden"
+{- FOURMOLU_ENABLE -}
 
 goldenTests :: IO TestTree
 goldenTests = do
-    ks <- findByExtension [".dhall"] "test-suite-golden/test-files/key"
-    rs <- findByExtension [".dhall"] "test-suite-golden/test-files/real-world"
-    g1 <- goldenTestSet "archetypes" ks
-    g2 <- goldenTestSet "real-world examples" rs
-    return $ testGroup "golden tests" [g1 , g2]
+  ks <- findByExtension [".dhall"] "test-suite-golden/test-files/key"
+  rs <- findByExtension [".dhall"] "test-suite-golden/test-files/real-world"
+  g1 <- goldenTestSet "archetypes" ks
+  g2 <- goldenTestSet "real-world examples" rs
+  return $ testGroup "golden tests" [g1, g2]
 
 goldenTestSet :: String -> [FilePath] -> IO TestTree
 goldenTestSet title dhallFiles = do
-    return $ testGroup title
-        [ testGroup ".dhall to .cabal"
-            [ goldenVsFile
-                (testName dhallFile)
-                (cabalFile -<.> goldExt Cabal)
-                cabalFile
-                (writeDhallCabal dhallFile)
-            | dhallFile <- dhallFiles
-            , let cabalFile = cabalFilePath dhallFile
-            ]
-        , testGroup ".dhall to dhall"
-            [ goldenVsString
-                (testName dhallFile)
-                (dhallFile -<.> goldExt Dhall)
-                (fmap fromString . showDhall $ dhallFile)
-            | dhallFile <- dhallFiles
-            ]
-        , testGroup ".dhall to json"
-            [ goldenVsFile
-                (testName dhallFile)
-                (dhallFile -<.> goldExt Json)
-                jsonFile
-                (writeJson dhallFile jsonFile)
-            | dhallFile <- dhallFiles
-            , let jsonFile = dhallFile -<.> ".json"
-            ]
-        , testGroup ".dhall to yaml"
-            [ goldenVsFile
-                (testName dhallFile)
-                (dhallFile -<.> goldExt Yaml)
-                yamlFile
-                (writeYaml dhallFile yamlFile)
-            | dhallFile <- dhallFiles
-            , let yamlFile = dhallFile -<.> ".yaml"
-            ]
-        , testGroup ".yaml to .cabal"
-            [ goldenVsFile
-                (testName dhallFile)
-                (cabalFile -<.> goldExt Cabal)
-                cabalFile
-                (writeYamlCabal yamlFile cabalFile yamlCabalFile)
-            | dhallFile <- dhallFiles
-            , let yamlFile = dhallFile -<.> ".yaml"
-            , let cabalFile = cabalFilePath dhallFile
-            , let yamlCabalFile = yamlFile <.> ".cabal"
-            ]
-        ]
+  return $
+    testGroup
+      title
+      [ testGroup
+          ".dhall to .cabal"
+          [ goldenVsFile
+            (testName dhallFile)
+            goldenFile
+            cabalFile
+            (writeDhallCabal dhallFile)
+          | dhallFile <- dhallFiles
+          , let cabalFile = cabalFilePath dhallFile
+          , let goldenFile = cabalFile -<.> goldExt Cabal
+          ]
+      , testGroup
+          ".dhall to dhall"
+          [ goldenVsString
+            (testName dhallFile)
+            goldenFile
+            (fmap fromString . showDhall $ dhallFile)
+          | dhallFile <- dhallFiles
+          , let goldenFile = dhallFile -<.> goldExt Dhall
+          ]
+      , testGroup
+          ".dhall to json"
+          [ goldenVsFile
+            (testName dhallFile)
+            goldenFile
+            jsonFile
+            (writeJson dhallFile jsonFile)
+          | dhallFile <- dhallFiles
+          , let jsonFile = dhallFile -<.> ".json"
+          , let goldenFile = dhallFile -<.> goldExt Json
+          ]
+      , testGroup
+          ".dhall to yaml"
+          [ goldenVsFile
+            (testName dhallFile)
+            goldenFile
+            yamlFile
+            (writeYaml dhallFile yamlFile)
+          | dhallFile <- dhallFiles
+          , let yamlFile = dhallFile -<.> ".yaml"
+          , let goldenFile = dhallFile -<.> goldExt Yaml
+          ]
+      , testGroup
+          ".yaml to .cabal"
+          [ goldenVsFile
+            (testName dhallFile)
+            goldenFile
+            cabalFile
+            (writeYamlCabal yamlFile cabalFile yamlCabalFile)
+          | dhallFile <- dhallFiles
+          , let yamlFile = dhallFile -<.> ".yaml"
+          , let cabalFile = cabalFilePath dhallFile
+          , let yamlCabalFile = yamlFile <.> ".cabal"
+          , let goldenFile = cabalFile -<.> goldExt Cabal
+          ]
+      ]
 
 testName :: FilePath -> FilePath
 testName p =
-    if | fName == dName -> fName
-       | fName == "package" -> dName
-       | dName == "key" -> fName
-       | dName == "real-world" -> fName
-       | otherwise -> dName </> fName
-    where
-        dName =
-            joinPath
-            . take 1
-            . reverse
-            . splitDirectories
-            . takeDirectory
-            $ p
+  if
+      | fName == dName -> fName
+      | fName == "package" -> dName
+      | dName == "key" -> fName
+      | dName == "real-world" -> fName
+      | otherwise -> dName </> fName
+  where
+    dName =
+      joinPath
+        . take 1
+        . reverse
+        . splitDirectories
+        . takeDirectory
+        $ p
 
-        fName = takeBaseName p
+    fName = takeBaseName p
 
 writeDhallCabal :: FilePath -> IO ()
 writeDhallCabal dhallFile =
-    hpack NoVerbose (setDecode fileToJson options)
-    where
-        d = optionsDecodeOptions defaultOptions
-        d' = d {decodeOptionsTarget = dhallFile}
-        options = defaultOptions {optionsDecodeOptions = d'}
+  hpack NoVerbose (setDecode dhallFileToJson options)
+  where
+    d = optionsDecodeOptions defaultOptions
+    d' = d{decodeOptionsTarget = dhallFile}
+    options = defaultOptions{optionsDecodeOptions = d'}
 
 writeYamlCabal :: FilePath -> FilePath -> FilePath -> IO ()
 writeYamlCabal yamlFile cabalFile yamlCabalFile = do
-        renameFile cabalFile tmp
-        hpack NoVerbose options
-        renameFile cabalFile yamlCabalFile
-        renameFile tmp cabalFile
-    where
-        tmp = cabalFile <.> ".TMP"
+  renameFile cabalFile tmp
+  hpack NoVerbose options
+  renameFile cabalFile yamlCabalFile
+  renameFile tmp cabalFile
+  where
+    tmp = cabalFile <.> ".TMP"
 
-        d = optionsDecodeOptions defaultOptions
-        d' = d {decodeOptionsTarget = yamlFile}
-        options =
-            defaultOptions
-                { optionsDecodeOptions = d'
-                }
+    d = optionsDecodeOptions defaultOptions
+    d' = d{decodeOptionsTarget = yamlFile}
+    options =
+      defaultOptions
+        { optionsDecodeOptions = d'
+        }
 
 writeJson :: FilePath -> FilePath -> IO ()
 writeJson dhallFile jsonFile = do
-    s <- showJson Nothing dhallFile
-    writeFile jsonFile s
+  s <- showJson Nothing dhallFile
+  writeFile jsonFile s
+  appendFile jsonFile $ unlines [""]
 
 writeYaml :: FilePath -> FilePath -> IO ()
 writeYaml dhallFile yamlFile = do
-    s <- showYaml Nothing dhallFile
-    writeFile yamlFile s
+  s <- showYaml Nothing dhallFile
+  writeFile yamlFile s
+  appendFile yamlFile $ unlines [""]
 
 cabalFilePath :: FilePath -> FilePath
 cabalFilePath p
-    | takeBaseName p == "package" =
-        case reverse . splitDirectories $ ds of
-            d : ds' -> joinPath (reverse ds') </> d </> d <.> ".cabal"
-            _ -> replaceExtension p ".cabal"
-
-    | otherwise =
-        replaceExtension p ".cabal"
-
-    where
-        ds = takeDirectory p
+  | takeBaseName p == "package" =
+      case reverse . splitDirectories $ ds of
+        d : ds' -> joinPath (reverse ds') </> d </> d <.> ".cabal"
+        _ -> replaceExtension p ".cabal"
+  | otherwise =
+      replaceExtension p ".cabal"
+  where
+    ds = takeDirectory p
diff --git a/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal b/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal
--- a/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal
+++ b/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 9f10239d716ef4564587e29b36c0e3b74056721733790211e20061a86a0feb53
 
 name:           empty-inferred
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal.golden b/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal.golden
--- a/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal.golden
+++ b/test-suite-golden/test-files/key/empty-inferred/empty-inferred.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 9f10239d716ef4564587e29b36c0e3b74056721733790211e20061a86a0feb53
 
 name:           empty-inferred
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/empty-inferred/package.json b/test-suite-golden/test-files/key/empty-inferred/package.json
--- a/test-suite-golden/test-files/key/empty-inferred/package.json
+++ b/test-suite-golden/test-files/key/empty-inferred/package.json
diff --git a/test-suite-golden/test-files/key/empty-inferred/package.json.golden b/test-suite-golden/test-files/key/empty-inferred/package.json.golden
--- a/test-suite-golden/test-files/key/empty-inferred/package.json.golden
+++ b/test-suite-golden/test-files/key/empty-inferred/package.json.golden
diff --git a/test-suite-golden/test-files/key/empty-inferred/package.yaml b/test-suite-golden/test-files/key/empty-inferred/package.yaml
--- a/test-suite-golden/test-files/key/empty-inferred/package.yaml
+++ b/test-suite-golden/test-files/key/empty-inferred/package.yaml
@@ -1,1 +1,2 @@
 {}
+
diff --git a/test-suite-golden/test-files/key/empty-inferred/package.yaml.cabal b/test-suite-golden/test-files/key/empty-inferred/package.yaml.cabal
--- a/test-suite-golden/test-files/key/empty-inferred/package.yaml.cabal
+++ b/test-suite-golden/test-files/key/empty-inferred/package.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.35.0.
+-- This file has been generated from package.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/empty-inferred/package.yaml.golden b/test-suite-golden/test-files/key/empty-inferred/package.yaml.golden
--- a/test-suite-golden/test-files/key/empty-inferred/package.yaml.golden
+++ b/test-suite-golden/test-files/key/empty-inferred/package.yaml.golden
@@ -1,1 +1,2 @@
 {}
+
diff --git a/test-suite-golden/test-files/key/empty-package.cabal b/test-suite-golden/test-files/key/empty-package.cabal
--- a/test-suite-golden/test-files/key/empty-package.cabal
+++ b/test-suite-golden/test-files/key/empty-package.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from empty-package.dhall by hpack version 0.31.0.
+-- This file has been generated from empty-package.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: e0a74f511d829cae53cd712664781db312951dd773249603163ba1b1e32afd04
 
 name:           empty-package
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/empty-package.cabal.golden b/test-suite-golden/test-files/key/empty-package.cabal.golden
--- a/test-suite-golden/test-files/key/empty-package.cabal.golden
+++ b/test-suite-golden/test-files/key/empty-package.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from empty-package.dhall by hpack version 0.31.0.
+-- This file has been generated from empty-package.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: e0a74f511d829cae53cd712664781db312951dd773249603163ba1b1e32afd04
 
 name:           empty-package
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/empty-package.json b/test-suite-golden/test-files/key/empty-package.json
--- a/test-suite-golden/test-files/key/empty-package.json
+++ b/test-suite-golden/test-files/key/empty-package.json
diff --git a/test-suite-golden/test-files/key/empty-package.json.golden b/test-suite-golden/test-files/key/empty-package.json.golden
--- a/test-suite-golden/test-files/key/empty-package.json.golden
+++ b/test-suite-golden/test-files/key/empty-package.json.golden
diff --git a/test-suite-golden/test-files/key/empty-package.yaml b/test-suite-golden/test-files/key/empty-package.yaml
--- a/test-suite-golden/test-files/key/empty-package.yaml
+++ b/test-suite-golden/test-files/key/empty-package.yaml
@@ -1,1 +1,2 @@
 name: empty-package
+
diff --git a/test-suite-golden/test-files/key/empty-package.yaml.cabal b/test-suite-golden/test-files/key/empty-package.yaml.cabal
--- a/test-suite-golden/test-files/key/empty-package.yaml.cabal
+++ b/test-suite-golden/test-files/key/empty-package.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from empty-package.yaml by hpack version 0.35.0.
+-- This file has been generated from empty-package.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/empty-package.yaml.golden b/test-suite-golden/test-files/key/empty-package.yaml.golden
--- a/test-suite-golden/test-files/key/empty-package.yaml.golden
+++ b/test-suite-golden/test-files/key/empty-package.yaml.golden
@@ -1,1 +1,2 @@
 name: empty-package
+
diff --git a/test-suite-golden/test-files/key/import-local/import-local.cabal b/test-suite-golden/test-files/key/import-local/import-local.cabal
--- a/test-suite-golden/test-files/key/import-local/import-local.cabal
+++ b/test-suite-golden/test-files/key/import-local/import-local.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: fb3f09267f149cb49eb030ac951c27be9964aa0d51e91460e5b2d59ee1a5082f
 
 name:           import-local
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/import-local/import-local.cabal.golden b/test-suite-golden/test-files/key/import-local/import-local.cabal.golden
--- a/test-suite-golden/test-files/key/import-local/import-local.cabal.golden
+++ b/test-suite-golden/test-files/key/import-local/import-local.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: fb3f09267f149cb49eb030ac951c27be9964aa0d51e91460e5b2d59ee1a5082f
 
 name:           import-local
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/import-local/package.json b/test-suite-golden/test-files/key/import-local/package.json
--- a/test-suite-golden/test-files/key/import-local/package.json
+++ b/test-suite-golden/test-files/key/import-local/package.json
diff --git a/test-suite-golden/test-files/key/import-local/package.json.golden b/test-suite-golden/test-files/key/import-local/package.json.golden
--- a/test-suite-golden/test-files/key/import-local/package.json.golden
+++ b/test-suite-golden/test-files/key/import-local/package.json.golden
diff --git a/test-suite-golden/test-files/key/import-local/package.yaml b/test-suite-golden/test-files/key/import-local/package.yaml
--- a/test-suite-golden/test-files/key/import-local/package.yaml
+++ b/test-suite-golden/test-files/key/import-local/package.yaml
@@ -1,1 +1,2 @@
 name: import-local
+
diff --git a/test-suite-golden/test-files/key/import-local/package.yaml.cabal b/test-suite-golden/test-files/key/import-local/package.yaml.cabal
--- a/test-suite-golden/test-files/key/import-local/package.yaml.cabal
+++ b/test-suite-golden/test-files/key/import-local/package.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.35.0.
+-- This file has been generated from package.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/import-local/package.yaml.golden b/test-suite-golden/test-files/key/import-local/package.yaml.golden
--- a/test-suite-golden/test-files/key/import-local/package.yaml.golden
+++ b/test-suite-golden/test-files/key/import-local/package.yaml.golden
@@ -1,1 +1,2 @@
 name: import-local
+
diff --git a/test-suite-golden/test-files/key/import-relative/import-relative.cabal b/test-suite-golden/test-files/key/import-relative/import-relative.cabal
--- a/test-suite-golden/test-files/key/import-relative/import-relative.cabal
+++ b/test-suite-golden/test-files/key/import-relative/import-relative.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 989056d21c3910e06ec15967716df134a39f43c561858afff828d22802a22005
 
 name:           import-relative
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/import-relative/import-relative.cabal.golden b/test-suite-golden/test-files/key/import-relative/import-relative.cabal.golden
--- a/test-suite-golden/test-files/key/import-relative/import-relative.cabal.golden
+++ b/test-suite-golden/test-files/key/import-relative/import-relative.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from package.dhall by hpack version 0.31.0.
+-- This file has been generated from package.dhall by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 989056d21c3910e06ec15967716df134a39f43c561858afff828d22802a22005
 
 name:           import-relative
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/import-relative/package.json b/test-suite-golden/test-files/key/import-relative/package.json
--- a/test-suite-golden/test-files/key/import-relative/package.json
+++ b/test-suite-golden/test-files/key/import-relative/package.json
diff --git a/test-suite-golden/test-files/key/import-relative/package.json.golden b/test-suite-golden/test-files/key/import-relative/package.json.golden
--- a/test-suite-golden/test-files/key/import-relative/package.json.golden
+++ b/test-suite-golden/test-files/key/import-relative/package.json.golden
diff --git a/test-suite-golden/test-files/key/import-relative/package.yaml b/test-suite-golden/test-files/key/import-relative/package.yaml
--- a/test-suite-golden/test-files/key/import-relative/package.yaml
+++ b/test-suite-golden/test-files/key/import-relative/package.yaml
@@ -1,1 +1,2 @@
 name: import-relative
+
diff --git a/test-suite-golden/test-files/key/import-relative/package.yaml.cabal b/test-suite-golden/test-files/key/import-relative/package.yaml.cabal
--- a/test-suite-golden/test-files/key/import-relative/package.yaml.cabal
+++ b/test-suite-golden/test-files/key/import-relative/package.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.35.0.
+-- This file has been generated from package.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/import-relative/package.yaml.golden b/test-suite-golden/test-files/key/import-relative/package.yaml.golden
--- a/test-suite-golden/test-files/key/import-relative/package.yaml.golden
+++ b/test-suite-golden/test-files/key/import-relative/package.yaml.golden
@@ -1,1 +1,2 @@
 name: import-relative
+
diff --git a/test-suite-golden/test-files/key/when-dependencies.cabal b/test-suite-golden/test-files/key/when-dependencies.cabal
--- a/test-suite-golden/test-files/key/when-dependencies.cabal
+++ b/test-suite-golden/test-files/key/when-dependencies.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from when-dependencies.dhall by hpack version 0.31.1.
+-- This file has been generated from when-dependencies.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: a1d315a919b697e7986a0c149715373427427e43104f82f05f394a439793907f
 
 name:           when-dependencies
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/when-dependencies.cabal.golden b/test-suite-golden/test-files/key/when-dependencies.cabal.golden
--- a/test-suite-golden/test-files/key/when-dependencies.cabal.golden
+++ b/test-suite-golden/test-files/key/when-dependencies.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from when-dependencies.dhall by hpack version 0.31.1.
+-- This file has been generated from when-dependencies.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: a1d315a919b697e7986a0c149715373427427e43104f82f05f394a439793907f
 
 name:           when-dependencies
 version:        0.0.0
diff --git a/test-suite-golden/test-files/key/when-dependencies.json b/test-suite-golden/test-files/key/when-dependencies.json
--- a/test-suite-golden/test-files/key/when-dependencies.json
+++ b/test-suite-golden/test-files/key/when-dependencies.json
diff --git a/test-suite-golden/test-files/key/when-dependencies.json.golden b/test-suite-golden/test-files/key/when-dependencies.json.golden
--- a/test-suite-golden/test-files/key/when-dependencies.json.golden
+++ b/test-suite-golden/test-files/key/when-dependencies.json.golden
diff --git a/test-suite-golden/test-files/key/when-dependencies.yaml b/test-suite-golden/test-files/key/when-dependencies.yaml
--- a/test-suite-golden/test-files/key/when-dependencies.yaml
+++ b/test-suite-golden/test-files/key/when-dependencies.yaml
@@ -9,3 +9,4 @@
     dependencies:
     - base == 4.*
     - yaml-pretty-extras
+
diff --git a/test-suite-golden/test-files/key/when-dependencies.yaml.cabal b/test-suite-golden/test-files/key/when-dependencies.yaml.cabal
--- a/test-suite-golden/test-files/key/when-dependencies.yaml.cabal
+++ b/test-suite-golden/test-files/key/when-dependencies.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from when-dependencies.yaml by hpack version 0.35.0.
+-- This file has been generated from when-dependencies.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/when-dependencies.yaml.golden b/test-suite-golden/test-files/key/when-dependencies.yaml.golden
--- a/test-suite-golden/test-files/key/when-dependencies.yaml.golden
+++ b/test-suite-golden/test-files/key/when-dependencies.yaml.golden
@@ -9,3 +9,4 @@
     dependencies:
     - base == 4.*
     - yaml-pretty-extras
+
diff --git a/test-suite-golden/test-files/key/with-GHC2021.cabal b/test-suite-golden/test-files/key/with-GHC2021.cabal
--- a/test-suite-golden/test-files/key/with-GHC2021.cabal
+++ b/test-suite-golden/test-files/key/with-GHC2021.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from with-GHC2021.dhall by hpack version 0.34.6.
+-- This file has been generated from with-GHC2021.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/with-GHC2021.cabal.golden b/test-suite-golden/test-files/key/with-GHC2021.cabal.golden
--- a/test-suite-golden/test-files/key/with-GHC2021.cabal.golden
+++ b/test-suite-golden/test-files/key/with-GHC2021.cabal.golden
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from with-GHC2021.dhall by hpack version 0.34.6.
+-- This file has been generated from with-GHC2021.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/with-GHC2021.json b/test-suite-golden/test-files/key/with-GHC2021.json
--- a/test-suite-golden/test-files/key/with-GHC2021.json
+++ b/test-suite-golden/test-files/key/with-GHC2021.json
diff --git a/test-suite-golden/test-files/key/with-GHC2021.json.golden b/test-suite-golden/test-files/key/with-GHC2021.json.golden
--- a/test-suite-golden/test-files/key/with-GHC2021.json.golden
+++ b/test-suite-golden/test-files/key/with-GHC2021.json.golden
diff --git a/test-suite-golden/test-files/key/with-GHC2021.yaml b/test-suite-golden/test-files/key/with-GHC2021.yaml
--- a/test-suite-golden/test-files/key/with-GHC2021.yaml
+++ b/test-suite-golden/test-files/key/with-GHC2021.yaml
@@ -49,3 +49,4 @@
 executable:
   main: Main.hs
   source-dirs: src
+
diff --git a/test-suite-golden/test-files/key/with-GHC2021.yaml.cabal b/test-suite-golden/test-files/key/with-GHC2021.yaml.cabal
--- a/test-suite-golden/test-files/key/with-GHC2021.yaml.cabal
+++ b/test-suite-golden/test-files/key/with-GHC2021.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from with-GHC2021.yaml by hpack version 0.35.0.
+-- This file has been generated from with-GHC2021.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/key/with-GHC2021.yaml.golden b/test-suite-golden/test-files/key/with-GHC2021.yaml.golden
--- a/test-suite-golden/test-files/key/with-GHC2021.yaml.golden
+++ b/test-suite-golden/test-files/key/with-GHC2021.yaml.golden
@@ -49,3 +49,4 @@
 executable:
   main: Main.hs
   source-dirs: src
+
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.cabal b/test-suite-golden/test-files/real-world/hpack/hpack.cabal
--- a/test-suite-golden/test-files/real-world/hpack/hpack.cabal
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.cabal
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from hpack.dhall by hpack version 0.31.0.
+-- This file has been generated from hpack.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 6233d5bc3d8cc3400d64ab30856182d4a593d9245bfdd5096e1287213cc3ae31
 
 name:           hpack
 version:        0.31.1
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.cabal.golden b/test-suite-golden/test-files/real-world/hpack/hpack.cabal.golden
--- a/test-suite-golden/test-files/real-world/hpack/hpack.cabal.golden
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 1.12
 
--- This file has been generated from hpack.dhall by hpack version 0.31.0.
+-- This file has been generated from hpack.dhall by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 6233d5bc3d8cc3400d64ab30856182d4a593d9245bfdd5096e1287213cc3ae31
 
 name:           hpack
 version:        0.31.1
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.json b/test-suite-golden/test-files/real-world/hpack/hpack.json
--- a/test-suite-golden/test-files/real-world/hpack/hpack.json
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.json
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.json.golden b/test-suite-golden/test-files/real-world/hpack/hpack.json.golden
--- a/test-suite-golden/test-files/real-world/hpack/hpack.json.golden
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.json.golden
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.yaml b/test-suite-golden/test-files/real-world/hpack/hpack.yaml
--- a/test-suite-golden/test-files/real-world/hpack/hpack.yaml
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.yaml
@@ -59,3 +59,4 @@
     - template-haskell
     - HUnit >= 1.6.0.0
     build-tools: hspec-discover
+
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.yaml.cabal b/test-suite-golden/test-files/real-world/hpack/hpack.yaml.cabal
--- a/test-suite-golden/test-files/real-world/hpack/hpack.yaml.cabal
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 1.12
 
--- This file has been generated from hpack.yaml by hpack version 0.35.0.
+-- This file has been generated from hpack.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
diff --git a/test-suite-golden/test-files/real-world/hpack/hpack.yaml.golden b/test-suite-golden/test-files/real-world/hpack/hpack.yaml.golden
--- a/test-suite-golden/test-files/real-world/hpack/hpack.yaml.golden
+++ b/test-suite-golden/test-files/real-world/hpack/hpack.yaml.golden
@@ -59,3 +59,4 @@
     - template-haskell
     - HUnit >= 1.6.0.0
     build-tools: hspec-discover
+
diff --git a/test-suite-golden/test-files/real-world/stack/stack.cabal b/test-suite-golden/test-files/real-world/stack/stack.cabal
--- a/test-suite-golden/test-files/real-world/stack/stack.cabal
+++ b/test-suite-golden/test-files/real-world/stack/stack.cabal
@@ -1,10 +1,8 @@
 cabal-version: 2.0
 
--- This file has been generated from stack.dhall by hpack version 0.35.0.
+-- This file has been generated from stack.dhall by hpack version 0.38.3.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 645c43bbed2e4ee44172441652f686f9df4f80fe34991062b018c2410e276567
 
 name:           stack
 version:        1.10.0
@@ -286,8 +284,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if os(windows)
@@ -400,8 +398,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if flag(static)
@@ -517,8 +515,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if !flag(integration-tests)
@@ -627,7 +625,7 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
diff --git a/test-suite-golden/test-files/real-world/stack/stack.cabal.golden b/test-suite-golden/test-files/real-world/stack/stack.cabal.golden
--- a/test-suite-golden/test-files/real-world/stack/stack.cabal.golden
+++ b/test-suite-golden/test-files/real-world/stack/stack.cabal.golden
@@ -1,10 +1,8 @@
 cabal-version: 2.0
 
--- This file has been generated from stack.dhall by hpack version 0.35.0.
+-- This file has been generated from stack.dhall by hpack version 0.38.3.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: 645c43bbed2e4ee44172441652f686f9df4f80fe34991062b018c2410e276567
 
 name:           stack
 version:        1.10.0
@@ -286,8 +284,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if os(windows)
@@ -400,8 +398,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if flag(static)
@@ -517,8 +515,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if !flag(integration-tests)
@@ -627,7 +625,7 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
diff --git a/test-suite-golden/test-files/real-world/stack/stack.json b/test-suite-golden/test-files/real-world/stack/stack.json
--- a/test-suite-golden/test-files/real-world/stack/stack.json
+++ b/test-suite-golden/test-files/real-world/stack/stack.json
diff --git a/test-suite-golden/test-files/real-world/stack/stack.json.golden b/test-suite-golden/test-files/real-world/stack/stack.json.golden
--- a/test-suite-golden/test-files/real-world/stack/stack.json.golden
+++ b/test-suite-golden/test-files/real-world/stack/stack.json.golden
diff --git a/test-suite-golden/test-files/real-world/stack/stack.yaml b/test-suite-golden/test-files/real-world/stack/stack.yaml
--- a/test-suite-golden/test-files/real-world/stack/stack.yaml
+++ b/test-suite-golden/test-files/real-world/stack/stack.yaml
@@ -356,3 +356,4 @@
     - hspec
     - stack
     - smallcheck
+
diff --git a/test-suite-golden/test-files/real-world/stack/stack.yaml.cabal b/test-suite-golden/test-files/real-world/stack/stack.yaml.cabal
--- a/test-suite-golden/test-files/real-world/stack/stack.yaml.cabal
+++ b/test-suite-golden/test-files/real-world/stack/stack.yaml.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.0
 
--- This file has been generated from stack.yaml by hpack version 0.35.0.
+-- This file has been generated from stack.yaml by hpack version 0.39.6.
 --
 -- see: https://github.com/sol/hpack
 
@@ -284,8 +284,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if os(windows)
@@ -398,8 +398,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if flag(static)
@@ -515,8 +515,8 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
   if !flag(integration-tests)
@@ -625,7 +625,7 @@
     build-depends:
         Win32
   else
-    build-tools:
-        hsc2hs
+    build-tool-depends:
+        hsc2hs:hsc2hs
     build-depends:
         unix
diff --git a/test-suite-golden/test-files/real-world/stack/stack.yaml.golden b/test-suite-golden/test-files/real-world/stack/stack.yaml.golden
--- a/test-suite-golden/test-files/real-world/stack/stack.yaml.golden
+++ b/test-suite-golden/test-files/real-world/stack/stack.yaml.golden
@@ -356,3 +356,4 @@
     - hspec
     - stack
     - smallcheck
+
