ede-0.2.3: src/Main.hs
{-# LANGUAGE RecordWildCards #-}
-- Module : Text.EDE
-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
-- License : This Source Code Form is subject to the terms of
-- the Mozilla Public License, v. 2.0.
-- A copy of the MPL can be found in the LICENSE file or
-- you can obtain it at http://mozilla.org/MPL/2.0/.
-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability : experimental
-- Portability : non-portable (GHC extensions)
module Main (main) where
import Control.Monad
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as LBS
import Data.Conduit
import qualified Data.Conduit.Attoparsec as Conduit
import qualified Data.Conduit.Binary as Conduit
import Data.Monoid
import qualified Data.Text.Lazy.IO as Text
import Data.Version (showVersion)
import Options.Applicative
import qualified System.Directory as Dir
import qualified System.IO as IO
import qualified Text.EDE as EDE
data Options = Options
{ template :: FilePath
, bindings :: Maybe Object
, alternate :: !Bool
} deriving (Eq, Show)
optionParser :: Parser Options
optionParser = Options
<$> (strOption
( short 't'
<> long "template"
<> metavar "FILE"
<> help "ED-E template to render."
)
<|> argument str (metavar "FILE"))
<*> optional (option (eitherReader reader)
( short 'd'
<> long "data"
<> metavar "JSON"
<> help "Bindings to make available in the environment, as JSON. \
\If not given, standard input is read."
))
<*> switch
( short 'a'
<> long "alternate-syntax"
<> help "Use alternate template syntax."
)
optionInfo :: ParserInfo Options
optionInfo = info (helper <*> optionParser)
( fullDesc
<> header ("ed-e v" ++ showVersion EDE.version)
<> progDesc "ED-E Template Engine CLI."
)
main :: IO ()
main = execParser optionInfo >>= render
where
render Options{..} = do
t <- parse template alternate
b <- maybe stdin return bindings
EDE.result errRender Text.putStrLn (EDE.render t b)
parse f alt = do
p <- Dir.getPermissions f
unless (Dir.readable p) (errUnreadable f)
let syntax | alt = EDE.alternateSyntax
| otherwise = EDE.defaultSyntax
EDE.parseFileWith syntax f >>=
EDE.result (error . show) return
stdin = do
IO.hSetBinaryMode IO.stdin True
v <- Conduit.sourceHandle IO.stdin $$ Conduit.sinkParser json'
either (error . show) return (fromValue v)
errRender = error . mappend "Error rendering template:\n" . show
errUnreadable = error . (<> " is not readable")
reader :: String -> Either String Object
reader = join . fmap fromValue . eitherDecode . LBS.pack
fromValue :: Value -> Either String Object
fromValue = maybe (Left "Bindings must be given as a JSON object") Right
. EDE.fromValue