inject (empty) → 0.1.0
raw patch · 7 files changed
+168/−0 lines, 7 filesdep +attoparsecdep +basedep +hspecsetup-changed
Dependencies added: attoparsec, base, hspec, hspec-expectations, inject, process, text
Files
- LICENSE +19/−0
- Setup.lhs +3/−0
- driver/Main.hs +8/−0
- inject.cabal +64/−0
- src/Text/Inject.hs +50/−0
- src/Util.hs +23/−0
- test/Spec.hs +1/−0
+ LICENSE view
@@ -0,0 +1,19 @@+Copyright (c) 2013 Simon Hengel <sol@typeful.net>++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ driver/Main.hs view
@@ -0,0 +1,8 @@+module Main (main) where++import qualified Data.Text.IO as T++import Text.Inject++main :: IO ()+main = T.getContents >>= inject >>= T.putStr
+ inject.cabal view
@@ -0,0 +1,64 @@+name: inject+version: 0.1.0+license: MIT+license-file: LICENSE+copyright: (c) 2013 Simon Hengel+author: Simon Hengel <sol@typeful.net>+maintainer: Simon Hengel <sol@typeful.net>+build-type: Simple+cabal-version: >= 1.8+category: Text+synopsis: A minimalistic template engine+description: Inject expands shell commands in arbitrary text templates.+ .+ <https://github.com/sol/inject#readme>++source-repository head+ type: git+ location: https://github.com/sol/inject++library+ ghc-options:+ -Wall+ hs-source-dirs:+ src+ exposed-modules:+ Text.Inject+ other-modules:+ Util+ build-depends:+ base == 4.*+ , text+ , process+ , attoparsec++executable inject+ ghc-options:+ -Wall+ hs-source-dirs:+ driver+ main-is:+ Main.hs+ build-depends:+ base == 4.*+ , text+ , inject++test-suite spec+ type:+ exitcode-stdio-1.0+ ghc-options:+ -Wall -Werror+ cpp-options:+ -DTEST+ hs-source-dirs:+ src, test+ main-is:+ Spec.hs+ build-depends:+ base == 4.*+ , text+ , process+ , attoparsec+ , hspec >= 1.3+ , hspec-expectations
+ src/Text/Inject.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE OverloadedStrings, CPP #-}+module Text.Inject (+ inject+#ifdef TEST+, Element (..)+, pBraces+#endif+) where++import Prelude hiding (takeWhile)+import Control.Applicative+import Data.Text (Text)+import qualified Data.Text as T+import Data.Attoparsec.Text+import Util++type Template = [Element]++data Element = Plain Text | Braces Text+ deriving (Eq, Show)++inject :: Text -> IO Text+inject = fmap T.concat . mapM f . parseTemplate+ where+ f :: Element -> IO Text+ f element = case element of+ Plain text -> return text+ Braces cmd -> system (T.unpack cmd)++parseTemplate :: Text -> Template+parseTemplate = either parseError id . parseOnly (pTemplate <* endOfInput)+ where+ parseError = (error . unwords) [+ "Parsing failed."+ , "This should never happen"+ , "Please report a bug!"+ ]++pTemplate :: Parser Template+pTemplate = many (pBraces <|> (Plain <$> pText))++pText :: Parser Text+pText = T.cons <$> anyChar <*> takeWhile (/= '{')++pBraces :: Parser Element+pBraces = Braces . T.init <$> ("{{" *> scan 0 f <* "}")+ where+ f 0 '}' = Just 1+ f 1 '}' = Nothing+ f _ _ = Just (0 :: Int)
+ src/Util.hs view
@@ -0,0 +1,23 @@+module Util where++import qualified Control.Exception as E+import System.Process+import System.IO (hClose)+import System.Exit+import Data.Text+import Data.Text.IO+++system :: String -> IO Text+system cmd = E.mask $ \restore -> do+ (Nothing, Just h, Nothing, pid) <- createProcess (shell cmd) {std_out = CreatePipe}+ restore $ do+ output <- hGetContents h+ waitForProcess pid >>= \r -> case r of+ ExitSuccess -> return output+ ExitFailure c ->+ (E.throwIO . userError) ("system: " ++ cmd ++ " (exit " ++ show c ++ ")")+ `E.onException` do+ hClose h+ terminateProcess pid+ waitForProcess pid
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}