keyword-args (empty) → 0.1.0.0
raw patch · 6 files changed
+218/−0 lines, 6 filesdep +basedep +bytestringdep +cassavasetup-changed
Dependencies added: base, bytestring, cassava, containers, hspec, parsec
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- keyword-args.cabal +57/−0
- spec/Spec.hs +1/−0
- src/Data/KeywordArgs/Parse.hs +48/−0
- src/Main.hs +90/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2015 Justin Leitgeb++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.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ keyword-args.cabal view
@@ -0,0 +1,57 @@+name: keyword-args+version: 0.1.0.0+synopsis: Extract data from a keyword-args config file format++description: Extracts data from a configuration file with keywords+ separated fram arguments by one or more spaces. Removes+ comments and unnecessary whitespace.++license: MIT+license-file: LICENSE+author: Justin Leitgeb+maintainer: justin@stackbuilders.com+copyright: 2015 Stack Builders Inc.+category: System+build-type: Simple+cabal-version: >=1.10+++executable keyword-args+ main-is: Main.hs+ other-modules: Data.KeywordArgs.Parse++ build-depends: base >=4.5 && <4.8+ , parsec >= 3.1.0 && <= 3.2+ , containers+ , cassava+ , bytestring++ hs-source-dirs: src+ default-language: Haskell2010+++library+ exposed-modules: Data.KeywordArgs.Parse+ build-depends: base >=4.5 && <4.8+ , parsec >= 3.1.0 && <= 3.2+ , containers++ hs-source-dirs: src+ default-language: Haskell2010+++test-suite keyword-args-test+ type: exitcode-stdio-1.0+ hs-source-dirs: spec, src+ main-is: Spec.hs+ build-depends: base >=4.5 && <4.8+ , parsec >= 3.1.0 && <= 3.2+ , containers++ , hspec++ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/stackbuilders/keyword-args
+ spec/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ src/Data/KeywordArgs/Parse.hs view
@@ -0,0 +1,48 @@+module Data.KeywordArgs.Parse (configParser) where++import Data.Maybe (catMaybes)+import Data.Char (isSpace)++import Text.Parsec ((<|>), many, try, manyTill, char, anyChar, many1, satisfy)+import Text.Parsec.String (Parser)++import Text.ParserCombinators.Parsec.Char (string, space, tab, newline,+ alphaNum)++import Text.Parsec.Combinator (eof)++import Control.Applicative ((<*), (*>), (<$>))++configParser :: Parser [(String, String)]+configParser = catMaybes <$> many line+++configurationOption :: Parser (String, String)+configurationOption = do+ many space++ option <- many1 (satisfy (not . isSpace))++ many1 space++ let+ endOfOption = comment <|> endOfLineOrInput+ quotedValue = char '"' *> manyTill anyChar (try (char '"')) <* endOfOption+ unquotedValue = manyTill anyChar endOfOption++ value <- quotedValue <|> unquotedValue++ return (option, value)++comment :: Parser ()+comment =+ -- ^ use `try` to avoid consuming leading spaces if no match+ try (many space *> char '#')+ *> manyTill anyChar endOfLineOrInput+ *> return ()++endOfLineOrInput :: Parser ()+endOfLineOrInput = newline *> return () <|> eof++line :: Parser (Maybe (String, String))+line = comment *> return Nothing <|> Just <$> configurationOption
+ src/Main.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE OverloadedStrings #-}++module Main where++import System.Console.GetOpt++import System.Environment (getArgs, getProgName)+import System.Exit (ExitCode(..), exitWith, exitSuccess)+import System.IO.Error (ioError)++import Paths_keyword_args (version)+import Data.Maybe (fromMaybe)++import Data.Version (showVersion)++import Data.ByteString.Lazy.Char8 (unpack)++import Data.KeywordArgs.Parse++import Text.Parsec+import Text.ParserCombinators.Parsec.Error (ParseError)++import Data.Csv (encode)++data Options = Options+ { optShowVersion :: Bool+ , optShowHelp :: Bool+ } deriving Show++defaultOptions = Options+ { optShowVersion = False+ , optShowHelp = False+ }++options :: [OptDescr (Options -> Options)]+options =+ [ Option ['V'] ["version"] (NoArg (\opts -> opts { optShowVersion = True }))+ "show version number"++ , Option ['h'] ["help"] (NoArg (\opts -> opts { optShowHelp = True }))+ "show help"+ ]++showHelp = do+ prg <- getProgName+ putStrLn (usageInfo prg options)+ exitSuccess++headerMessage :: String -> String+headerMessage progName = "Usage: " ++ progName ++ " [OPTION...]"++lintOpts :: [String] -> IO (Options, [String])+lintOpts argv = do+ name <- getProgName++ case getOpt Permute options argv of+ (o, n, [] ) -> return (foldl (flip id) defaultOptions o, n)+ (_, _, errs) ->+ ioError (userError (concat errs ++ usageInfo (headerMessage name) options))++parseConfig :: String -> Either ParseError [(String, String)]+parseConfig = parse configParser "(unknown)"++runCheck :: IO ()+runCheck = do++ f <- getContents++ case parseConfig f of+ Left e -> do+ ioError $ userError $ "Parse error: " ++ show e++ Right config -> putStr $ unpack $ encode config+++main :: IO ()+main = do+ opts <- getArgs >>= lintOpts++ name <- getProgName++ if optShowHelp $ fst opts+ then+ putStrLn $ usageInfo (headerMessage name) options+ else+ if optShowVersion $ fst opts then+ putStrLn $ name ++ " " ++ showVersion version +++ " (C) 2015 Stack Builders Inc."+ else+ runCheck