{-# LANGUAGE OverloadedStrings #-} module HsDev.Cache ( escapePath, versionCache, packageDbCache, projectCache, standaloneCache, dump, load, writeVersion, readVersion, -- * Reexports Database ) where import Control.DeepSeq (force) import Control.Exception import Control.Lens (view) import Data.Aeson (encode, eitherDecode) import Data.Aeson.Encode.Pretty (encodePretty) import qualified Data.ByteString.Lazy.Char8 as BS import Data.Char (isAlphaNum) import Data.List (intercalate) import System.FilePath import Text.Read (readMaybe) import HsDev.PackageDb import HsDev.Project import HsDev.Database (Database) import HsDev.Version import HsDev.Util (split, version) -- | Escape path escapePath :: FilePath -> FilePath escapePath = intercalate "." . map (filter isAlphaNum) . splitDirectories -- | Name of cache for version versionCache :: FilePath versionCache = "version" <.> "json" -- | Name of cache for cabal packageDbCache :: PackageDb -> FilePath packageDbCache GlobalDb = "global" <.> "json" packageDbCache UserDb = "user" <.> "json" packageDbCache (PackageDb p) = escapePath p <.> "json" -- | Name of cache for projects projectCache :: Project -> FilePath projectCache p = (escapePath . view projectPath $ p) <.> "json" -- | Name of cache for standalone files standaloneCache :: FilePath standaloneCache = "standalone" <.> "json" -- | Dump database to file dump :: FilePath -> Database -> IO () dump file = BS.writeFile file . encodePretty -- | Load database from file, strict load :: FilePath -> IO (Either String Database) load file = handle onIO $ do cts <- BS.readFile file return $ force $ eitherDecode cts where onIO :: IOException -> IO (Either String Database) onIO _ = return $ Left $ "IO exception while reading cache from " ++ file -- | Write version writeVersion :: FilePath -> IO () writeVersion file = BS.writeFile file $ encode version -- | Read version readVersion :: FilePath -> IO (Maybe [Int]) readVersion file = handle onIO $ do cts <- BS.readFile file return $ either (const Nothing) id $ eitherDecode cts where onIO :: IOException -> IO (Maybe [Int]) onIO _ = return Nothing