improve back-compat of post-receive hook

* init: Improve generated post-receive hook, so it won't fail when
  run on a system whose git-annex is too old to support git-annex post-receive
* init: Update the post-receive hook when re-run in an existing repository.

This commit was sponsored by Jack Hill on Patreon.
This commit is contained in:
Joey Hess 2018-09-25 15:02:12 -04:00
parent fc8be1980c
commit 177e45517f
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 74 additions and 30 deletions

View file

@ -1,6 +1,6 @@
{- git hooks
-
- Copyright 2013-2015 Joey Hess <id@joeyh.name>
- Copyright 2013-2018 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@ -20,6 +20,7 @@ import Utility.FileMode
data Hook = Hook
{ hookName :: FilePath
, hookScript :: String
, hookOldScripts :: [String]
}
deriving (Ord)
@ -30,38 +31,47 @@ hookFile :: Hook -> Repo -> FilePath
hookFile h r = localGitDir r </> "hooks" </> hookName h
{- Writes a hook. Returns False if the hook already exists with a different
- content. -}
- content. Upgrades old scripts. -}
hookWrite :: Hook -> Repo -> IO Bool
hookWrite h r = do
let f = hookFile h r
ifM (doesFileExist f)
( expectedContent h r
, do
viaTmp writeFile f (hookScript h)
p <- getPermissions f
setPermissions f $ p {executable = True}
return True
)
hookWrite h r = ifM (doesFileExist f)
( expectedContent h r >>= \case
UnexpectedContent -> return False
ExpectedContent -> return True
OldExpectedContent -> go
, go
)
where
f = hookFile h r
go = do
viaTmp writeFile f (hookScript h)
p <- getPermissions f
setPermissions f $ p {executable = True}
return True
{- Removes a hook. Returns False if the hook contained something else, and
- could not be removed. -}
hookUnWrite :: Hook -> Repo -> IO Bool
hookUnWrite h r = do
let f = hookFile h r
ifM (doesFileExist f)
( ifM (expectedContent h r)
( do
removeFile f
return True
, return False
)
, return True
)
hookUnWrite h r = ifM (doesFileExist f)
( expectedContent h r >>= \case
UnexpectedContent -> return False
_ -> do
removeFile f
return True
, return True
)
where
f = hookFile h r
expectedContent :: Hook -> Repo -> IO Bool
data ExpectedContent = UnexpectedContent | ExpectedContent | OldExpectedContent
expectedContent :: Hook -> Repo -> IO ExpectedContent
expectedContent h r = do
content <- readFile $ hookFile h r
return $ content == hookScript h
return $ if content == hookScript h
then ExpectedContent
else if any (content ==) (hookOldScripts h)
then OldExpectedContent
else UnexpectedContent
hookExists :: Hook -> Repo -> IO Bool
hookExists h r = do