{-# LANGUAGE NoImplicitPrelude #-}

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

module Stack.Options.UpgradeParser
  ( upgradeOptsParser
  ) where

import         Options.Applicative
                 ( Parser, flag', help, idm, long, metavar, showDefault
                 , strOption, switch, value
                 )
import         Options.Applicative.Builder.Extra ( boolFlags )
import         Stack.Prelude
import         Stack.Upgrade
                 ( BinaryOpts (..), SourceOpts (..), UpgradeOpts (..) )

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

upgradeOptsParser ::
     Bool
     -- ^ The default for --[no]-only-local-bin

  -> Parser UpgradeOpts
upgradeOptsParser :: Bool -> Parser UpgradeOpts
upgradeOptsParser Bool
onlyLocalBin = Maybe BinaryOpts -> Maybe SourceOpts -> UpgradeOpts
UpgradeOpts
  (Maybe BinaryOpts -> Maybe SourceOpts -> UpgradeOpts)
-> Parser (Maybe BinaryOpts)
-> Parser (Maybe SourceOpts -> UpgradeOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser (Maybe BinaryOpts)
forall {a}. Parser (Maybe a)
sourceOnly Parser (Maybe BinaryOpts)
-> Parser (Maybe BinaryOpts) -> Parser (Maybe BinaryOpts)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser BinaryOpts -> Parser (Maybe BinaryOpts)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser BinaryOpts
binaryOpts)
  Parser (Maybe SourceOpts -> UpgradeOpts)
-> Parser (Maybe SourceOpts) -> Parser UpgradeOpts
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 SourceOpts)
forall {a}. Parser (Maybe a)
binaryOnly Parser (Maybe SourceOpts)
-> Parser (Maybe SourceOpts) -> Parser (Maybe SourceOpts)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser SourceOpts -> Parser (Maybe SourceOpts)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser SourceOpts
sourceOpts)
 where
  binaryOnly :: Parser (Maybe a)
binaryOnly = Maybe a -> Mod FlagFields (Maybe a) -> Parser (Maybe a)
forall a. a -> Mod FlagFields a -> Parser a
flag' Maybe a
forall a. Maybe a
Nothing
    (  String -> Mod FlagFields (Maybe a)
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"binary-only"
    Mod FlagFields (Maybe a)
-> Mod FlagFields (Maybe a) -> Mod FlagFields (Maybe a)
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields (Maybe a)
forall (f :: * -> *) a. String -> Mod f a
help String
"Do not use a source upgrade path."
    )
  sourceOnly :: Parser (Maybe a)
sourceOnly = Maybe a -> Mod FlagFields (Maybe a) -> Parser (Maybe a)
forall a. a -> Mod FlagFields a -> Parser a
flag' Maybe a
forall a. Maybe a
Nothing
    (  String -> Mod FlagFields (Maybe a)
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"source-only"
    Mod FlagFields (Maybe a)
-> Mod FlagFields (Maybe a) -> Mod FlagFields (Maybe a)
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields (Maybe a)
forall (f :: * -> *) a. String -> Mod f a
help String
"Do not use a binary upgrade path."
    )

  binaryOpts :: Parser BinaryOpts
binaryOpts = Maybe String
-> Bool
-> Bool
-> Maybe String
-> Maybe String
-> Maybe String
-> BinaryOpts
BinaryOpts
    (Maybe String
 -> Bool
 -> Bool
 -> Maybe String
 -> Maybe String
 -> Maybe String
 -> BinaryOpts)
-> Parser (Maybe String)
-> Parser
     (Bool
      -> Bool
      -> Maybe String
      -> Maybe String
      -> Maybe String
      -> BinaryOpts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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
"binary-platform"
          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
"Platform type for archive to download."
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PLATFORM"
          ))
    Parser
  (Bool
   -> Bool
   -> Maybe String
   -> Maybe String
   -> Maybe String
   -> BinaryOpts)
-> Parser Bool
-> Parser
     (Bool
      -> Maybe String -> Maybe String -> Maybe String -> BinaryOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod FlagFields Bool -> Parser Bool
switch
          (  String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"force-download"
          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
"Download the latest available Stack executable, even if not \
                  \newer."
          )
    Parser
  (Bool
   -> Maybe String -> Maybe String -> Maybe String -> BinaryOpts)
-> Parser Bool
-> Parser
     (Maybe String -> Maybe String -> Maybe String -> BinaryOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Bool -> String -> String -> Mod FlagFields Bool -> Parser Bool
boolFlags Bool
onlyLocalBin
          String
"only-local-bin"
          String
"downloading only to Stack's local binary directory"
          Mod FlagFields Bool
forall m. Monoid m => m
idm
    Parser (Maybe String -> Maybe String -> Maybe String -> BinaryOpts)
-> Parser (Maybe String)
-> Parser (Maybe String -> Maybe String -> BinaryOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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
"binary-version"
          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
"Download a specific Stack version, even if already \
                  \installed."
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"VERSION"
          ))
    Parser (Maybe String -> Maybe String -> BinaryOpts)
-> Parser (Maybe String) -> Parser (Maybe String -> BinaryOpts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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
"github-org"
          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
"GitHub organization name."
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"USER"
          ))
    Parser (Maybe String -> BinaryOpts)
-> Parser (Maybe String) -> Parser BinaryOpts
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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
"github-repo"
          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
"GitHub repository name."
          Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"REPO"
          ))

  sourceOpts :: Parser SourceOpts
sourceOpts = Maybe (String, String) -> SourceOpts
SourceOpts
    (Maybe (String, String) -> SourceOpts)
-> Parser (Maybe (String, String)) -> Parser SourceOpts
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (   ( \Bool
fromGit String
repo String
branch ->
                if Bool
fromGit
                  then (String, String) -> Maybe (String, String)
forall a. a -> Maybe a
Just (String
repo, String
branch)
                  else Maybe (String, String)
forall a. Maybe a
Nothing
            )
        (Bool -> String -> String -> Maybe (String, String))
-> Parser Bool
-> Parser (String -> String -> Maybe (String, String))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod FlagFields Bool -> Parser Bool
switch
              ( String -> Mod FlagFields Bool
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"git"
              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
"Clone from Git instead of downloading from Hackage \
                      \(more dangerous)."
              )
        Parser (String -> String -> Maybe (String, String))
-> Parser String -> Parser (String -> Maybe (String, String))
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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
"git-repo"
              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
"Clone from specified Git repository."
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"URL"
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value String
"https://github.com/commercialhaskell/stack"
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields String
forall a (f :: * -> *). Show a => Mod f a
showDefault
              )
        Parser (String -> Maybe (String, String))
-> Parser String -> Parser (Maybe (String, String))
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> 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
"git-branch"
              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
"Clone from specified Git branch."
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"BRANCH"
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value String
"master"
              Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields String
forall a (f :: * -> *). Show a => Mod f a
showDefault
              )
        )