gitrev-typed
Copyright(c) 2025 Thomas Bidne
LicenseBSD3
Maintainertbidne@protonmail.com
Safe HaskellNone
LanguageHaskell2010

Development.GitRev.Typed

Description

Typed version of Development.GitRev.

Since: 0.1

Synopsis

Basic functions

These functions are simple, merely a typed version of Development.GitRev's API.

NOTE: These functions do not error if git fails to run, opting instead to return some default value (e.g. string UNKNOWN, boolean False).

gitBranch :: Code Q String Source #

Return the branch (or tag) name of the current git commit, or UNKNOWN if not in a git repository. For detached heads, this will just be HEAD.

Examples

Expand
λ. $$gitBranch
"main"

Since: 0.1

gitCommitCount :: Code Q String Source #

Return the number of commits in the current head.

Examples

Expand
λ. $$gitCommitCount
"47"

Since: 0.1

gitCommitDate :: Code Q String Source #

Return the commit date of the current head.

Examples

Expand
λ. $$gitCommitDate
"Mon Apr 14 22:14:44 2025 +1200"

Since: 0.1

gitDescribe :: Code Q String Source #

Return the long git description for the current git commit, or UNKNOWN if not in a git repository.

Examples

Expand
λ. $$gitDescribe
"1.2.0-14-g40b5d7b"

Since: 0.1

gitDiff :: Code Q String Source #

Return the diff of the working copy with HEAD.

Examples

Expand
λ. $$gitDiff
"diff ..."

Since: 0.1

gitDirty :: Code Q Bool Source #

Return True if there are non-committed files present in the repository.

Examples

Expand
λ. $$gitDirty
False

Since: 0.1

gitDirtyTracked :: Code Q Bool Source #

Return True if there are non-commited changes to tracked files present in the repository.

Examples

Expand
λ. $$gitDirtyTracked
False

Since: 0.1

gitHash :: Code Q String Source #

Return the hash of the current git commit, or UNKNOWN if not in a git repository.

Examples

Expand
λ. $$gitHash
"e67e943dd03744d3f93c21f84e127744e6a04543"

Since: 0.1

gitShortHash :: Code Q String Source #

Return the short hash of the current git commit, or UNKNOWN if not in a git repository.

Examples

Expand
λ. $$gitShortHash
"e67e943"

Since: 0.1

gitTree :: Code Q String Source #

Return the hash of the current tree.

Examples

Expand
λ. $$gitTree
"b718a493773568bbf920a4710b5b83bd1762dbb9"

Since: 0.1

Custom behavior

These functions allow defining custom behavior. For instance, using the primitive gitHashQ and combinator projectError, we can define a variant of gitHash that instead fails to compile if there are any problems with git:

-- simplified type signatures
qToCode      :: Q a -> Code Q a
projectError :: Q (Either e a) -> Q a
gitHashQ     :: Q (Either GitError String)
>>> :{
  let gitHashOrDie :: Code Q String
      gitHashOrDie = qToCode $ projectError gitHashQ
:}

We can also define a function that falls back to an environment variable, in case the git command fails. firstSuccessQ takes the first action that returns Right.

firstSuccessQ :: NonEmpty (Q (Either e a)) -> Q (Either (Errors e) a)

-- unifying errors
embedGitError :: Q (Either GitError a) -> Q (Either GitRevError a)
embedEnvError :: Q (Either EnvError a) -> Q (Either GitRevError a)

-- look up environment variable
envValQ :: String -> Q (Either EnvError String)
>>> :{
  let gitHashEnv :: String -> Code Q (Either (Errors GitRevError) String)
      gitHashEnv var =
        qToCode $
          firstSuccessQ
            -- using -XOverloadedLists to make this a little nicer
            -- syntactically.
            [ embedGitError gitHashQ,
              embedEnvError $ envValQ var
            ]
:}

Naturally, these can be combined:

>>> :{
  let gitHashEnvOrDie :: String -> Code Q String
      gitHashEnvOrDie var =
        qToCode
          . projectError
          $ firstSuccessQ
            [ embedGitError gitHashQ,
              embedEnvError $ envValQ var
            ]
:}

"Out-of-tree" builds

Custom definitions are particularly useful for "out-of-tree" builds, where the build takes place outside of the normal git tree.

