{-|
Module : Project
Description : Project system for PP ('pp.yaml' file)
Copyright : (c) 2017 Patrick Champion
License : see LICENSE file
Maintainer : chlablak@gmail.com
Stability : provisional
Portability : portable
-}
{-# LANGUAGE OverloadedStrings #-}
module Project
( Project(..)
, ProjectTemplate(..)
, ProjectTest(..)
, get
, set
) where
import qualified Args
import Control.Monad
import Data.Maybe
import Data.Yaml ((.:), (.=))
import qualified Data.Yaml as Y
import qualified Log
import System.Directory
import System.IO
-- |Project file
pFile :: String -> FilePath
pFile d = d ++ "/pp.yaml"
-- |Project configuration
data Project = Project
{ projectName :: String
, projectVersion :: String
, projectDescription :: String
, projectGrammars :: [String]
, projectTemplates :: [ProjectTemplate]
, projectUseWork :: Bool
, projectTests :: [ProjectTest]
}
| NoProject
| MalformedProject String
deriving (Eq, Show)
data ProjectTemplate = ProjectTemplate
{ templateFile :: String
, templateDst :: String
} deriving (Eq, Show)
data ProjectTest = ProjectTest
{ testFile :: String
, testAstDst :: String
} deriving (Eq, Show)
instance Y.FromJSON Project where
parseJSON (Y.Object v) = Project <$> v .: "name"
<*> v .: "version"
<*> v .: "description"
<*> v .: "grammars"
<*> v .: "templates"
<*> v .: "use-work"
<*> v .: "tests"
instance Y.ToJSON Project where
toJSON v = Y.object [ "name" .= projectName v
, "version" .= projectVersion v
, "description" .= projectDescription v
, "grammars" .= projectGrammars v
, "templates" .= projectTemplates v
, "use-work" .= projectUseWork v
, "tests" .= projectTests v]
instance Y.FromJSON ProjectTemplate where
parseJSON (Y.Object v) = ProjectTemplate <$> v .: "file"
<*> v .: "destination"
instance Y.ToJSON ProjectTemplate where
toJSON v = Y.object [ "file" .= templateFile v
, "destination" .= templateDst v]
instance Y.FromJSON ProjectTest where
parseJSON (Y.Object v) = ProjectTest <$> v .: "file"
<*> v .: "ast"
instance Y.ToJSON ProjectTest where
toJSON v = Y.object [ "file" .= testFile v
, "ast" .= testAstDst v]
-- |Get project config
get :: Log.LoggerIO Project
get = do
let f = pFile "."
e <- Log.io $ doesFileExist f
if e then do
p <- Log.io (Y.decodeFileEither f :: IO (Either Y.ParseException Project))
case p of
Left err -> return $ MalformedProject $ show err
Right q -> return q
else
return NoProject
-- |Set project config
set :: Project -> Log.Logger
set p = do
e <- Log.io $ doesFileExist $ pFile "."
let f = if e then "." else projectName p
Log.io $ Y.encodeFile (pFile f) p