packages feed

conf 0.1.0.0 → 0.1.1.0

raw patch · 7 files changed

+204/−39 lines, 7 filesdep +HUnitdep +confdep +test-frameworkdep ~base

Dependencies added: HUnit, conf, test-framework, test-framework-hunit, test-framework-th

Dependency ranges changed: base

Files

.gitignore view
@@ -1,2 +1,7 @@ dist/ *.swap+.cabal-sandbox+cabal.sandbox.config+out/+.idea/+*.iml
README.md view
@@ -1,20 +1,29 @@-Conf: Haskell-Style Config Parsing-===+Conf: Parser for Haskell-based configuration files.+=========== +Installation+-----------+You can install this library from Hackage via `cabal install conf`++Description+-----------+ This package is designed to allow you to create configuration files with declarative Haskell and parse the values back into Haskell code. The benefit here is to have a configuration file in Haskell that does-not have to be recompiled - it is interpreted/parsed at runtime in a +not have to be recompiled - it is interpreted/parsed at runtime in a type-safe manner. +Example usage:+ ```haskell--- Example configuration "my-config"+-- /path/to/my-config.hs foo = ["bar", "baz"] spam = Eggs ```  ```haskell--- Example application+-- Application source import Data.Conf import Data.Maybe @@ -24,14 +33,28 @@ getSpam :: Conf -> Spam getSpam = fromMaybe SomethingEntirelyDifferent . getConf "spam" -getFoo :: Conf -> Maybe [Int]+getFoo :: Conf -> Maybe Int getFoo = getConf "foo"  main = do-    conf <- readConf "/path/to/my-config"-    let spam = getSpam conf-    print spam  -- Output: "Eggs"-    let foo = getFoo conf-    print foo   -- Output: "Nothing"+    conf <- readConf "my-config.hs"+    print $ getSpam conf -- Output: Eggs+    print $ getFoo conf  -- Output: Nothing+```++Building+--------+```bash+cabal sandbox init  # If you haven't already+cabal install -j --dependencies-only+cabal build+```++Running the Tests+-----------------+```bash+cabal sandbox init  # If you haven't already+cabal install -j --enable-tests --dependencies-only+cabal test ``` 
conf.cabal view
@@ -1,10 +1,10 @@ name:                conf-version:             0.1.0.0+version:             0.1.1.0 license:             BSD3 license-file:        LICENSE author:              Cary M. Robbins maintainer:          carymrobbins@gmail.com-copyright:           Copyright (C) 2014 Cary M. Robbins+copyright:           Copyright (C) 2015 Cary M. Robbins category:            Configuration, Parsing build-type:          Simple cabal-version:       >=1.10@@ -13,7 +13,7 @@     This package is designed to allow you to create configuration files     with declarative Haskell and parse the values back into Haskell code.     The benefit here is to have a configuration file in Haskell that does-    not have to be recompiled - it is interpreted/parsed at runtime in a +    not have to be recompiled - it is interpreted/parsed at runtime in a     type-safe manner.     .     Example usage:@@ -21,32 +21,31 @@     > -- /path/to/my-config.hs     > foo = ["bar", "baz"]     > spam = Eggs-    >+    .     > -- Application source     > import Data.Conf     > import Data.Maybe-    > +    >     > data Spam = Eggs | Parrot | SomethingEntirelyDifferent     >     deriving (Show, Read)-    > +    >     > getSpam :: Conf -> Spam     > getSpam = fromMaybe SomethingEntirelyDifferent . getConf "spam"-    > -    > getFoo :: Conf -> Maybe Foo+    >+    > getFoo :: Conf -> Maybe Int     > getFoo = getConf "foo"     >     > main = do     >     conf <- readConf "my-config.hs"-    >     let spam = getSpam conf-    >     print spam-    >     let foo = getFoo conf-    >     print foo+    >     print $ getSpam conf -- Output: Eggs+    >     print $ getFoo conf  -- Output: Nothing  extra-source-files:     LICENSE     README.md     Setup.hs     .gitignore+    tools/generate-readme.hs  source-repository head     type: git@@ -55,11 +54,21 @@ library   exposed-modules:     Data.Conf                      , Data.Conf.Parser-  -- other-modules:       -  -- other-extensions:    -  build-depends:       base >=4.6 && <4.7-                     , haskell-src   hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall+  build-depends:       base >=4.6 && <4.8+                     , haskell-src +Test-Suite unit-test+  type:                exitcode-stdio-1.0+  main-is:             UnitTests.hs+  hs-source-dirs:      tests+  default-language:    Haskell2010+  build-depends:       conf+                     , base >=4.6 && <4.8+                     , HUnit+                     , test-framework+                     , test-framework-hunit+                     , test-framework-th+  other-extensions:    TemplateHaskell
src/Data/Conf.hs view
@@ -1,4 +1,4 @@-module Data.Conf (Conf, readConf, getConf) where+module Data.Conf (Conf, readConf, getConf, parseConf) where  import Control.Monad import Text.Read@@ -9,4 +9,3 @@  readConf :: String -> IO [(String, String)] readConf = liftM parseConf . readFile-
src/Data/Conf/Parser.hs view
@@ -1,24 +1,26 @@ module Data.Conf.Parser (Conf, parseConf) where +import Data.Maybe+ import Language.Haskell.Parser import Language.Haskell.Pretty import Language.Haskell.Syntax  type Conf = [(String, String)] -getModule :: ParseResult HsModule -> HsModule-getModule (ParseOk x) = x+getModule :: ParseResult HsModule -> Maybe HsModule+getModule (ParseOk x) = Just x+getModule _ = Nothing -getDecl :: HsModule -> [HsDecl]-getDecl (HsModule _ _ _ _ ds) = ds+getDecls :: HsModule -> [HsDecl]+getDecls (HsModule _ _ _ _ ds) = ds -getPair :: HsDecl -> (String, HsExp)-getPair (HsPatBind _ (HsPVar (HsIdent name)) (HsUnGuardedRhs value) _) =-    (name, value)+getPair :: HsDecl -> Maybe (String, HsExp)+getPair (HsPatBind _ (HsPVar (HsIdent name)) (HsUnGuardedRhs value) _) = Just (name, value)+getPair _ = Nothing  parseDecls :: String -> [HsDecl]-parseDecls = getDecl . getModule . parseModule+parseDecls s = maybe [] getDecls $ getModule $ parseModule s  parseConf :: String -> Conf-parseConf = map (fmap prettyPrint . getPair) . parseDecls-+parseConf s = map (fmap prettyPrint) $ mapMaybe getPair $ parseDecls s
+ tests/UnitTests.hs view
@@ -0,0 +1,31 @@+{-# LANGUAGE TemplateHaskell #-}+module Main where++import Test.Framework+import Test.Framework.TH+import Test.Framework.Providers.HUnit+import Test.HUnit hiding (test)++import Data.Conf+import Data.Maybe++myConfig = unlines+    [ "foo = [\"bar\", \"baz\"]"+    , "spam = Eggs"+    ]++data Spam = Eggs | Parrot | SomethingEntirelyDifferent+    deriving (Show, Read, Eq)++getSpam :: Conf -> Spam+getSpam = fromMaybe SomethingEntirelyDifferent . getConf "spam"++getFoo :: Conf -> Maybe Int+getFoo = getConf "foo"++case_example_usage = do+    let conf = parseConf myConfig+    getSpam conf @=? Eggs+    getFoo conf @=? Nothing++main = $(defaultMainGenerator)
+ tools/generate-readme.hs view
@@ -0,0 +1,96 @@+#!/usr/bin/env runghc++import Control.Arrow+import Data.Function+import Data.List+import Data.Maybe+import System.Environment++title = "Conf"+cabalFileName = "conf.cabal"+outputFileName = "README.md"++header synopsis = unlines+    [ title `applySynopsis` synopsis+    , "==========="+    , ""+    , "Installation"+    , "-----------"+    , "You can install this library from Hackage via `cabal install conf`"+    , ""+    , "Description"+    , "-----------"+    ]++footer = unlines+    [ "Building"+    , "--------"+    , "```bash"+    , "cabal sandbox init  # If you haven't already"+    , "cabal install -j --dependencies-only"+    , "cabal build"+    , "```"+    , ""+    , "Running the Tests"+    , "-----------------"+    , "```bash"+    , "cabal sandbox init  # If you haven't already"+    , "cabal install -j --enable-tests --dependencies-only"+    , "cabal test"+    , "```"+    ]++main = do+    args <- getArgs+    cabal <- readFile cabalFileName+    let synopsis = parseSynopsis cabal+    let readme = unlines [header synopsis, parseBody cabal, footer]+    handleArgs args readme++handleArgs args+    | "--stdout" `elem` args = putStrLn+    | otherwise = writeFile outputFileName++applySynopsis title synopsis  = intercalate ": " . filter (not . null) $ xs+  where+    xs = [title, synopsis]++parseSynopsis =+    lines >>>+    filter ("synopsis:" `isPrefixOf`) >>>+    head >>>+    break (== ':') >>>+    snd >>>+    dropWhile (`elem` [':', ' '])++parseBody =+    lines >>>+    parseDescription >>>+    parseNewlines >>>+    parseCode >>>+    unlines++parseDescription =+    dropWhile (/= "description:") >>>+    drop 1 >>>+    takeWhile ((== " ") . take 1) >>>+    map (dropWhile ((== ' ')))++parseNewlines = map f+  where+    f "." = ""+    f x = x++parseCode :: [String] -> [String]+parseCode =+    groupBy ((==) `on` take 1) >>>+    map applyCodeBlocks >>>+    concat++applyCodeBlocks :: [String] -> [String]+applyCodeBlocks xs+    | isCode xs = [ "```haskell" ] ++ map (drop 2) xs ++ [ "```" ]+    | otherwise = xs++isCode :: [String] -> Bool+isCode xs = (take 1 xs >>= take 1) == ">"