module Git where import Data.List.Split import System import System.Directory import System.Exit import System.Process data UpdateRepoError = UpdateRepoError { path :: FilePath , message :: String } deriving (Eq, Show) data UpdateRepoSuccess = UpdateRepoSuccess { repo :: FilePath , result :: String } deriving (Eq, Show) isGitInstalled :: IO Bool isGitInstalled = do (exitCode, stdOut, stdErr) <- readProcessWithExitCode "git" ["--version"] [] return (exitCode == ExitSuccess) getCurrentBranch :: FilePath -> IO String getCurrentBranch path = do let gitRepoPath = appendGitFolder path (exitCode, stdOut, stdErr) <- readProcessWithExitCode "git" ["--git-dir", gitRepoPath, "branch"] [] return (extractCurrentBranch stdOut) updateRepo :: FilePath -> String -> IO (Either UpdateRepoError UpdateRepoSuccess) updateRepo path branch = do let gitRepoPath = appendGitFolder path readProcessWithExitCode "git" ["--git-dir", "--work-tree", path, gitRepoPath, "fetch", "origin", "master"] [] readProcessWithExitCode "git" ["--git-dir", "--work-tree", path, gitRepoPath, "fetch", "origin", "develop"] [] readProcessWithExitCode "git" ["--git-dir", "--work-tree", path, gitRepoPath, "stash"] [] (exitCode, stdOut, stdErr) <- readProcessWithExitCode "git" ["--git-dir", gitRepoPath, "--work-tree", path, "pull", "origin", branch, "-n" , "-f"] [] if exitCode == ExitSuccess then return (Right (UpdateRepoSuccess path stdOut)) else return (Left (UpdateRepoError path stdErr)) containsGitMetadataDirectory :: [FilePath] -> Bool containsGitMetadataDirectory = any isGitMetadataDirectory containsOtherVCSMetadataDirectory :: [FilePath] -> Bool containsOtherVCSMetadataDirectory = any isOtherVCSDierctory isGitMetadataDirectory :: FilePath -> Bool isGitMetadataDirectory = contains gitFolder isOtherVCSDierctory :: FilePath -> Bool isOtherVCSDierctory = contains ".hg" contains :: FilePath -> FilePath -> Bool contains directory path | null path = False | path == directory = True | path == directory ++ separator = True | otherwise = contains directory (tail path) extractCurrentBranch :: String -> String extractCurrentBranch stdOut = drop 2 $ head selectedBranches where branches = splitOn "\n" stdOut selectedBranches = filter (\branch -> '*' `elem` branch) branches appendGitFolder :: String -> String appendGitFolder path = path ++ gitFolder gitFolder = ".git"