These builds present a problem, as we normally rely on building in the project directory where the .git directory is easy to locate. For example, while gitHash will work for 'cabal build', it will not work for 'nix build' or 'cabal install'. Fortunately, there are workarounds, both relying on passing the right data via environment variables.

  1. Passing the git directory.

    For situations where we can pass the current directory during installation e.g.

    $ export EXAMPLE_HOME=$(pwd); cabal install example

    We can use

    runGitInEnvDirQ :: String -> Q (Either GitError a) -> Q (Either GitRevError a)
    

    to define

    >>> :{
      let gitHashSrcDir :: Code Q String
          gitHashSrcDir =
            qToCode
            . projectStringUnknown
            $ firstSuccessQ
              [ -- 1. We first try normal gitHashQ.
                embedGitError gitHashQ,
                -- 2. If that fails, we try again in the directory pointed
                --    to by "EXAMPLE_HOME".
                runGitInEnvDirQ "EXAMPLE_HOME" gitHashQ
              ]
    :}
    

    If the initial call to gitHashQ fails, then we will try again, running the command from the directory pointed to by EXAMPLE_HOME.

  2. Passing the value itself.

    This approach can work well with nix, as nix flakes provides a variety of revisions via its self interface. For example:

      # Injecting the git hash via EXAMPLE_HASH where drv is the normal
      # derivation.
      drv.overrideAttrs (oldAttrs: {
        # Also: self.shortRev, self.dirtyShortRev
        EXAMPLE_HASH = "${self.rev or self.dirtyRev}";
      });
    

    Then we can define

    >>> :{
      let gitHashVal :: Code Q String
          gitHashVal =
            qToCode
            . projectStringUnknown
            $ firstSuccessQ
              [ -- 1. We first try normal gitHashQ.
                embedGitError gitHashQ,
                -- 2. If that fails, get the value directly from
                --    "EXAMPLE_HASH".
                embedEnvError $ envValQ "EXAMPLE_HASH"
              ]
    :}
    

    Once again, if the first attempt fails, we will run the second action, looking for the value of EXAMPLE_HASH.

Finally, we can compose these together to make a function that works for all three cases:

>>> :{
  let gitHashValSrc :: Code Q String
      gitHashValSrc =
        qToCode
          . projectStringUnknown
          $ firstSuccessQ
            [ embedGitError gitHashQ,
              runGitInEnvDirQ "EXAMPLE_HOME" gitHashQ,
              embedEnvError $ envValQ "EXAMPLE_HASH"
            ]
:}

Multiple queries

Using the typed interfaced, it is easy to combine multiple queries in a safe way.

>>> :{
  import Control.Applicative (liftA3)
  -- | Returns (date, hash, short hash)
  gitComplexData :: Code Q (String, String, String)
  gitComplexData = toCode qs
    where
      toCode = qToCode . projectError
      qs =
        firstSuccessQ
          [ embedGitError gitComplexDataFromGitQ,
            runGitInEnvDirQ "EXAMPLE_HOME" gitComplexDataFromGitQ
          ]
  gitComplexDataFromGitQ :: Q (Either GitError (String, String, String))
  gitComplexDataFromGitQ = do
    -- custom command for commit YYYY-MM-DD
    d <- runGitQ ["log", "HEAD", "-1", "--format=%cs"] IdxNotUsed
    h <- gitHashQ
    sh <- gitShortHashQ
    pure $ liftA3 (,,) d h sh
:}

Git Primitives

gitBranchQ :: Q (Either GitError String) Source #

Returns the current git branch.

Examples

Expand
>>> $$(qToCode gitBranchQ)
Right ...

Since: 0.1

gitCommitCountQ :: Q (Either GitError String) Source #

Returns the git commit count.

Examples

Expand
>>> $$(qToCode gitCommitCountQ)
Right ...

Since: 0.1

gitCommitDateQ :: Q (Either GitError String) Source #

Returns the latest git commit date.

Examples

Expand
>>> $$(qToCode gitCommitDateQ)
Right ...

Since: 0.1

gitDescribeQ :: Q (Either GitError String) Source #

Returns the git description.

Examples

Expand
>>> $$(qToCode gitDescribeQ)
Right ...

Since: 0.1

gitDiffQ :: Q (Either GitError String) Source #

Return the diff of the working copy with HEAD.

Examples

Expand
>>> $$(qToCode gitDiffQ)
Right ...

Since: 0.1

gitDirtyQ :: Q (Either GitError Bool) Source #

Returns the git dirty status.

Examples

Expand
>>> $$(qToCode gitDirtyQ)
Right ...

