{-# LANGUAGE FlexibleContexts #-} module Options where import Data.Monoid import qualified Distribution.Package as C import Distribution.Text import qualified Distribution.Version as V import Options.Applicative.Types (readerAsk, fromM, manyM) import Options.Applicative.Builder import Options.Applicative.Common import qualified Text.ParserCombinators.Parsec as P import Db import Options.Db import qualified Data.List as L data Options = Options { outputDir :: FilePath, quiet :: Bool, cabalFile :: Maybe FilePath, cabalExclusions :: [String], sandbox :: Bool, nouser :: Bool, db :: Maybe FilePath, dbOrdering :: [Db], packages :: [C.Dependency] } deriving Show parser :: Parser Options parser = Options <$> (strOption $ long "output" <> short 'o' <> metavar "" <> value "./docsets" <> help "the directory to write created docsets to") <*> switch (long "quiet" <> short 'q' <> help "set to quiet output") <*> option (Just <$> readerAsk) (long "cabal" <> short 'c' <> metavar "" <> value Nothing <> help "the cabal file to retrieve package dependencies from") <*> option toPackageL (long "cabal-excludes" <> short 'x' <> value [] <> metavar "ghc,lens.." <> help "limit package results from a cabal file source") <*> switch (long "sandbox" <> short 's' <> help "use cabal sandbox") <*> switch (long "no-user" <> short 'n' <> help "don't source packages from user db") <*> option fp (long "db" <> metavar "" <> value Nothing <> help "package db directory") <*> option toOrdering (long "ordering" <> short 'd' <> value defaultOrdering <> metavar "user,sandbox.." <> help "ordering of user, dir, and sandbox db's") <*> (fromM . manyM $ ( argument dep (metavar "packages" <> help "a list of packages to specifically build, e.g. either-1.0.1 text"))) where fp :: ReadM (Maybe FilePath) fp = do str' <- str return $ if (L.null str') then Nothing else (Just str') versionless :: C.PackageIdentifier -> Bool versionless p = C.packageVersion p == V.Version [] [] dep :: ReadM C.Dependency dep = do pkg_str <- readerAsk case simpleParse pkg_str of Nothing -> readerError $ "failed parsing package: " Just pkg -> return $ if versionless pkg then C.Dependency (C.packageName pkg) V.anyVersion else C.thisPackageVersion pkg toPackageL :: ReadM [String] toPackageL = do expr <- readerAsk case P.parse parser' [] expr of Left err -> readerError . show $ err Right pkgs -> return pkgs where parser' :: P.Parser [String] parser' = P.sepBy (P.many1 (P.notFollowedBy (P.char ',') >> P.letter)) (P.char ',')