module GitHUD.Git.Parse.Base (
getGitRepoState
) where
import Control.Applicative ((<$>))
import Control.Concurrent (forkIO)
import Control.Concurrent.MVar (newEmptyMVar, takeMVar)
import GitHUD.Git.Types
import GitHUD.Git.Command
import GitHUD.Git.Parse.Status
import GitHUD.Git.Parse.Branch
import GitHUD.Git.Parse.Count
removeEndingNewline :: String -> String
removeEndingNewline str = concat . lines $ str
getGitRepoState :: IO GitRepoState
getGitRepoState = do
mvLocalBranch <- newEmptyMVar
mvGitStatus <- newEmptyMVar
mvRemoteName <- newEmptyMVar
mvStashCount <- newEmptyMVar
mvCommitShortSHA <- newEmptyMVar
mvCommitTag <- newEmptyMVar
forkIO $ gitCmdLocalBranchName mvLocalBranch
forkIO $ gitCmdPorcelainStatus mvGitStatus
forkIO $ gitCmdStashCount mvStashCount
forkIO $ gitCmdCommitShortSHA mvCommitShortSHA
forkIO $ gitCmdCommitTag mvCommitTag
localBranchName <- removeEndingNewline <$> (takeMVar mvLocalBranch)
forkIO $ gitCmdRemoteName localBranchName mvRemoteName
remoteName <- removeEndingNewline <$> takeMVar mvRemoteName
repoState <- gitParseStatus <$> takeMVar mvGitStatus
stashCountStr <- takeMVar mvStashCount
commitShortSHA <- removeEndingNewline <$> takeMVar mvCommitShortSHA
commitTag <- removeEndingNewline <$> takeMVar mvCommitTag
fillGitRemoteRepoState zeroGitRepoState {
gitLocalRepoChanges = repoState
, gitRemote = remoteName
, gitLocalBranch = localBranchName
, gitCommitShortSHA = commitShortSHA
, gitCommitTag = commitTag
, gitStashCount = (getCount stashCountStr)
}
fillGitRemoteRepoState :: GitRepoState
-> IO GitRepoState
fillGitRemoteRepoState repoState@( GitRepoState { gitRemote = ""} ) = return repoState
fillGitRemoteRepoState repoState = do
mvRemoteBranchName <- newEmptyMVar
mvMergeBase <- newEmptyMVar
mvCommitsToPull <- newEmptyMVar
mvCommitsToPush <- newEmptyMVar
forkIO $ gitCmdRemoteBranchName (gitLocalBranch repoState) mvRemoteBranchName
forkIO $ gitCmdMergeBase (gitLocalBranch repoState) mvMergeBase
remoteBranch <- removeEndingNewline <$> (takeMVar mvRemoteBranchName)
mergeBase <- removeEndingNewline <$> (takeMVar mvMergeBase)
let fullRemoteBranchName = buildFullyQualifiedRemoteBranchName (gitRemote repoState) remoteBranch
forkIO $ gitCmdRevToPush fullRemoteBranchName "HEAD" mvCommitsToPush
forkIO $ gitCmdRevToPull fullRemoteBranchName "HEAD" mvCommitsToPull
(mergeBranchToPull, mergeBranchToPush) <- getRemoteMasterMergeState mergeBase fullRemoteBranchName
commitsToPushStr <- takeMVar mvCommitsToPush
let commitsToPush = getCount commitsToPushStr
commitsToPullStr <- takeMVar mvCommitsToPull
let commitsToPull = getCount commitsToPullStr
return repoState {
gitRemoteTrackingBranch = remoteBranch
, gitCommitsToPull = commitsToPull
, gitCommitsToPush = commitsToPush
, gitMergeBranchCommitsToPull = mergeBranchToPull
, gitMergeBranchCommitsToPush = mergeBranchToPush
}
getRemoteMasterMergeState :: String
-> String
-> IO (Int, Int)
getRemoteMasterMergeState "" _ = return (0, 0)
getRemoteMasterMergeState _ fullRemoteBranchName = do
mvMergeBranchCommitsToPull <- newEmptyMVar
mvMergeBranchCommitsToPush <- newEmptyMVar
forkIO $ gitCmdRevToPush "origin/master" fullRemoteBranchName mvMergeBranchCommitsToPush
forkIO $ gitCmdRevToPull "origin/master" fullRemoteBranchName mvMergeBranchCommitsToPull
mergeBranchCommitsToRMasterStr <- takeMVar mvMergeBranchCommitsToPull
let mergeBranchCommitsToRMaster = getCount mergeBranchCommitsToRMasterStr
mergeBranchCommitsToMergeStr <- takeMVar mvMergeBranchCommitsToPush
let mergeBranchCommitsToMerge = getCount mergeBranchCommitsToMergeStr
return (mergeBranchCommitsToRMaster, mergeBranchCommitsToMerge)