Since: 0.1

gitDirtyTrackedQ :: Q (Either GitError Bool) Source #

Returns the git dirty status, ignoring untracked files.

Examples

Expand
>>> $$(qToCode gitDirtyTrackedQ)
Right ...

Since: 0.1

gitHashQ :: Q (Either GitError String) Source #

Returns the latest git hash.

Examples

Expand
>>> $$(qToCode gitHashQ)
Right ...

Since: 0.1

gitShortHashQ :: Q (Either GitError String) Source #

Returns the latest git short hash.

Examples

Expand
>>> $$(qToCode gitShortHashQ)
Right ...

Since: 0.1

gitTreeQ :: Q (Either GitError String) Source #

Returns the hash of the current tree.

Examples

Expand
>>> $$(qToCode gitTreeQ)
Right ...

Since: 0.1

Running your own git actions

runGitQ Source #

Arguments

:: [String]

Arguments to git.

-> IndexUsed

Whether the index is used.

-> Q (Either GitError String) 

Runs git with the arguments. If IdxUsed is passed, it is tracked for recompliation purposes.

Examples

Expand
>>> :{
  -- Returns 'YYYY-MM-DD' rather than e.g. gitCommitDateQ's
  -- 'Fri May 2 13:29:59 2025 +1200'.
  gitCommitDateShortQ :: Q (Either GitError String)
  gitCommitDateShortQ = runGitQ ["log", "HEAD", "-1", "--format=%cs"] IdxNotUsed
:}

Since: 0.1

runGitPostProcessQ Source #

Arguments

:: (String -> String)

Function to run on the result.

-> [String]

Arguments to git.

-> IndexUsed

Whether the index is used.

-> Q (Either GitError String) 

Like runGitQ, except it applies the given function to the result. Normal runGitQ takes everything up until the first new line or carriage return.

Examples

Expand
>>> :{
  runGitNoProcessQ :: [String] -> IndexUsed -> Q (Either GitError String)
  runGitNoProcessQ = runGitPostProcessQ id
:}

Since: 0.1

data IndexUsed Source #

Type to flag if the git index is used or not in a call to runGitQ.

Since: 0.1

Constructors

IdxUsed

The git index is used.

Since: 0.1

IdxNotUsed

The git index is not used.

Since: 0.1

Instances

Instances details
Show IndexUsed Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git.Common

Eq IndexUsed Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git.Common

Environment lookup

This section allows looking up data via environment variables.

Warning: caching

Suppose we install an executable example-exe, that depends on example-lib, where the latter contains a TH splice for env var FOO. We first install via:

export FOO=A; cabal install example-exe --installdir=build --overwrite-policy=always

This will build example-lib with A in the splice.

Now suppose we run cabal clean (or delete the build directory e.g. dist-newstyle) and run:

export FOO=B; cabal install example-exe --installdir=build --overwrite-policy=always

What will the result of the splice be? Probably still A! The problem is that cabal does not know that the environment has changed, hence it detects no changes, and example-lib is not re-installed.

The solution is to manually delete the library example-lib, which probably exists in the state directory e.g. ~/.local/state/cabal/store/ghc-9.8.4-inplace.

envValQ Source #

Arguments

:: String

The environment variable k.

-> Q (Either EnvError String)

The result v or an error.

Performs an environment variable lookup in Q.

Examples

Expand
>>> setEnv "SOME_VAR" "val"
>>> $$(qToCode $ envValQ "SOME_VAR")
Right "val"

Since: 0.1

runInEnvDirQ Source #

Arguments

:: String

The environment variable k that should point to some directory d.

-> Q a

The Q action q.

-> Q (Either EnvError a)

The result of running q in directory d.

Runs the given Q-action under the directory d pointed to by the given environment variable.

Examples

Expand
>>> import System.Directory (listDirectory)
>>> setEnv "SOME_DIR" "./src"
>>> $$(qToCode $ runInEnvDirQ "SOME_DIR" $ runIO (listDirectory "./"))
Right ["Development"]

Since: 0.1

runGitInEnvDirQ Source #

Arguments

:: String

Environment variable pointing to a directory path, in which we run the git process.

-> Q (Either GitError a)

Git process to run.

-> Q (Either GitRevError a)

The result.

Runs the git action under the directory d pointed to by the given environment variable.

Examples

Expand
>>> setEnv "SOME_DIR" "./"
>>> $$(qToCode $ runGitInEnvDirQ "SOME_DIR" gitHashQ)
Right ...

