{-| Utilities to interact with the dhall-docs home directory -} {-# OPTIONS_GHC -Wno-unused-imports #-} {-# LANGUAGE QuasiQuotes #-} module Dhall.Docs.Store (getDocsHomeDirectory, makeHashForDirectory) where import Dhall.Crypto (SHA256Digest (..), sha256Hash) import Path (Abs, Dir, Path, Rel) import Path.IO (XdgDirectory (..)) import qualified Codec.Archive.Tar as Tar import qualified Codec.Archive.Tar.Entry as Tar.Entry import qualified Data.ByteString.Lazy import qualified Data.List import qualified Path import qualified Path.IO {-| Fetches the dhall-docs home directory. If @XDG_DATA_HOME@ env var is defined, then @${XDG_DATA_HOME}/dhall-docs@ will be returned. Otherwise, "${HOME}/.local/share/dhall-docs" -} getDocsHomeDirectory :: IO (Path Abs Dir) getDocsHomeDirectory = do dir <- Path.IO.getXdgDir Path.IO.XdgData $ Just $ [Path.reldir|dhall-docs|] Path.IO.ensureDir dir return dir {-| Compute the hash for a directory. It takes into account the hierarchy structure of it and the contents of its files, but not the name of the actual files. This is done by computing the hash of each file and sorting them by its absolute file name, and computing the hash of the concatenation of all hashes. -} makeHashForDirectory :: Path Abs Dir -> IO SHA256Digest makeHashForDirectory dir = do -- Builds a map so key order is preserved between several calls files <- Data.List.sort . map Path.fromRelFile . snd <$> Path.IO.listDirRecurRel dir let setTimeToZero entry = entry{Tar.Entry.entryTime = 0} inMemoryTarBytes <- Data.ByteString.Lazy.toStrict . Tar.write . map setTimeToZero <$> Tar.pack (Path.fromAbsDir dir) files return $ sha256Hash inMemoryTarBytes