packages feed

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"