Since: 0.1

withEnvValQ Source #

Arguments

:: String

The environment variable k to lookup.

-> (String -> Q a)

Function to run on k's value if k exists.

-> Q (Either EnvError a) 

Runs a Q-action on the result of an environment variable, if it exists.

Examples

Expand
>>> import System.Directory (listDirectory)
>>> setEnv "SOME_DIR" "./src"
>>> $$(qToCode $ withEnvValQ "SOME_DIR" (runIO . listDirectory))
Right ["Development"]

Since: 0.1

Q to Code

qToCode :: Lift a => Q a -> Code Q a Source #

Lifts a Q computation to Code, for usage with typed TH.

Since: 0.1

Q Combinators

Laziness

As alluded to above, Q's default semigroup instance is not lazy enough:

>>> :{
  $$( qToCode $
      (runIO (putStrLn "in q1") $> (Right "q1") :: Q (Either () String))
        <> (runIO (putStrLn "in q2") $> Left ())
    )
:}
in q1
in q2
Right "q1"

For this reason, we introduce QFirst:

mkQFirst :: Q (Either e a) -> QFirst e a
unQFirst :: QFirst e a -> Q (Either (Errors e) a)
>>> :{
  $$( qToCode $ unQFirst $
      (mkQFirst $ runIO (putStrLn "in q1") $> (Right "q1") :: QFirst () String)
        <> (mkQFirst $ runIO (putStrLn "in q2") $> Left ())
    )
:}
in q1
Right "q1"

The function

  firstSuccessQ :: NonEmpty (Q (Either e a)) -> Q (Either (Errors e) a)

utilizes QFirst for sequencing a series of Q actions, stopping after the first success.

data QFirst e a Source #

Wrapper for Q over Either with a lazier Semigroup. With this, we can run:

  mkQFirst q1 <> mkQFirst q2

This will only execute q2 if q1 returns Left, unlike Q's normal Semigroup instance.

If both actions fail, then both errors will be returned via Errors.

Warning: exceptions

In order for QFirst to work as expected, the underlying Q action should not throw exceptions. Uncaught exceptions will not be caught by QFirst, hence the intended "try multiple Q-actions until we have a success" pattern will not work.

Since: 0.1

Instances

Instances details
Bifunctor QFirst Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

bimap :: (a -> b) -> (c -> d) -> QFirst a c -> QFirst b d #

first :: (a -> b) -> QFirst a c -> QFirst b c #

second :: (b -> c) -> QFirst a b -> QFirst a c #

HasField "unQFirst" (QFirst e a) (Q (Either (Errors e) a)) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

getField :: QFirst e a -> Q (Either (Errors e) a) #

e ~ SomeException => MonadIO (QFirst e) Source #

Catches synchronous exceptions.

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

liftIO :: IO a -> QFirst e a #

