-- | The information from Paths_rattle cleaned up module General.Paths( rattleVersionString, initDataDirectory, readDataFileHTML ) where import Paths_rattle import Control.Exception import Control.Monad.Extra import Data.Version import System.Directory import System.FilePath import System.IO.Unsafe import System.Environment import General.Extra import qualified Data.ByteString.Lazy as LBS rattleVersionString :: String rattleVersionString = showVersion version -- We want getDataFileName to be relative to the current directory on program startup, -- even if we issue a change directory command. Therefore, first call caches, future ones read. {-# NOINLINE dataDirs #-} dataDirs :: [String] dataDirs = unsafePerformIO $ do datdir <- getDataDir exedir <- takeDirectory <$> getExecutablePath `catchIO` \_ -> pure "" curdir <- getCurrentDirectory pure $ [datdir] ++ [exedir | exedir /= ""] ++ [curdir] -- | The data files may be located relative to the current directory, if so cache it in advance. initDataDirectory :: IO () initDataDirectory = void $ evaluate dataDirs getDataFile :: FilePath -> IO FilePath getDataFile file = do let poss = map ( file) dataDirs res <- filterM doesFileExist_ poss case res of [] -> fail $ unlines $ ("Could not find data file " ++ file ++ ", looked in:") : map (" " ++) poss x:_ -> pure x readDataFileHTML :: FilePath -> IO LBS.ByteString readDataFileHTML file = LBS.readFile =<< getDataFile ("html" file)