|
@@ -0,0 +1,76 @@
|
|
|
+{-# LANGUAGE OverloadedStrings #-}
|
|
|
+{-# LANGUAGE RecordWildCards #-}
|
|
|
+
|
|
|
+module Config
|
|
|
+( ConfigFile
|
|
|
+, fetchConfig
|
|
|
+, Ini.iniValueL
|
|
|
+) where
|
|
|
+
|
|
|
+import Control.Monad (forM)
|
|
|
+import Data.Ini.Config.Bidir ((.=), (.=?), (&))
|
|
|
+import qualified Data.Ini.Config.Bidir as Ini
|
|
|
+import qualified Data.Text as T
|
|
|
+import qualified Data.Text.IO as T
|
|
|
+import Data.Monoid ((<>))
|
|
|
+import qualified System.Directory as Sys
|
|
|
+import System.FilePath ((</>))
|
|
|
+import qualified System.Exit as Sys
|
|
|
+import qualified System.Environment.XDG.BaseDir as Sys
|
|
|
+import Text.Read (readMaybe)
|
|
|
+
|
|
|
+import Types
|
|
|
+
|
|
|
+type ConfigFile = Ini.Ini Config
|
|
|
+
|
|
|
+defaultConfig :: IO Config
|
|
|
+defaultConfig = do
|
|
|
+ _configInstallPath <- Sys.getUserDataDir ("hatch" </> "install")
|
|
|
+ let _configCurrentCompiler = Nothing
|
|
|
+ return Config { .. }
|
|
|
+
|
|
|
+configSpec :: Ini.IniSpec Config ()
|
|
|
+configSpec = do
|
|
|
+ Ini.section "hatch" $ do
|
|
|
+ configInstallPath .= Ini.field "path" Ini.string
|
|
|
+ & Ini.optional
|
|
|
+ configCurrentCompiler .=? Ini.field "current" versionField
|
|
|
+
|
|
|
+versionField :: Ini.FieldValue Compiler
|
|
|
+versionField = Ini.FieldValue { .. }
|
|
|
+ where
|
|
|
+ fvParse t
|
|
|
+ | Just ver <- T.stripPrefix "ghc-" t
|
|
|
+ , [x,y,z] <- T.splitOn "." ver
|
|
|
+ , Just x' <- readMaybe (T.unpack x)
|
|
|
+ , Just y' <- readMaybe (T.unpack y)
|
|
|
+ , Just z' <- readMaybe (T.unpack z)
|
|
|
+ = Right (Compiler (x', y', z'))
|
|
|
+ | otherwise = Left ("Bad GHC version: " ++ show t)
|
|
|
+ fvEmit = T.pack . compilerString
|
|
|
+
|
|
|
+locateConfig :: FilePath -> IO (Maybe FilePath)
|
|
|
+locateConfig filename = do
|
|
|
+ xdgLocs <- Sys.getAllConfigFiles "hatch" filename
|
|
|
+ let confLocations = ["./" <> filename] ++
|
|
|
+ xdgLocs ++
|
|
|
+ ["/etc/hatch/" <> filename]
|
|
|
+ results <- forM confLocations (\fp -> (,) fp <$> Sys.doesFileExist fp)
|
|
|
+ case filter snd results of
|
|
|
+ [] -> return Nothing
|
|
|
+ ((fp, _):_) -> return (Just fp)
|
|
|
+
|
|
|
+fetchConfig :: IO (Ini.Ini Config)
|
|
|
+fetchConfig = do
|
|
|
+ def <- defaultConfig
|
|
|
+ let ini = Ini.ini def configSpec
|
|
|
+ confLocation <- locateConfig "config.ini"
|
|
|
+ print confLocation
|
|
|
+ case confLocation of
|
|
|
+ Nothing -> return ini
|
|
|
+ Just fp -> do
|
|
|
+ content <- T.readFile fp
|
|
|
+ case Ini.parseIni content ini of
|
|
|
+ Left err -> do
|
|
|
+ Sys.die err
|
|
|
+ Right x -> return x
|