module Data.Git.Config
( Config(..)
, Section(..)
, readConfig
) where
import Control.Applicative
import Data.Git.Path
import Filesystem.Path.CurrentOS
newtype Config = Config [Section]
deriving (Show,Eq)
data Section = Section
{ sectionName :: String
, sectionKVs :: [(String, String)]
} deriving (Show,Eq)
parseConfig :: String -> Config
parseConfig = Config . reverse . toSections . foldl accSections ([], Nothing) . lines
where toSections (l,Nothing) = l
toSections (l,Just s) = s : l
accSections (sections, mcurrent) ('[':sectNameE)
| last sectNameE == ']' =
let sectName = take (length sectNameE 1) sectNameE
in case mcurrent of
Nothing -> (sections, Just $ Section sectName [])
Just current -> (sectionFinalize current : sections, Just $ Section sectName [])
| otherwise =
(sections, mcurrent)
accSections acc@(_, Nothing) _ = acc
accSections (sections, Just current) kvLine =
case break (== '=') kvLine of
(k,'=':v) -> (sections, Just $ sectionAppend current (strip k, strip v))
(_,_) -> (sections, Just current)
sectionAppend (Section n l) kv = Section n (kv:l)
sectionFinalize (Section n l) = Section n $ reverse l
strip s = dropSpaces $ reverse $ dropSpaces $ reverse s
where dropSpaces = dropWhile (\c -> c == ' ' || c == '\t')
readConfigPath filepath = parseConfig <$> readFile (encodeString filepath)
readConfig gitRepo = readConfigPath (configPath gitRepo)