support reading config over ssh

This commit is contained in:
Joey Hess 2010-10-22 12:38:20 -04:00
parent 014f7f650d
commit 8da596feff

View file

@ -56,12 +56,11 @@ data Repo =
-- remoteName holds the name used for this repo in remotes -- remoteName holds the name used for this repo in remotes
remoteName :: Maybe String remoteName :: Maybe String
} | RemoteRepo { } | RemoteRepo {
url :: String, url :: URI,
top :: FilePath,
config :: Map String String, config :: Map String String,
remotes :: [Repo], remotes :: [Repo],
remoteName :: Maybe String remoteName :: Maybe String
} deriving (Show, Read, Eq) } deriving (Show, Eq)
{- Local Repo constructor. -} {- Local Repo constructor. -}
repoFromPath :: FilePath -> Repo repoFromPath :: FilePath -> Repo
@ -77,13 +76,11 @@ repoFromPath dir =
repoFromUrl :: String -> Repo repoFromUrl :: String -> Repo
repoFromUrl url = repoFromUrl url =
RemoteRepo { RemoteRepo {
url = url, url = fromJust $ parseURI url,
top = path url,
config = Map.empty, config = Map.empty,
remotes = [], remotes = [],
remoteName = Nothing remoteName = Nothing
} }
where path url = uriPath $ fromJust $ parseURI url
{- User-visible description of a git repo. -} {- User-visible description of a git repo. -}
repoDescribe repo = repoDescribe repo =
@ -91,7 +88,7 @@ repoDescribe repo =
then fromJust $ remoteName repo then fromJust $ remoteName repo
else if (repoIsLocal repo) else if (repoIsLocal repo)
then top repo then top repo
else url repo else show (url repo)
{- Constructs and returns an updated version of a repo with {- Constructs and returns an updated version of a repo with
- different remotes list. -} - different remotes list. -}
@ -105,8 +102,8 @@ repoRemoteName r =
then fromJust $ remoteName r then fromJust $ remoteName r
else "" else ""
{- Some code needs to vary between remote and local repos, or bare and {- Some code needs to vary between remote and local repos,
- non-bare, these functions help with that. -} - or bare and non-bare, these functions help with that. -}
repoIsLocal repo = case (repo) of repoIsLocal repo = case (repo) of
LocalRepo {} -> True LocalRepo {} -> True
RemoteRepo {} -> False RemoteRepo {} -> False
@ -116,6 +113,10 @@ assertlocal repo action =
then action then action
else error $ "acting on remote git repo " ++ (repoDescribe repo) ++ else error $ "acting on remote git repo " ++ (repoDescribe repo) ++
" not supported" " not supported"
assertssh repo action =
case (uriScheme $ url repo) of
"ssh:" -> action
_ -> error $ "unsupported remote repo type " ++ (show $ url repo)
bare :: Repo -> Bool bare :: Repo -> Bool
bare repo = bare repo =
if (member b (config repo)) if (member b (config repo))
@ -193,16 +194,24 @@ notInRepo repo location = do
{- Runs git config and populates a repo with its config. -} {- Runs git config and populates a repo with its config. -}
configRead :: Repo -> IO Repo configRead :: Repo -> IO Repo
configRead repo = assertlocal repo $ do configRead repo = if (repoIsLocal repo)
{- Cannot use pipeRead because it relies on the config having {- Cannot use pipeRead because it relies on the config having
been already read. Instead, chdir to the repo. -} been already read. Instead, chdir to the repo. -}
cwd <- getCurrentDirectory then do
bracket_ (changeWorkingDirectory (top repo)) cwd <- getCurrentDirectory
(\_ -> changeWorkingDirectory cwd) $ bracket_ (changeWorkingDirectory (top repo))
pOpen ReadFromPipe "git" ["config", "--list"] $ \h -> do (\_ -> changeWorkingDirectory cwd) $
val <- hGetContentsStrict h pOpen ReadFromPipe "git" ["config", "--list"] proc
let r = repo { config = configParse val } else assertssh repo $ do
return r { remotes = configRemotes r } pOpen ReadFromPipe "ssh" [sshhost, sshcommand] proc
where
sshhost = (uriUserInfo a) ++ (uriRegName a) ++ (uriPort a)
where a = fromJust $ uriAuthority $ url repo
sshcommand = "cd '" ++ (uriPath $ url repo) ++ "' && git config --list"
proc h = do
val <- hGetContentsStrict h
let r = repo { config = configParse val }
return r { remotes = configRemotes r }
{- Calculates a list of a repo's configured remotes, by parsing its config. -} {- Calculates a list of a repo's configured remotes, by parsing its config. -}
configRemotes :: Repo -> [Repo] configRemotes :: Repo -> [Repo]