-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathOmniConfig.hs
57 lines (49 loc) · 1.77 KB
/
OmniConfig.hs
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
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, GADTs #-}
module OmniConfig (
OptionsSource(..), allProgramOpts, commandLine, environment, homeOptFile
, checkNegatedOpt
) where
import Prelude hiding (FilePath)
import System.Environment
import Control.Exception (SomeException, handle)
import qualified Data.Text as T
import Data.Text (Text)
import Filesystem.Path.CurrentOS
import Filesystem (readTextFile, getHomeDirectory)
allProgramOpts :: [OptionsSource] -> IO [Text]
allProgramOpts confs = do
fmap Prelude.concat $ mapM loadProgramOptions confs
checkNegatedOpt :: Text -> [Text] -> (Maybe Bool, [Text])
checkNegatedOpt optText args =
if elem negatedOpt args
then (Just False, filteredArgs)
else if elem opt args
then (Just True, filteredArgs)
else (Nothing, args)
where
filteredArgs = filter (\arg -> arg /= negatedOpt && arg /= opt) args
opt = "--" `T.append` optText
negatedOpt = "--no-" `T.append` optText
data OptionsSource = OptionsSource {
loadProgramOptions :: IO [Text]
}
commandLine :: OptionsSource
commandLine = OptionsSource {
loadProgramOptions = fmap (map T.pack) getArgs
}
environment :: Text -> OptionsSource
environment name = OptionsSource {
loadProgramOptions = do
env <- getEnvironment
return $ case lookup (T.unpack $ T.replace "-" "_" $ T.toUpper name `T.append` "_OPTS") env of
Nothing -> []
Just s -> T.splitOn " " $ T.pack s
}
homeOptFile :: Text -> OptionsSource
homeOptFile name = OptionsSource {
loadProgramOptions = do
hd <- getHomeDirectory
contents <- handle (\(_::SomeException) -> return "") $
readTextFile $ hd </> fromText ("." `T.append` name) </> "opts"
return $ T.splitOn " " $ T.strip contents
}