Applicative (QFirst e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

pure :: a -> QFirst e a #

(<*>) :: QFirst e (a -> b) -> QFirst e a -> QFirst e b #

liftA2 :: (a -> b -> c) -> QFirst e a -> QFirst e b -> QFirst e c #

(*>) :: QFirst e a -> QFirst e b -> QFirst e b #

(<*) :: QFirst e a -> QFirst e b -> QFirst e a #

Functor (QFirst e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

fmap :: (a -> b) -> QFirst e a -> QFirst e b #

(<$) :: a -> QFirst e b -> QFirst e a #

Monad (QFirst e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

(>>=) :: QFirst e a -> (a -> QFirst e b) -> QFirst e b #

(>>) :: QFirst e a -> QFirst e b -> QFirst e b #

return :: a -> QFirst e a #

Semigroup (QFirst e a) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

(<>) :: QFirst e a -> QFirst e a -> QFirst e a #

sconcat :: NonEmpty (QFirst e a) -> QFirst e a #

stimes :: Integral b => b -> QFirst e a -> QFirst e a #

mkQFirst :: Q (Either e a) -> QFirst e a Source #

Wraps a Q computation in QFirst.

Since: 0.1

unQFirst :: QFirst e a -> Q (Either (Errors e) a) Source #

Unwraps QFirst.

Since: 0.1

firstSuccessQ :: NonEmpty (Q (Either e a)) -> Q (Either (Errors e) a) Source #

firstSuccessQ qs takes the first qi in qs that returns Right, without executing any qj for j > i. If there are no Rights, returns all errors.

Examples

Expand
>>> :{
   $$( qToCode $
         firstSuccessQ $
           (pure $ Left $ MkGitError "not found")
             :| [ gitHashQ,
                  error "oh no"
                ]
     )
:}
Right ...

Since: 0.1

data Errors e Source #

Collects multiple errors. Intended for displaying multiple exceptions via displayException.

Since: 0.1

Instances

Instances details
Applicative Errors Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

pure :: a -> Errors a #

(<*>) :: Errors (a -> b) -> Errors a -> Errors b #

liftA2 :: (a -> b -> c) -> Errors a -> Errors b -> Errors c #

(*>) :: Errors a -> Errors b -> Errors b #

(<*) :: Errors a -> Errors b -> Errors a #

Functor Errors Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

fmap :: (a -> b) -> Errors a -> Errors b #

(<$) :: a -> Errors b -> Errors a #

Monad Errors Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

(>>=) :: Errors a -> (a -> Errors b) -> Errors b #

(>>) :: Errors a -> Errors b -> Errors b #

return :: a -> Errors a #

Foldable Errors Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

fold :: Monoid m => Errors m -> m #

foldMap :: Monoid m => (a -> m) -> Errors a -> m #

foldMap' :: Monoid m => (a -> m) -> Errors a -> m #

foldr :: (a -> b -> b) -> b -> Errors a -> b #

foldr' :: (a -> b -> b) -> b -> Errors a -> b #

foldl :: (b -> a -> b) -> b -> Errors a -> b #

foldl' :: (b -> a -> b) -> b -> Errors a -> b #

foldr1 :: (a -> a -> a) -> Errors a -> a #

foldl1 :: (a -> a -> a) -> Errors a -> a #

toList :: Errors a -> [a] #

null :: Errors a -> Bool #

length :: Errors a -> Int #

elem :: Eq a => a -> Errors a -> Bool #

maximum :: Ord a => Errors a -> a #

minimum :: Ord a => Errors a -> a #

sum :: Num a => Errors a -> a #

product :: Num a => Errors a -> a #

Traversable Errors Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

traverse :: Applicative f => (a -> f b) -> Errors a -> f (Errors b) #

sequenceA :: Applicative f => Errors (f a) -> f (Errors a) #

mapM :: Monad m => (a -> m b) -> Errors a -> m (Errors b) #

sequence :: Monad m => Errors (m a) -> m (Errors a) #

HasField "unErrors" (Errors e) (NonEmpty e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

getField :: Errors e -> NonEmpty e #

HasField "unQFirst" (QFirst e a) (Q (Either (Errors e) a)) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

getField :: QFirst e a -> Q (Either (Errors e) a) #

Lift e => Lift (Errors e :: Type) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

lift :: Quote m => Errors e -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => Errors e -> Code m (Errors e) #

Semigroup (Errors e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

(<>) :: Errors e -> Errors e -> Errors e #

sconcat :: NonEmpty (Errors e) -> Errors e #

stimes :: Integral b => b -> Errors e -> Errors e #

Exception e => Exception (Errors e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Show e => Show (Errors e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

showsPrec :: Int -> Errors e -> ShowS #

show :: Errors e -> String #

showList :: [Errors e] -> ShowS #

Eq e => Eq (Errors e) Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.QFirst

Methods

(==) :: Errors e -> Errors e -> Bool #

(/=) :: Errors e -> Errors e -> Bool #

mkErrors :: NonEmpty e -> Errors e Source #

Wraps a type in Errors.

Since: 0.1

unErrors :: Errors e -> NonEmpty e Source #

Unwraps Errors.

Since: 0.1

Eliminating Either

projectStringUnknown :: Functor f => f (Either e String) -> f String Source #

Projects Left to the string UNKNOWN.

Examples

Expand
>>> $$(qToCode $ projectStringUnknown (pure $ Left ()))
"UNKNOWN"

Since: 0.1

projectConst :: forall f e a. Functor f => a -> f (Either e a) -> f a Source #

Projects Left to the given value.

Examples

Expand
>>> $$(qToCode $ projectConst "FAILURE" (pure $ Left ()))
"FAILURE"

Since: 0.1

projectFalse :: Functor f => f (Either e Bool) -> f Bool Source #

Projects Left to False.

Examples

Expand
>>> $$(qToCode $ projectFalse (pure $ Left ()))
False

Since: 0.1

projectError :: forall f e a. (Exception e, Functor f) => f (Either e a) -> f a Source #

Projects Left via error, rendering via displayException. Hence an error will cause a compilation failure in Q.

Examples

Expand
>>> :{
  let gitHashOrDieQ :: Q Bool
      gitHashOrDieQ = projectError gitDirtyQ
:}

Since: 0.1

projectErrorMap :: Functor f => (e -> String) -> f (Either e a) -> f a Source #

Projects Left via error, rendering via the given function. Hence an error will cause a compilation failure.

Examples

Expand
>>> :{
  let gitHashOrDieQ :: Q Bool
      gitHashOrDieQ = (projectErrorMap show) gitDirtyQ
:}

Since: 0.1

projectLeft :: Functor f => (e -> a) -> f (Either e a) -> f a Source #

Projects Left via the given function.

Since: 0.1

Errors

data GitRevError Source #

General error type for anything that can go wrong when running gitrev-typed splices.

Since: 0.1

Constructors

GitRevErrorGit GitError

Git error.

Since: 0.1

GitRevErrorEnv EnvError

Environment variable lookup error.

Since: 0.1

GitRevErrorText Text

Catch-all for anything else that can go wrong.

Since: 0.1

newtype GitError Source #

Errors that can be encountered with git.

Since: 0.1

Constructors

MkGitError 

Fields

Instances

Instances details
Exception GitError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git

Show GitError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git

Eq GitError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git

Lift GitError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Git

Methods

lift :: Quote m => GitError -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => GitError -> Code m GitError #

data EnvError Source #

Environment variable lookup failure.

Since: 0.1

Constructors

MkEnvError 

Fields

  • var :: String

    The environment variable.

    Since: 0.1

  • value :: Maybe String

    The value of the environment variable, if it exists.

    Since: 0.1

  • reason :: String

    Text reason for the failure.

    Since: 0.1

Instances

Instances details
Exception EnvError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Environment

Show EnvError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Environment

Eq EnvError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Environment

Lift EnvError Source #

Since: 0.1

Instance details

Defined in Development.GitRev.Internal.Environment

Methods

lift :: Quote m => EnvError -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => EnvError -> Code m EnvError #

Utilities

embedGitError Source #

Arguments

:: forall f p a. (Bifunctor p, Functor f) 
=> f (p GitError a)

.

-> f (p GitRevError a) 

Embeds a GitError in the larger GitRevError.

Examples

Expand
>>> :{
  let q :: Q (Either GitError ())
      q = pure (Left $ MkGitError "not found")
  in runQ $ embedGitError q
:}
Left (GitRevErrorGit (MkGitError {reason = "not found"}))

Since: 0.1

embedEnvError Source #

Arguments

:: forall f p a. (Bifunctor p, Functor f) 
=> f (p EnvError a)

.

-> f (p GitRevError a) 

Embeds an EnvError in the larger GitRevError.

Examples

Expand
>>> :{
  let q :: Q (Either EnvError ())
      q = pure (Left $ MkEnvError "VAR" Nothing "VAR does not exist")
  in runQ $ embedEnvError q
:}
Left (GitRevErrorEnv (MkEnvError {var = "VAR", value = Nothing, reason = "VAR does not exist"}))

Since: 0.1

embedTextError Source #

Arguments

:: forall f p a. (Bifunctor p, Functor f) 
=> f (p Text a)

.

-> f (p GitRevError a) 

Embeds a Text in the larger GitRevError.

Examples

Expand
>>> :{
  let q :: Q (Either Text ())
      q = pure (Left "Something went wrong")
  in runQ $ embedTextError q
:}
Left (GitRevErrorText "Something went wrong")

Since: 0.1

joinFirst Source #

Arguments

:: forall p a1 a2 b c. (Bifunctor p, forall a. Monad (p a)) 
=> (a1 -> b)

Map outer.

-> (a2 -> b)

Map inner.

-> p a1 (p a2 c)

Nested bifunctor.

-> p b c

Flattened bifunctor.

Join the first component in a bifunctor, useful for unifying nested errors with GitRevError.

Examples

Expand
>>> e = Right @EnvError (Left @Text @() "an error")
>>> :type e
e :: Either EnvError (Either Text ())
>>> let joined = joinFirst GitRevErrorEnv GitRevErrorText e
>>> joined
Left (GitRevErrorText "an error")
>>> :type joined
joined :: Either GitRevError ()

Since: 0.1