module Propellor.Git where

import Utility.Process
import Utility.Exception
import Utility.Directory
import Utility.Misc
import Utility.PartialPrelude

import Data.Maybe
import Control.Applicative
import Prelude

getCurrentBranch :: IO String
getCurrentBranch :: IO String
getCurrentBranch = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '\n')
	(String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["symbolic-ref", "--short", "HEAD"]

getCurrentBranchRef :: IO String
getCurrentBranchRef :: IO String
getCurrentBranchRef = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '\n')
	(String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["symbolic-ref", "HEAD"]

getCurrentGitSha1 :: String -> IO String
getCurrentGitSha1 :: String -> IO String
getCurrentGitSha1 branchref :: String
branchref = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '\n')
	(String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["show-ref", "--hash", String
branchref]

hasOrigin :: IO Bool
hasOrigin :: IO Bool
hasOrigin = String -> IO Bool
hasRemote "origin"

hasRemote :: String -> IO Bool
hasRemote :: String -> IO Bool
hasRemote remotename :: String
remotename = Bool -> IO Bool -> IO Bool
forall (m :: * -> *) a. MonadCatch m => a -> m a -> m a
catchDefaultIO Bool
False (IO Bool -> IO Bool) -> IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ do
	[String]
rs <- String -> [String]
lines (String -> [String]) -> IO String -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["remote"]
	Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ String
remotename String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
rs

remoteUrl :: String -> IO (Maybe String)
remoteUrl :: String -> IO (Maybe String)
remoteUrl remotename :: String
remotename = Maybe String -> IO (Maybe String) -> IO (Maybe String)
forall (m :: * -> *) a. MonadCatch m => a -> m a -> m a
catchDefaultIO Maybe String
forall a. Maybe a
Nothing (IO (Maybe String) -> IO (Maybe String))
-> IO (Maybe String) -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ [String] -> Maybe String
forall a. [a] -> Maybe a
headMaybe ([String] -> Maybe String)
-> (String -> [String]) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines
	(String -> Maybe String) -> IO String -> IO (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["config", "remote." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
remotename String -> String -> String
forall a. [a] -> [a] -> [a]
++ ".url"]

hasGitRepo :: IO Bool
hasGitRepo :: IO Bool
hasGitRepo = String -> IO Bool
doesFileExist ".git/HEAD"

type Version = [Int]

gitVersion :: IO Version
gitVersion :: IO Version
gitVersion = String -> Version
forall a. Read a => String -> [a]
extract (String -> Version) -> IO String -> IO Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess "git" ["--version"]
  where
	extract :: String -> [a]
extract s :: String
s = case String -> [String]
lines String
s of
		[] -> []
		(l :: String
l:_) -> (String -> Maybe a) -> [String] -> [a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe String -> Maybe a
forall a. Read a => String -> Maybe a
readish ([String] -> [a]) -> [String] -> [a]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
segment (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '.') (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$
			[String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop 2 ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ String -> [String]
words String
l