@@ -0,0 +1,75 @@
1+{-# LANGUAGE Rank2Types #-}
2+
3+module Main where
4+
5+import Control.Monad.IfElse
6+import Control.Monad.Reader
7+import Control.Monad.State hiding ( State )
8+import Distribution.Hackage.DB
9+import Options.Applicative
10+import System.IO
11+import Data.Monoid
12+import Data.Maybe
13+import Distribution.Compiler
14+import Distribution.Text
15+
16+data Options = Options
17+ { verbose :: Bool
18+ , overlay :: [FilePath]
19+ , compiler :: CompilerId
20+ }
21+ deriving (Show)
22+
23+data Config = Config
24+ { _verbose :: Bool
25+ , _hackage :: Hackage
26+ }
27+ deriving (Show)
28+
29+data State = State
30+ deriving (Show)
31+
32+type Compile a = MonadIO m => StateT State (ReaderT Config m) a
33+
34+yell :: String -> Compile ()
35+yell = liftIO . hPutStrLn stderr
36+
37+msgInfo, msgWarn :: String -> Compile ()
38+msgInfo = whenM (asks _verbose) . yell . showString "INFO: "
39+msgWarn = yell . showString "WARN: "
40+
41+runCompiler :: MonadIO m => Compile a -> Options -> m a
42+runCompiler f opts = do
43+ db <- liftIO readHackage
44+ let cfg = Config
45+ { _verbose = verbose opts
46+ , _hackage = db
47+ }
48+ st = State
49+ f' = msgInfo (showString "options = " (show opts)) >> f
50+ runReaderT (evalStateT f' st) cfg
51+
52+main :: IO ()
53+main = execParser mainOptions >>= runCompiler (msgInfo "starting up")
54+ where
55+ parseCompilerId :: Parser CompilerId
56+ parseCompilerId = nullOption
57+ ( long "compiler"
58+ <> eitherReader (\s -> maybe (Left (show s ++ " is no valid compiler id")) Right (simpleParse s))
59+ <> help "identifier of the compiler"
60+ <> metavar "COMPILER-ID"
61+ <> value (fromJust (simpleParse "ghc-7.8.2"))
62+ <> showDefaultWith display
63+ )
64+
65+ parseOptions :: Parser Options
66+ parseOptions = Options
67+ <$> switch (long "verbose" <> help "enable detailed progress diagnostics")
68+ <*> many (strOption (long "overlay" <> help "path(s) to local Hackage overlay" <> metavar "PATH"))
69+ <*> parseCompilerId
70+
71+ mainOptions :: ParserInfo Options
72+ mainOptions = info (helper <*> parseOptions)
73+ ( fullDesc
74+ <> header "hackage2nix -- convert the Hackage database into Nix build instructions"
75+ )