dhall-docs-0.0.1: src/Dhall/Docs/Store.hs
{-| 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