@@ -0,0 +1,62 @@
1+{-# LANGUAGE LambdaCase #-}
2+module Obelisk.ExecutableConfig.Internal where
3+
4+import Control.Exception (bracket)
5+import Control.Monad (forM)
6+import qualified Data.ByteString as BS
7+import Data.List (sortOn)
8+import Data.Maybe (catMaybes, maybe)
9+import Data.Text (Text)
10+import qualified Data.Text as T
11+import qualified Data.Text.Encoding as T
12+import Foreign.C.String (withCString)
13+import Foreign.Ptr (nullPtr)
14+import System.FilePath.Posix ((</>))
15+
16+import Obelisk.ExecutableConfig.Internal.AssetManager
17+
18+getFromMgr mgr withCS name = do
19+ let open = do
20+ a <- withCS name $ \fn ->
21+ assetManager_open mgr fn 3
22+ return $ if unAAsset a == nullPtr
23+ then Nothing
24+ else Just a
25+ close = mapM_ asset_close
26+ bracket open close $ mapM $ \asset -> do
27+ b <- asset_getBuffer asset
28+ l <- asset_getLength asset
29+ fmap T.decodeUtf8 $ BS.packCStringLen (b, fromIntegral l)
30+
31+getFrontendConfigs :: IO [(Text, Text)]
32+getFrontendConfigs
33+ = fmap (sortOn fst)
34+ $ getConfigs
35+ $ \fp -> BS.isPrefixOf (BS.pack $ fmap (fromIntegral . fromEnum) "config/common/") fp
36+ || BS.isPrefixOf (BS.pack $ fmap (fromIntegral . fromEnum) "config/frontend/") fp
37+
38+getConfigs :: (BS.ByteString -> Bool) -> IO [(Text, Text)]
39+getConfigs p = bracket getAssets freeAssetManager $ \mgrObj -> do
40+ mgr <- assetManagerFromJava mgrObj
41+ let openDir = do
42+ d <- withCString "config.files" $ \fn ->
43+ assetManager_open mgr fn 3
44+ return $ if unAAsset d == nullPtr
45+ then Nothing
46+ else Just d
47+ closeDir = mapM_ asset_close
48+ configPaths <- bracket openDir closeDir $ \case
49+ Just asset -> do
50+ b <- asset_getBuffer asset
51+ l <- asset_getLength asset
52+ lines0 <$> BS.packCStringLen (b, fromIntegral l)
53+ Nothing -> error "could not open configuration manifest 'config.files'"
54+ fmap catMaybes $ forM (filter p configPaths) $ \fp ->
55+ fmap (\v -> (T.decodeUtf8 fp,v)) <$> getFromMgr mgr BS.useAsCString fp
56+
57+lines0 :: BS.ByteString -> [BS.ByteString]
58+lines0 ps
59+ | BS.null ps = []
60+ | otherwise = case BS.elemIndex 0 ps of
61+ Nothing -> [ps]
62+ Just n -> BS.take n ps : lines0 (BS.drop (n+1) ps)