module Propellor.Git.Config where

import Propellor.Git
import Utility.Process
import Utility.Exception
import Utility.SafeCommand
import Utility.Monad

import Control.Monad
import Control.Applicative
import Prelude

getGitConfigValue :: String -> IO (Maybe String)
getGitConfigValue :: String -> IO (Maybe String)
getGitConfigValue String
key = do
	value <- IO String -> IO (Maybe String)
forall (m :: * -> *) a. MonadCatch m => m a -> m (Maybe a)
catchMaybeIO (IO String -> IO (Maybe String)) -> IO String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$
		(Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n')
			(String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcessString
"git" [String
"config", String
key]
	return $ case value of
		Just String
v | Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
v) -> String -> Maybe String
forall a. a -> Maybe a
Just String
v
		Maybe String
_ -> Maybe String
forall a. Maybe a
Nothing

-- `git config --bool propellor.blah` outputs "false" if propellor.blah is unset
-- i.e. the git convention is that the default value of any git-config setting
-- is "false".  So we don't need a Maybe Bool here.
getGitConfigBool :: String -> IO Bool
getGitConfigBool :: String -> IO Bool
getGitConfigBool String
key = do
	value <- IO String -> IO (Maybe String)
forall (m :: * -> *) a. MonadCatch m => m a -> m (Maybe a)
catchMaybeIO (IO String -> IO (Maybe String)) -> IO String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$
		(Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n')
			(String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> IO String
readProcess String
"git" [String
"config", String
"--bool", String
key]
	return $ case value of
		Just String
"true" -> Bool
True
		Maybe String
_ -> Bool
False

setRepoUrl :: String -> IO ()
setRepoUrl :: String -> IO ()
setRepoUrl String
"" = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
setRepoUrl String
url = do
	subcmd <- IO Bool -> (IO String, IO String) -> IO String
forall (m :: * -> *) a. Monad m => m Bool -> (m a, m a) -> m a
ifM IO Bool
hasOrigin (String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"set-url", String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
"add")
	void $ boolSystem "git" [Param "remote", Param subcmd, Param "origin", Param url]
	-- same as --set-upstream-to, except origin branch
	-- may not have been pulled yet
	branch <- getCurrentBranch
	let branchval String
s = String
"branch." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
branch String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
	void $ boolSystem "git" [Param "config", Param (branchval "remote"), Param "origin"]
	void $ boolSystem "git" [Param "config", Param (branchval "merge"), Param $ "refs/heads/"++branch]

getRepoUrl :: IO (Maybe String)
getRepoUrl :: IO (Maybe String)
getRepoUrl = (String -> IO (Maybe String)) -> [String] -> IO (Maybe String)
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m (Maybe b)
getM String -> IO (Maybe String)
getGitConfigValue [String]
urls
  where
	urls :: [String]
urls = [String
"remote.deploy.url", String
"remote.origin.url"]