I am trying to get list of all files in HEAD commit from a git repository using gitlib
. Here is my code:
{-# LANGUAGE OverloadedStrings #-}
module GitOperations where
import Git
import Git.Libgit2 (lgFactory, LgRepo(..) )
import qualified Data.Text as T
import Control.Monad.Trans.Reader
import Control.Monad.Trans
import Data.ByteString.Char8 as BS
repositoryOptions :: RepositoryOptions
repositoryOptions = RepositoryOptions { repoPath = ".git"
, repoWorkingDir = Just "."
, repoIsBare = False
, repoAutoCreate = True}
main :: IO ()
main = do
repo <- openRepository lgFactory repositoryOptions
runReaderT listHEADFiles repo
listHEADFiles:: ReaderT LgRepo IO ()
listHEADFiles = do
ref <- resolveReference $ T.pack "HEAD"
case ref of
Nothing -> fail $ "Could not resolve reference named 'HEAD'"
Just reference -> do
obj <- lookupObject reference
case obj of
CommitObj commit -> do
objects <- listAllObjects (Just $ commitOid commit) (commitOid commit)
lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; bc <- blobContents blob; case bc of BlobString bs -> BS.putStrLn bs) objects
_ -> fail $ "'HEAD' is not a commit object"
The error I'm getting is:
Main.hs:33:96: error:
• Couldn't match kind ‘* -> *’ with ‘*’
When matching types
IO :: * -> *
BlobContents :: (* -> *) -> *
Expected type: IO (BlobContents m0)
Actual type: BlobContents IO
• In a stmt of a 'do' block: bc <- blobContents blob
In the expression:
do blob <- lookupBlob boOid
bc <- blobContents blob
case bc of { BlobString bs -> BS.putStrLn bs }
In a case alternative:
BlobObjOid boOid
-> do blob <- lookupBlob boOid
bc <- blobContents blob
case bc of { BlobString bs -> BS.putStrLn bs }
|
33 | lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; bc <- blobContents blob; case bc of BlobString bs -> BS.putStrLn bs) objects
| ^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
I do not understand how to go around this error message and how to adapt my code to make typechecker happy. Any tips are appreciated.
Note that git repository should contain at least one commit for the script to work.
UPD: Per @chi's recommendation, I have changed call to blobContents blob
to be non-monadic, but now that relevant line looks like lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; let bc = blobContents blob in case bc of BlobString bs -> BS.putStrLn bs) objects
, another error comes up and I don't know how to fix it:
Main.hs:33:72: error:
• No instance for (Git.Libgit2.HasLgRepo IO)
arising from a use of ‘lookupBlob’
• In a stmt of a 'do' block: blob <- lookupBlob boOid
In the expression:
do blob <- lookupBlob boOid
let bc = ... in case bc of { BlobString bs -> BS.putStrLn bs }
In a case alternative:
BlobObjOid boOid
-> do blob <- lookupBlob boOid
let ... in case bc of { BlobString bs -> ... }
|
33 | lift $ mapM_ (\o -> case o of BlobObjOid boOid -> do blob <- lookupBlob boOid; let bc = blobContents blob in case bc of BlobString bs -> BS.putStrLn bs) objects
| ^^^^^^^^^^^^^^^^
Failed, no modules loaded.
I am pretty new to gitlib
and it is overwhelming for me now that I try to make simple things work with git in haskell. Does anyone have any idea how to make this code compile successfully?
If I found the correct documentation page, blobContents
looks like a non-monadic function, so you can't use bc <- blobContents blob
. Use instead let bc = blobContents blob
.
This is consistent with the error message, which states that the actual type is not wrapped under IO.
Expected type: IO (BlobContents m0)
Actual type: BlobContents IO
Further, you use lift
too early:
lift $ mapM_ (\o -> case o of
BlobObjOid boOid -> do
blob <- lookupBlob boOid
let bc = blobContents blob
case bc of BlobString bs -> BS.putStrLn bs
) objects
Inside the lift
you are constrained to use IO
actions, only, and can not use the ones which require ReaderT LgRepo IO
. To solve this issue, simply move the lift
inwards:
mapM_ (\o -> case o of
BlobObjOid boOid -> do
blob <- lookupBlob boOid
let bc = blobContents blob
case bc of BlobString bs -> lift $ BS.putStrLn bs
) objects