aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-03-14 12:17:38 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-03-14 12:18:15 -0400
commitf974a200871d11edc44af5e5acad491f9653ad12 (patch)
tree8c64251a41e05e95781b82d86ae8983eeba31717
parent5b869eef911d36627174ed5a02452011effc2a14 (diff)
check hook executability
-rw-r--r--Git.hs10
-rw-r--r--Utility/FileMode.hs7
2 files changed, 15 insertions, 2 deletions
diff --git a/Git.hs b/Git.hs
index 043cda5ea..9b7dccfeb 100644
--- a/Git.hs
+++ b/Git.hs
@@ -32,9 +32,11 @@ import qualified Data.Map as M
import Data.Char
import Network.URI (uriPath, uriScheme, unEscapeString)
import System.Directory
+import System.Posix.Files
import Common
import Git.Types
+import Utility.FileMode
{- User-visible description of a git repo. -}
repoDescribe :: Repo -> String
@@ -111,8 +113,12 @@ gitDir repo
hookPath :: String -> Repo -> IO (Maybe FilePath)
hookPath script repo = do
let hook = gitDir repo </> "hooks" </> script
- ok <- doesFileExist hook
- return $ if ok then Just hook else Nothing
+ e <- doesFileExist hook
+ if e
+ then do
+ m <- fileMode <$> getFileStatus hook
+ return $ if isExecutable m then Just hook else Nothing
+ else return Nothing
{- Path to a repository's --work-tree, that is, its top.
-
diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs
index 6c1c06e82..571b03503 100644
--- a/Utility/FileMode.hs
+++ b/Utility/FileMode.hs
@@ -34,3 +34,10 @@ allowWrite f = do
{- Checks if a file mode indicates it's a symlink. -}
isSymLink :: FileMode -> Bool
isSymLink mode = symbolicLinkMode `intersectFileModes` mode == symbolicLinkMode
+
+{- Checks if a file has any executable bits set. -}
+isExecutable :: FileMode -> Bool
+isExecutable mode = ebits `intersectFileModes` mode /= 0
+ where
+ ebits = ownerExecuteMode `unionFileModes`
+ groupExecuteMode `unionFileModes` otherExecuteMode