|
@@ -0,0 +1,98 @@
|
|
|
+{-# LANGUAGE OverloadedStrings #-}
|
|
|
+
|
|
|
+module Collage.Config
|
|
|
+( Config(..)
|
|
|
+, Source(..)
|
|
|
+, Expose(..)
|
|
|
+, getConfig
|
|
|
+, example
|
|
|
+) where
|
|
|
+
|
|
|
+import Control.Applicative ((<|>))
|
|
|
+import qualified Data.Adnot as A
|
|
|
+import qualified Data.ByteString as B
|
|
|
+import qualified Data.Map.Strict as M
|
|
|
+import qualified Data.Text as T
|
|
|
+import qualified Data.Vector as V
|
|
|
+
|
|
|
+data Config = Config
|
|
|
+ { confDocument :: T.Text
|
|
|
+ , confSources :: [Source]
|
|
|
+ } deriving (Eq, Show)
|
|
|
+
|
|
|
+instance A.FromAdnot Config where
|
|
|
+ parseAdnot = A.withSumNamed "config file" "document" go
|
|
|
+ where
|
|
|
+ go payload
|
|
|
+ | Just file <- payload V.!? 0
|
|
|
+ = Config <$> A.withString "file name" pure file
|
|
|
+ <*> mapM A.parseAdnot (V.toList (V.tail payload))
|
|
|
+ | otherwise = Left "expected source file in config"
|
|
|
+
|
|
|
+
|
|
|
+data Source = Source
|
|
|
+ { sourceName :: T.Text
|
|
|
+ , sourceDir :: FilePath
|
|
|
+ , sourceCommands :: [String]
|
|
|
+ , sourceExpose :: [Expose]
|
|
|
+ } deriving (Eq, Show)
|
|
|
+
|
|
|
+instance A.FromAdnot Source where
|
|
|
+ parseAdnot = A.withProduct "source" $ \p -> do
|
|
|
+ name <- p A..: "name"
|
|
|
+ dir <- p A..: "dir"
|
|
|
+ cmds <- p A..: "cmd"
|
|
|
+ expose <- p A..: "expose" <|> (fmap pure (p A..: "expose"))
|
|
|
+ return (Source name dir cmds expose)
|
|
|
+
|
|
|
+
|
|
|
+data Expose
|
|
|
+ = ExposeFile FilePath
|
|
|
+ | ExposeSections FilePath
|
|
|
+ | NamedMap (M.Map T.Text Expose)
|
|
|
+ deriving (Eq, Show)
|
|
|
+
|
|
|
+instance A.FromAdnot Expose where
|
|
|
+ parseAdnot v = file v <|> sections v <|> namedMap v
|
|
|
+ where
|
|
|
+ file = A.withSumNamed "exposed fragments" "file" $ \ ps ->
|
|
|
+ case V.toList ps of
|
|
|
+ [] -> Left "Expected name for file"
|
|
|
+ [f] -> ExposeFile <$> A.parseAdnot f
|
|
|
+ _ -> Left "Too many arguments to file"
|
|
|
+
|
|
|
+ sections = A.withSumNamed "exposed fragments" "sections" $ \ ps ->
|
|
|
+ case V.toList ps of
|
|
|
+ [] -> Left "Expected name for sections"
|
|
|
+ [f] -> ExposeFile <$> A.parseAdnot f
|
|
|
+ _ -> Left "Too many arguments to sections"
|
|
|
+
|
|
|
+ namedMap = A.withProduct "exposed fragments" $ \ p ->
|
|
|
+ NamedMap <$> mapM A.parseAdnot p
|
|
|
+
|
|
|
+parseConfig :: B.ByteString -> Either String Config
|
|
|
+parseConfig = A.decode
|
|
|
+
|
|
|
+getConfig :: FilePath -> IO (Either String Config)
|
|
|
+getConfig loc = do
|
|
|
+ loc <- B.readFile loc
|
|
|
+ return (parseConfig loc)
|
|
|
+
|
|
|
+example :: Config
|
|
|
+example = Config
|
|
|
+ { confDocument = "main.md"
|
|
|
+ , confSources =
|
|
|
+ [ Source
|
|
|
+ { sourceName = "rust-sample"
|
|
|
+ , sourceDir = "s1"
|
|
|
+ , sourceCommands = ["cargo clean", "cargo build"]
|
|
|
+ , sourceExpose = [ExposeFile "src/main.rs"]
|
|
|
+ }
|
|
|
+ , Source
|
|
|
+ { sourceName = "haskell-sample"
|
|
|
+ , sourceDir = "s2"
|
|
|
+ , sourceCommands = ["cabal new-build"]
|
|
|
+ , sourceExpose = [ExposeSections "Main.hs"]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|