pre-init config and hook
Added annex.pre-init-command git config and pre-init-annex hook that is run before git-annex repository initialization. This can block initialization. Or it can preform pre-initialization configuration or tweaking. I left stdio connected while it's running, so it could also be used for interactive prompting conceivably, although that would want to use /dev/tty anyway probably in order to not pollute the stdout of a command when automatic initialization is done. Sponsored-by: Dartmouth College's OpenNeuro project
This commit is contained in:
parent
9e95556d69
commit
42d55bc57c
9 changed files with 87 additions and 19 deletions
|
@ -48,6 +48,9 @@ preCommitAnnexHook = Git.Hook "pre-commit-annex" "" []
|
|||
postUpdateAnnexHook :: Git.Hook
|
||||
postUpdateAnnexHook = Git.Hook "post-update-annex" "" []
|
||||
|
||||
preInitAnnexHook :: Git.Hook
|
||||
preInitAnnexHook = Git.Hook "pre-init-annex" "" []
|
||||
|
||||
freezeContentAnnexHook :: Git.Hook
|
||||
freezeContentAnnexHook = Git.Hook "freezecontent-annex" "" []
|
||||
|
||||
|
@ -98,20 +101,33 @@ doesAnnexHookExist hook = do
|
|||
return exists
|
||||
|
||||
runAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex ()
|
||||
runAnnexHook hook commandcfg = ifM (doesAnnexHookExist hook)
|
||||
runAnnexHook hook commandcfg = runAnnexHook' hook commandcfg >>= \case
|
||||
Nothing -> noop
|
||||
Just failedcommanddesc ->
|
||||
warning $ UnquotedString $ failedcommanddesc ++ " failed"
|
||||
|
||||
-- Returns Nothing if the hook or GitConfig command succeeded, or a
|
||||
-- description of what failed.
|
||||
runAnnexHook' :: Git.Hook -> (GitConfig -> Maybe String) -> Annex (Maybe String)
|
||||
runAnnexHook' hook commandcfg = ifM (doesAnnexHookExist hook)
|
||||
( runhook
|
||||
, runcommandcfg
|
||||
)
|
||||
where
|
||||
runhook = unlessM (inRepo $ Git.runHook boolSystem hook []) $ do
|
||||
h <- fromRepo $ Git.hookFile hook
|
||||
commandfailed h
|
||||
runhook = ifM (inRepo $ Git.runHook boolSystem hook [])
|
||||
( return Nothing
|
||||
, do
|
||||
h <- fromRepo (Git.hookFile hook)
|
||||
commandfailed h
|
||||
)
|
||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||
Nothing -> return Nothing
|
||||
Just command ->
|
||||
unlessM (liftIO $ boolSystem "sh" [Param "-c", Param command]) $
|
||||
commandfailed command
|
||||
Nothing -> noop
|
||||
commandfailed c = warning $ UnquotedString $ c ++ " failed"
|
||||
ifM (liftIO $ boolSystem "sh" [Param "-c", Param command])
|
||||
( return Nothing
|
||||
, commandfailed $ "git configured command '" ++ command ++ "'"
|
||||
)
|
||||
commandfailed c = return $ Just c
|
||||
|
||||
runAnnexPathHook :: String -> Git.Hook -> (GitConfig -> Maybe String) -> RawFilePath -> Annex Bool
|
||||
runAnnexPathHook pathtoken hook commandcfg p = ifM (doesAnnexHookExist hook)
|
||||
|
@ -121,9 +137,9 @@ runAnnexPathHook pathtoken hook commandcfg p = ifM (doesAnnexHookExist hook)
|
|||
where
|
||||
runhook = inRepo $ Git.runHook boolSystem hook [ File (fromRawFilePath p) ]
|
||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||
Nothing -> return True
|
||||
Just basecmd -> liftIO $
|
||||
boolSystem "sh" [Param "-c", Param $ gencmd basecmd]
|
||||
Nothing -> return True
|
||||
gencmd = massReplace [ (pathtoken, shellEscape (fromRawFilePath p)) ]
|
||||
|
||||
outputOfAnnexHook :: Git.Hook -> (GitConfig -> Maybe String) -> Annex (Maybe String)
|
||||
|
@ -135,6 +151,6 @@ outputOfAnnexHook hook commandcfg = ifM (doesAnnexHookExist hook)
|
|||
runhook = inRepo (Git.runHook runhook' hook [])
|
||||
runhook' c ps = Just <$> readProcess c (toCommand ps)
|
||||
runcommandcfg = commandcfg <$> Annex.getGitConfig >>= \case
|
||||
Nothing -> return Nothing
|
||||
Just command -> liftIO $
|
||||
Just <$> readProcess "sh" ["-c", command]
|
||||
Nothing -> return Nothing
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{- git-annex repository initialization
|
||||
-
|
||||
- Copyright 2011-2024 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2011-2025 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU AGPL version 3 or higher.
|
||||
-}
|
||||
|
@ -74,17 +74,29 @@ data InitializeAllowed = InitializeAllowed
|
|||
|
||||
checkInitializeAllowed :: (InitializeAllowed -> Annex a) -> Annex a
|
||||
checkInitializeAllowed a = guardSafeToUseRepo $ noAnnexFileContent' >>= \case
|
||||
Nothing -> do
|
||||
checkSqliteWorks
|
||||
a InitializeAllowed
|
||||
Nothing -> runAnnexHook' preInitAnnexHook annexPreInitCommand >>= \case
|
||||
Nothing -> do
|
||||
checkSqliteWorks
|
||||
a InitializeAllowed
|
||||
Just failedcommanddesc -> do
|
||||
initpreventedby failedcommanddesc
|
||||
notinitialized
|
||||
Just noannexmsg -> do
|
||||
warning "Initialization prevented by .noannex file (remove the file to override)"
|
||||
initpreventedby ".noannex file (remove the file to override)"
|
||||
unless (null noannexmsg) $
|
||||
warning (UnquotedString noannexmsg)
|
||||
giveup "Not initialized."
|
||||
notinitialized
|
||||
where
|
||||
initpreventedby r = warning $ UnquotedString $
|
||||
"Initialization prevented by " ++ r
|
||||
notinitialized = giveup "Not initialized."
|
||||
|
||||
initializeAllowed :: Annex Bool
|
||||
initializeAllowed = isNothing <$> noAnnexFileContent'
|
||||
initializeAllowed = noAnnexFileContent' >>= \case
|
||||
Nothing -> runAnnexHook' preInitAnnexHook annexPreInitCommand >>= \case
|
||||
Nothing -> return True
|
||||
Just _ -> return False
|
||||
Just _ -> return False
|
||||
|
||||
noAnnexFileContent' :: Annex (Maybe String)
|
||||
noAnnexFileContent' = inRepo $
|
||||
|
@ -268,7 +280,7 @@ autoInitialize' check startupannex remotelist =
|
|||
getInitializedVersion >>= maybe needsinit checkUpgrade
|
||||
where
|
||||
needsinit =
|
||||
whenM (initializeAllowed <&&> check) $ do
|
||||
whenM (check <&&> initializeAllowed) $ do
|
||||
initialize startupannex Nothing Nothing
|
||||
autoEnableSpecialRemotes remotelist
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@ git-annex (10.20250103) UNRELEASED; urgency=medium
|
|||
annex.http-headers-command.
|
||||
* Added git configs annex.post-update-command and annex.pre-commit-command
|
||||
that correspond to the post-update-annex and pre-commit-annex hooks.
|
||||
* Added annex.pre-init-command git config and pre-init-annex hook
|
||||
that is run before git-annex repository initialization.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Fri, 03 Jan 2025 14:30:38 -0400
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ data GitConfig = GitConfig
|
|||
, annexAlwaysCompact :: Bool
|
||||
, annexCommitMessage :: Maybe String
|
||||
, annexCommitMessageCommand :: Maybe String
|
||||
, annexPreInitCommand :: Maybe String
|
||||
, annexPreCommitCommand :: Maybe String
|
||||
, annexPostUpdateCommand :: Maybe String
|
||||
, annexMergeAnnexBranches :: Bool
|
||||
|
@ -192,6 +193,7 @@ extractGitConfig configsource r = GitConfig
|
|||
, annexAlwaysCompact = getbool (annexConfig "alwayscompact") True
|
||||
, annexCommitMessage = getmaybe (annexConfig "commitmessage")
|
||||
, annexCommitMessageCommand = getmaybe (annexConfig "commitmessage-command")
|
||||
, annexPreInitCommand = getmaybe (annexConfig "pre-init-command")
|
||||
, annexPreCommitCommand = getmaybe (annexConfig "pre-commit-command")
|
||||
, annexPostUpdateCommand = getmaybe (annexConfig "post-update-command")
|
||||
, annexMergeAnnexBranches = getbool (annexConfig "merge-annex-branches") True
|
||||
|
|
|
@ -27,7 +27,11 @@ already initialized git-annex repository.
|
|||
A top-level `.noannex` file will prevent git-annex init from being used
|
||||
in a repository. This is useful for repositories that have a policy
|
||||
reason not to use git-annex. The content of the file will be displayed
|
||||
to the user who tries to run git-annex init.
|
||||
to the user who tries to run git-annex init.
|
||||
|
||||
The annex.pre-init-command git configuration or pre-init-annex hook
|
||||
is run before initialization and can exit nonzero as well to prevent
|
||||
initialization, as well as doing other setup.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
|
|
|
@ -1176,6 +1176,16 @@ repository, using [[git-annex-config]]. See its man page for a list.)
|
|||
Alternatively, a hook script can be installed in
|
||||
`.git/hooks/pre-commit-annex`
|
||||
|
||||
* `annex.pre-init-command`
|
||||
|
||||
This command is run before the repository is initialized, either by
|
||||
`git-annex init`, or automatic initialization. It can configure
|
||||
the repository in any way needed. If it exits nonzero, the repository
|
||||
initialization will fail.
|
||||
|
||||
Alternatively, a hook script can be installed in
|
||||
`.git/hooks/pre-init-annex`
|
||||
|
||||
* `annex.alwayscompact`
|
||||
|
||||
By default, git-annex compacts data it records in the git-annex branch.
|
||||
|
|
|
@ -6,3 +6,5 @@ The idea is stemmed from discussions/problems with using freeze/thaw hooks, and
|
|||
|
||||
[[!meta author=yoh]]
|
||||
[[!tag projects/openneuro]]
|
||||
|
||||
> [[done]] --[[Joey]]
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 5"""
|
||||
date="2025-01-13T17:33:02Z"
|
||||
content="""
|
||||
Note that the `.noannex` file that prevents init has some overlap with
|
||||
a pre-init hook that exits nonzero. I guess the .noannex file has the
|
||||
benefit of working in every clone of a repository without additional
|
||||
configuration.
|
||||
"""]]
|
|
@ -0,0 +1,10 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 6"""
|
||||
date="2025-01-13T18:17:42Z"
|
||||
content="""
|
||||
Implemented .git/hooks/pre-init-annex
|
||||
(and alternatively git config annex.pre-init-command)
|
||||
|
||||
Note that this is also run before automatic initialization.
|
||||
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue