module HMGit.Commands.Porcelain.Commit.Cmd (
    commitCmd
) where

import           HMGit.Commands                       (Cmd (..))
import           HMGit.Commands.Porcelain.Commit.Core (Commit (..),
                                                       CommitCfg (..),
                                                       commitDefault)

import           Control.Exception.Safe               (MonadCatch)
import           Control.Monad.IO.Class               (MonadIO)
import           Data.Foldable                        (asum)
import qualified Options.Applicative                  as OA

commitMode :: (MonadIO m, MonadCatch m) => OA.Parser (Commit m)
commitMode :: Parser (Commit m)
commitMode = [Parser (Commit m)] -> Parser (Commit m)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [
    Commit m -> Parser (Commit m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Commit m
forall (m :: * -> *). (MonadIO m, MonadCatch m) => Commit m
commitDefault
  ]

optCommitMessage :: OA.Parser String
optCommitMessage :: Parser String
optCommitMessage = ReadM String -> Mod OptionFields String -> Parser String
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM String
forall s. IsString s => ReadM s
OA.str (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields String] -> Mod OptionFields String
forall a. Monoid a => [a] -> a
mconcat [
    String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"<msg>"
  , Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
OA.short Char
'm'
  , String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"message"
  , String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"Get the name, ignoring whether it is a real name or a candidate name"
  ]

optCommitAuthor :: OA.Parser String
optCommitAuthor :: Parser String
optCommitAuthor = ReadM String -> Mod OptionFields String -> Parser String
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM String
forall s. IsString s => ReadM s
OA.str (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields String] -> Mod OptionFields String
forall a. Monoid a => [a] -> a
mconcat [
    String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"<author>"
  , String -> Mod OptionFields String
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value String
forall a. Monoid a => a
mempty
  , String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"author"
  , String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
OA.help (String -> Mod OptionFields String)
-> String -> Mod OptionFields String
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [
        String
"Set the commit author."
      , String
"Specify an explicit author using"
      , String
"the standard A U Thor <author@example.com> format."
      , String
"If nothing is specified, HMGit looks for the"
      , String
"HMGIT_AUTHOR_NAME and HMGIT_AUTHOR_EMAIL environment variables."
      ]
  ]

-- | The commit command field
commitCmd :: (MonadIO m, MonadCatch m) => OA.Mod OA.CommandFields (Cmd m)
commitCmd :: Mod CommandFields (Cmd m)
commitCmd = String -> ParserInfo (Cmd m) -> Mod CommandFields (Cmd m)
forall a. String -> ParserInfo a -> Mod CommandFields a
OA.command String
"commit"
    (ParserInfo (Cmd m) -> Mod CommandFields (Cmd m))
-> ParserInfo (Cmd m) -> Mod CommandFields (Cmd m)
forall a b. (a -> b) -> a -> b
$ Parser (Cmd m) -> InfoMod (Cmd m) -> ParserInfo (Cmd m)
forall a. Parser a -> InfoMod a -> ParserInfo a
OA.info (Commit m -> CommitCfg -> Cmd m
forall (m :: * -> *). Commit m -> CommitCfg -> Cmd m
CmdCommit
        (Commit m -> CommitCfg -> Cmd m)
-> Parser (Commit m) -> Parser (CommitCfg -> Cmd m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser (Commit m -> Commit m)
forall a. Parser (a -> a)
OA.helper Parser (Commit m -> Commit m)
-> Parser (Commit m) -> Parser (Commit m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Commit m)
forall (m :: * -> *).
(MonadIO m, MonadCatch m) =>
Parser (Commit m)
commitMode)
        Parser (CommitCfg -> Cmd m) -> Parser CommitCfg -> Parser (Cmd m)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> String -> CommitCfg
CommitCfg
            (String -> String -> CommitCfg)
-> Parser String -> Parser (String -> CommitCfg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String
optCommitMessage
            Parser (String -> CommitCfg) -> Parser String -> Parser CommitCfg
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
optCommitAuthor))
    (InfoMod (Cmd m) -> ParserInfo (Cmd m))
-> InfoMod (Cmd m) -> ParserInfo (Cmd m)
forall a b. (a -> b) -> a -> b
$ String -> InfoMod (Cmd m)
forall a. String -> InfoMod a
OA.progDesc String
"Record changes to the repository"