{-# LANGUAGE NoImplicitPrelude #-}

-- | Functions to parse command line arguments for Stack's @upload@ command.

module Stack.Options.UploadParser
  ( uploadOptsParser
  ) where

import qualified Data.Text as T
import           Options.Applicative
                   ( Parser, completeWith, completer, flag, help, idm, long
                   , metavar, option, readerError, short, strArgument, strOption
                   , switch
                   )
import           Options.Applicative.Builder.Extra ( boolFlags, dirCompleter )
import           Options.Applicative.Types ( readerAsk )
import           Stack.Prelude
import           Stack.Upload ( UploadOpts (..), UploadVariant (..) )
import           Stack.Types.PvpBounds ( PvpBounds (..), parsePvpBounds )

-- | Parse command line arguments for Stack's @upload@ command.

uploadOptsParser :: Parser UploadOpts
uploadOptsParser :: Parser UploadOpts
uploadOptsParser = [String]
-> Bool
-> Maybe PvpBounds
-> Bool
-> Bool
-> Maybe String
-> UploadVariant
-> UploadOpts
UploadOpts
  ([String]
 -> Bool
 -> Maybe PvpBounds
 -> Bool
 -> Bool
 -> Maybe String
 -> UploadVariant
 -> UploadOpts)
-> Parser [String]
-> Parser
     (Bool
      -> Maybe PvpBounds
      -> Bool
      -> Bool
      -> Maybe String
      -> UploadVariant
      -> UploadOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [String]
itemsToWorkWithParser
  Parser
  (Bool
   -> Maybe PvpBounds
   -> Bool
   -> Bool
   -> Maybe String
   -> UploadVariant
   -> UploadOpts)
-> Parser Bool
-> Parser
     (Maybe PvpBounds
      -> Bool -> Bool -> Maybe String -> UploadVariant -> UploadOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Bool
documentationParser
  Parser
  (Maybe PvpBounds
   -> Bool -> Bool -> Maybe String -> UploadVariant -> UploadOpts)
-> Parser (Maybe PvpBounds)
-> Parser
     (Bool -> Bool -> Maybe String -> UploadVariant -> UploadOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser PvpBounds -> Parser (Maybe PvpBounds)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser PvpBounds
pvpBoundsOption
  Parser
  (Bool -> Bool -> Maybe String -> UploadVariant -> UploadOpts)
-> Parser Bool
-> Parser (Bool -> Maybe String -> UploadVariant -> UploadOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Bool
ignoreCheckSwitch
  Parser (Bool -> Maybe String -> UploadVariant -> UploadOpts)
-> Parser Bool
-> Parser (Maybe String -> UploadVariant -> UploadOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Bool
buildPackageOption
  Parser (Maybe String -> UploadVariant -> UploadOpts)
-> Parser (Maybe String) -> Parser (UploadVariant -> UploadOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe String)
tarDirParser
  Parser (UploadVariant -> UploadOpts)
-> Parser UploadVariant -> Parser UploadOpts
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser UploadVariant
uploadVariantParser
 where
  itemsToWorkWithParser :: Parser [String]
itemsToWorkWithParser = Parser String -> Parser [String]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Mod ArgumentFields String -> Parser String
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument
    (  String -> Mod ArgumentFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"ITEM"
    Mod ArgumentFields String
-> Mod ArgumentFields String -> Mod ArgumentFields String
forall a. Semigroup a => a -> a -> a
<> Completer -> Mod ArgumentFields String
forall (f :: * -> *) a. HasCompleter f => Completer -> Mod f a
completer Completer
dirCompleter
    Mod ArgumentFields String
-> Mod ArgumentFields String -> Mod ArgumentFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod ArgumentFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"A relative path to a package directory or, for package upload \
            \only, an sdist tarball."
    ))
  documentationParser :: Parser Bool
documentationParser = Bool -> Bool -> Mod FlagFields Bool -> Parser Bool
forall a. a -> a -> Mod FlagFields a -> Parser a
flag Bool
False Bool
True
    (  String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"documentation"
    Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> Char -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'd'
    Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields Bool
forall (f :: * -> *) a. String -> Mod f a
help String
"Upload documentation for packages (not packages)."
    )
  pvpBoundsOption :: Parser PvpBounds
  pvpBoundsOption :: Parser PvpBounds
pvpBoundsOption = ReadM PvpBounds -> Mod OptionFields PvpBounds -> Parser PvpBounds
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM PvpBounds
readPvpBounds
    (  String -> Mod OptionFields PvpBounds
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"pvp-bounds"
    Mod OptionFields PvpBounds
-> Mod OptionFields PvpBounds -> Mod OptionFields PvpBounds
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields PvpBounds
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PVP-BOUNDS"
    Mod OptionFields PvpBounds
-> Mod OptionFields PvpBounds -> Mod OptionFields PvpBounds
forall a. Semigroup a => a -> a -> a
<> [String] -> Mod OptionFields PvpBounds
forall (f :: * -> *) a. HasCompleter f => [String] -> Mod f a
completeWith [String
"none", String
"lower", String
"upper", String
"both"]
    Mod OptionFields PvpBounds
-> Mod OptionFields PvpBounds -> Mod OptionFields PvpBounds
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields PvpBounds
forall (f :: * -> *) a. String -> Mod f a
help String
"For package upload, how PVP version bounds should be added to \
            \Cabal file: none, lower, upper, both."
    )
   where
    readPvpBounds :: ReadM PvpBounds
readPvpBounds = do
      String
s <- ReadM String
readerAsk
      case Text -> Either String PvpBounds
parsePvpBounds (Text -> Either String PvpBounds)
-> Text -> Either String PvpBounds
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
s of
        Left String
e -> String -> ReadM PvpBounds
forall a. String -> ReadM a
readerError String
e
        Right PvpBounds
v -> PvpBounds -> ReadM PvpBounds
forall a. a -> ReadM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PvpBounds
v
  ignoreCheckSwitch :: Parser Bool
ignoreCheckSwitch = Mod FlagFields Bool -> Parser Bool
switch
      (  String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"ignore-check"
      Mod FlagFields Bool -> Mod FlagFields Bool -> Mod FlagFields Bool
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields Bool
forall (f :: * -> *) a. String -> Mod f a
help String
"For package upload, do not check packages for common mistakes."
      )
  buildPackageOption :: Parser Bool
buildPackageOption = Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool
boolFlags Bool
False
      String
"test-tarball"
      String
"building of the resulting sdist tarball(s), for package upload."
      Mod FlagFields Bool
forall m. Monoid m => m
idm
  tarDirParser :: Parser (Maybe String)
tarDirParser = Parser String -> Parser (Maybe String)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
    (  String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"tar-dir"
    Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"For package upload, if specified, copy all the tar to this \
            \directory."
    ))
  uploadVariantParser :: Parser UploadVariant
uploadVariantParser = UploadVariant
-> UploadVariant
-> Mod FlagFields UploadVariant
-> Parser UploadVariant
forall a. a -> a -> Mod FlagFields a -> Parser a
flag UploadVariant
Publishing UploadVariant
Candidate
    (  String -> Mod FlagFields UploadVariant
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"candidate"
    Mod FlagFields UploadVariant
-> Mod FlagFields UploadVariant -> Mod FlagFields UploadVariant
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields UploadVariant
forall (f :: * -> *) a. String -> Mod f a
help String
"Upload as, or for, a package candidate."
    )