stack2nix-0.2: stack2nix/Main.hs
module Main ( main ) where
import Data.Semigroup ((<>))
import Data.Time (UTCTime, defaultTimeLocale,
parseTimeM)
import qualified Distribution.Compat.ReadP as P
import Distribution.System (Arch (..), OS (..), Platform (..),
buildPlatform)
import Distribution.Text (display)
import Options.Applicative
import Stack2nix
import System.IO (BufferMode (..), hSetBuffering,
stderr, stdout)
args :: Parser Args
args = Args
<$> optional (strOption $ long "revision" <> help "revision to use when fetching from VCS")
<*> optional (strOption $ short 'o' <> help "output file for generated nix expression" <> metavar "PATH")
<*> strOption (long "stack-yaml" <> help "Override project stack.yaml file" <> showDefault <> value "stack.yaml")
<*> option auto (short 'j' <> help "number of threads for subprocesses" <> showDefault <> value 4 <> metavar "INT")
<*> switch (long "test" <> help "enable tests")
<*> switch (long "bench" <> help "enable benchmarks")
<*> switch (long "haddock" <> help "enable documentation generation")
<*> optional (option utcTimeReader (long "hackage-snapshot" <> help "hackage snapshot time, ISO format"))
<*> option (readP platformReader) (long "platform" <> help "target platform to use when invoking stack or cabal2nix" <> value buildPlatform <> showDefaultWith display)
<*> strArgument (metavar "URI")
<*> flag True False (long "no-indent" <> help "disable indentation and place one item per line")
<*> switch (long "verbose" <> help "verbose output")
where
-- | A parser for the date. Hackage updates happen maybe once or twice a month.
-- Example: parseTime defaultTimeLocale "%FT%T%QZ" "2017-11-20T12:18:35Z" :: Maybe UTCTime
utcTimeReader :: ReadM UTCTime
utcTimeReader = eitherReader $ \arg ->
case parseTimeM True defaultTimeLocale "%FT%T%QZ" arg of
Nothing -> Left $ "Cannot parse date, ISO format used ('2017-11-20T12:18:35Z'): " ++ arg
Just utcTime -> Right utcTime
-- | A String parser for Distribution.System.Platform
-- | Copied from cabal2nix/src/Cabal2nix.hs
platformReader :: P.ReadP r Platform
platformReader = do
arch <- P.choice [P.string "i686" >> return I386, P.string "x86_64" >> return X86_64]
_ <- P.char '-'
os <- P.choice [P.string "linux" >> return Linux, P.string "darwin" >> return OSX]
return (Platform arch os)
readP :: P.ReadP a a -> ReadM a
readP p = eitherReader $ \s ->
case [ r' | (r',"") <- P.readP_to_S p s ] of
(r:_) -> Right r
_ -> Left ("invalid value " ++ show s)
main :: IO ()
main = do
hSetBuffering stdout LineBuffering
hSetBuffering stderr LineBuffering
stack2nix =<< execParser opts
where
opts = info
(helper
<*> infoOption ("stack2nix " ++ display version) (long "version" <> help "Show version number")
<*> args) $
fullDesc
<> progDesc "Generate a nix expression for a Haskell package using stack"