{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, TemplateHaskell, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, GeneralizedNewtypeDeriving, FunctionalDependencies #-} module Main where import qualified Control.Monad.Catch as E import qualified Data.Text as T import qualified Data.Text.Encoding as TE import Control.Monad.Reader import qualified Control.Monad.Log as Log import Control.Lens import qualified Network.Wai.Handler.Warp as Warp import Data.Semigroup ((<>)) import Options.Applicative import Options.Applicative.Text import Options.Applicative.Helper import qualified Distribution.Skete.Storage.Interface as Storage import qualified Distribution.Skete.Storage.GitFat as GitFat import Distribution.Skete.Haskell.Package import SketeUpdate data CommandOptions = COImport { _coUpdateConf :: UpdateConfig , _coRepo :: T.Text } | COServe { _coPort :: Warp.Port , _coRepo :: T.Text } -- | CODocs { -- _coPackageVersion :: Storage.PackageVersion -- , _coPackageSet :: Storage.PackageSet -- , _coRepo :: T.Text -- } deriving (Read, Show, Eq, Ord) makeClassy ''CommandOptions commandParser :: Parser CommandOptions commandParser = subconcat [ parseImport , parseServe -- , parseDocs ] where parsePackageSet = textOption $ long "set" <> metavar "PACKAGESET" <> showDefault <> help "The PackageSet to import the new PackageVersions into." <> value "all" parseRepo = textOption $ long "repo" <> metavar "GITDIR" <> help "The location of the skete store." <> value "./.git" parseImport = command "import" $ infoHelper `flip` (fpDesc "import") $ COImport <$> (UpdateConfig <$> textOption ( long "upstream" <> metavar "HACKAGE" <> showDefault <> help "A schema+host for a Hackage-like service to import PackageVersions from." <> value "https://hackage.haskell.org" ) <*> parsePackageSet <*> ((Just <$> strOption ( long "cache" <> metavar "CACHEDIR" <> help "A location to find predownloaded tarballs and save tarballs as they're downloaded." )) <|> (pure Nothing))) <*> parseRepo parseServe = command "serve" $ infoHelper `flip` (fpDesc "import") $ COServe <$> option auto ( long "port" <> metavar "PORT" <> showDefault <> help "Which port to provide a subset of the Hackage API on." <> value 8081 ) <*> parseRepo -- parseDocs = Prelude.error "doc parser not completed" data CommandConfig = CCImport { _ccUpConf :: UpdateConfig } -- | CCServe { -- _ccPort :: Warp.Port -- } deriving (Show, Eq, Ord) makeClassy ''CommandConfig instance HasUpdateConfig CommandConfig where updateConfig = ccUpConf data WrappedConfig c = WrappedConfig { _wcLoggerConf :: Log.Logger () , _wcComConf :: c } makeClassy ''WrappedConfig instance HasUpdateConfig (WrappedConfig UpdateConfig) where updateConfig = wcComConf newtype SketeToolT c m a = SketeToolT { runSketeToolT :: ReaderT (WrappedConfig c) m a } deriving ( Functor, Applicative, Monad, MonadIO, E.MonadThrow, E.MonadCatch , MonadTrans, MonadReader (WrappedConfig c) ) instance MonadIO m => Log.MonadLog () (SketeToolT c m) where askLogger = view wcLoggerConf localLogger f m = local (over wcLoggerConf f) m main :: IO () main = do logConf <- Log.makeDefaultLogger Log.simpleTimeFormat (Log.LogStderr 0) (Log.Level 0) () --Log.runLogTSafe logConf . Log.debug . mconcat $ ["Logger created"] cmd <- helperExecParser commandParser (fpDesc "skete-haskell, the skete Haskell package manager.") (Storage.storage (GitFat.GFC . TE.encodeUtf8 $ (cmd ^. coRepo))::GitFat.GitFat p a -> IO a) $ do case cmd of COImport {_coUpdateConf=upConf} -> (runReaderT `flip` (WrappedConfig logConf upConf)) . runSketeToolT $ do fullUpdate _ -> liftIO . print $ cmd {- view timeBetweenUpdates >>= delay hackageNewEvents -}