{-# LANGUAGE CPP #-}
#ifdef FILE_EMBED
{-# LANGUAGE TemplateHaskell #-}
#endif
module Development.Shake.Internal.Paths(
shakeVersionString,
initDataDirectory,
hasManualData, copyManualData,
readDataFileHTML
) where
import Control.Monad.Extra
import Data.Version
import System.FilePath
import General.Extra
import qualified Data.ByteString.Lazy as LBS
import Paths_shake
#ifdef FILE_EMBED
import qualified Data.ByteString as BS
import Data.FileEmbed
#else
import Control.Exception
import System.Directory
import System.Info.Extra
import System.IO.Unsafe
import System.Environment
#endif
shakeVersionString :: String
shakeVersionString = showVersion version
#ifdef FILE_EMBED
initDataDirectory :: IO ()
initDataDirectory = pure ()
htmlDataFiles :: [(FilePath, BS.ByteString)]
htmlDataFiles =
[ ("profile.html", $(embedFile "html/profile.html"))
, ("progress.html", $(embedFile "html/progress.html"))
, ("shake.js", $(embedFile "html/shake.js"))
]
readDataFileHTML :: FilePath -> IO LBS.ByteString
readDataFileHTML file = do
case lookup file htmlDataFiles of
Nothing -> fail $ "Could not find data file " ++ file ++ " in embedded data files!"
Just x -> pure (LBS.fromStrict x)
manualDirData :: [(FilePath, BS.ByteString)]
manualDirData = $(embedDir "docs/manual")
hasManualData :: IO Bool
hasManualData = pure True
copyManualData :: FilePath -> IO ()
copyManualData dest = do
createDirectoryRecursive dest
forM_ manualDirData $ \(file, bs) -> do
BS.writeFile (dest </> file) bs
#else
{-# NOINLINE dataDirs #-}
dataDirs :: [String]
dataDirs = unsafePerformIO $ do
datdir <- getDataDir
exedir <- takeDirectory <$> getExecutablePath `catchIO` \_ -> pure ""
curdir <- getCurrentDirectory
pure $ [datdir] ++ [exedir | exedir /= ""] ++ [curdir]
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
hasDataFile :: FilePath -> IO Bool
hasDataFile file = anyM (\dir -> doesFileExist_ $ dir </> file) dataDirs
readDataFileHTML :: FilePath -> IO LBS.ByteString
readDataFileHTML file = LBS.readFile =<< getDataFile ("html" </> file)
manualFiles :: [FilePath]
manualFiles = map ("docs/manual" </>) ["Shakefile.hs","main.c","constants.c","constants.h","build" <.> if isWindows then "bat" else "sh"]
hasManualData :: IO Bool
hasManualData = allM hasDataFile manualFiles
copyManualData :: FilePath -> IO ()
copyManualData dest = do
createDirectoryRecursive dest
forM_ manualFiles $ \file -> do
src <- getDataFile file
copyFile src (dest </> takeFileName file)
#endif