File: Main.hs

package info (click to toggle)
haskell-mustache 2.4.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 184 kB
  • sloc: haskell: 1,212; makefile: 3
file content (72 lines) | stat: -rw-r--r-- 2,283 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE NamedFieldPuns     #-}
module Main (main) where


import           Data.Aeson                      (Value, eitherDecode)
import           Data.Bifunctor                  (first)
import qualified Data.ByteString                 as B (readFile)
import qualified Data.ByteString.Lazy            as BS (readFile)
import           Data.Foldable                   (for_)
import qualified Data.Text.IO                    as TIO (putStrLn)
import           Data.Yaml                       (decodeEither')

import           System.Console.CmdArgs.Implicit (Data, Typeable, argPos, args,
                                                  cmdArgs, def, help, summary,
                                                  typ, (&=))
import           System.FilePath                 (takeExtension)
import           Text.Mustache                   (automaticCompile, substitute,
                                                  toMustache)


data Arguments = Arguments
  { template     :: FilePath
  , templateDirs :: [FilePath]
  , dataFiles    :: [FilePath]
  } deriving (Show, Data, Typeable)


commandArgs :: Arguments
commandArgs = Arguments
  { template = def
      &= argPos 0
      &= typ "TEMPLATE"
  , dataFiles = def
      &= args
      &= typ "DATA-FILES"
  , templateDirs = ["."]
      &= help "The directories in which to search for the templates"
      &= typ "DIRECTORIES"
  } &= summary "Simple mustache template subtitution"


readJSON :: FilePath -> IO (Either String Value)
readJSON = fmap eitherDecode . BS.readFile


readYAML :: FilePath -> IO (Either String Value)
readYAML = fmap (first show . decodeEither') . B.readFile


main :: IO ()
main = do
  (Arguments { template, templateDirs, dataFiles }) <- cmdArgs commandArgs

  eitherTemplate <- automaticCompile templateDirs template

  case eitherTemplate of
    Left err -> print err
    Right compiledTemplate ->
      for_ dataFiles $ \file -> do

        let decoder =
              case takeExtension file of
                ".yml"  -> readYAML
                ".yaml" -> readYAML
                _       -> readJSON
        decoded <- decoder file

        either
          putStrLn
          (TIO.putStrLn . substitute compiledTemplate . toMustache)
          decoded