Merge pull request #38 from fabricatedmath/master

added 'embedFileIfExists'
This commit is contained in:
Michael Snoyman 2021-05-10 19:00:04 +03:00 committed by GitHub
commit 6633884509
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 2 deletions

View File

@ -19,6 +19,7 @@
module Data.FileEmbed
( -- * Embed at compile time
embedFile
, embedFileIfExists
, embedOneFileOf
, embedDir
, embedDirListing
@ -60,13 +61,14 @@ import qualified Data.ByteString.Internal as B
#endif
import System.Directory (doesDirectoryExist, doesFileExist,
getDirectoryContents, canonicalizePath)
import Control.Exception (throw, ErrorCall(..))
import Control.Monad (filterM)
import Control.Exception (throw, tryJust, ErrorCall(..))
import Control.Monad (filterM, guard)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Control.Arrow ((&&&), second)
import Control.Applicative ((<$>))
import Data.ByteString.Unsafe (unsafePackAddressLen)
import System.IO.Error (isDoesNotExistError)
import System.IO.Unsafe (unsafePerformIO)
import System.FilePath ((</>), takeDirectory, takeExtension)
import Data.String (fromString)
@ -87,6 +89,31 @@ embedFile fp =
#endif
(runIO $ B.readFile fp) >>= bsToExp
-- | Maybe embed a single file in your source code depending on whether or not file exists.
--
-- Warning: When a build is compiled with the file missing, a recompile when the file exists might not trigger an embed of the file.
-- You might try to fix this by doing a clean build.
--
-- > import qualified Data.ByteString
-- >
-- > maybeMyFile :: Maybe Data.ByteString.ByteString
-- > maybeMyFile = $(embedFileIfExists "dirName/fileName")
embedFileIfExists :: FilePath -> Q Exp
embedFileIfExists fp = do
mbs <- runIO maybeFile
case mbs of
Nothing -> [| Nothing |]
Just bs -> do
#if MIN_VERSION_template_haskell(2,7,0)
qAddDependentFile fp
#endif
[| Just $(bsToExp bs) |]
where
maybeFile :: IO (Maybe B.ByteString)
maybeFile =
either (const Nothing) Just <$>
tryJust (guard . isDoesNotExistError) (B.readFile fp)
-- | Embed a single existing file in your source code
-- out of list a list of paths supplied.
--

View File

@ -33,6 +33,7 @@ test-suite test
main-is: main.hs
hs-source-dirs: test
build-depends: base
, bytestring
, file-embed
, filepath

View File

@ -2,6 +2,7 @@
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad (unless)
import qualified Data.ByteString as B (ByteString, filter)
import Data.FileEmbed
import System.FilePath ((</>))
@ -19,3 +20,9 @@ main = do
]
let str = $(embedStringFile "test/sample/foo") :: String
filter (/= '\r') str @?= "foo\n"
let mbs = $(embedFileIfExists "test/sample/foo")
fmap (B.filter (/= fromIntegral (fromEnum '\r'))) mbs @?= Just "foo\n"
let mbs2 = $(embedFileIfExists "test/sample/foo2") :: Maybe B.ByteString
mbs2 @?= Nothing