support conditionally excluding queued files
Switched code to use a for loop to avoid a filterM that would have doubled the memory used. This commit was supported by the NSF-funded DataLad project.
This commit is contained in:
parent
82cfcfc838
commit
6a445dc086
2 changed files with 34 additions and 17 deletions
31
Git/Queue.hs
31
Git/Queue.hs
|
@ -11,6 +11,7 @@ module Git.Queue (
|
||||||
Queue,
|
Queue,
|
||||||
new,
|
new,
|
||||||
addCommand,
|
addCommand,
|
||||||
|
addCommandCond,
|
||||||
addUpdateIndex,
|
addUpdateIndex,
|
||||||
size,
|
size,
|
||||||
full,
|
full,
|
||||||
|
@ -36,8 +37,11 @@ data Action
|
||||||
| CommandAction
|
| CommandAction
|
||||||
{ getSubcommand :: String
|
{ getSubcommand :: String
|
||||||
, getParams :: [CommandParam]
|
, getParams :: [CommandParam]
|
||||||
, getFiles :: [CommandParam]
|
{- The IO action is run when constructing the action, and
|
||||||
}
|
- can return False if the file should not be included
|
||||||
|
- after all. -}
|
||||||
|
, getFiles :: [(FilePath, IO Bool)]
|
||||||
|
}
|
||||||
|
|
||||||
{- A key that can uniquely represent an action in a Map. -}
|
{- A key that can uniquely represent an action in a Map. -}
|
||||||
data ActionKey = UpdateIndexActionKey | CommandActionKey String
|
data ActionKey = UpdateIndexActionKey | CommandActionKey String
|
||||||
|
@ -79,13 +83,19 @@ new lim = Queue 0 (fromMaybe defaultLimit lim) M.empty
|
||||||
- result.
|
- result.
|
||||||
-}
|
-}
|
||||||
addCommand :: String -> [CommandParam] -> [FilePath] -> Queue -> Repo -> IO Queue
|
addCommand :: String -> [CommandParam] -> [FilePath] -> Queue -> Repo -> IO Queue
|
||||||
addCommand subcommand params files q repo =
|
addCommand subcommand params files q repo =
|
||||||
|
addCommandCond subcommand params files' q repo
|
||||||
|
where
|
||||||
|
files' = map (\f -> (f, return True)) files
|
||||||
|
|
||||||
|
addCommandCond :: String -> [CommandParam] -> [(FilePath, IO Bool)] -> Queue -> Repo -> IO Queue
|
||||||
|
addCommandCond subcommand params files q repo =
|
||||||
updateQueue action different (length files) q repo
|
updateQueue action different (length files) q repo
|
||||||
where
|
where
|
||||||
action = CommandAction
|
action = CommandAction
|
||||||
{ getSubcommand = subcommand
|
{ getSubcommand = subcommand
|
||||||
, getParams = params
|
, getParams = params
|
||||||
, getFiles = map File files
|
, getFiles = files
|
||||||
}
|
}
|
||||||
|
|
||||||
different (CommandAction { getSubcommand = s }) = s /= subcommand
|
different (CommandAction { getSubcommand = s }) = s /= subcommand
|
||||||
|
@ -157,17 +167,22 @@ runAction repo (UpdateIndexAction streamers) =
|
||||||
Git.UpdateIndex.streamUpdateIndex repo $ reverse streamers
|
Git.UpdateIndex.streamUpdateIndex repo $ reverse streamers
|
||||||
runAction repo action@(CommandAction {}) = do
|
runAction repo action@(CommandAction {}) = do
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
let p = (proc "xargs" $ "-0":"git":toCommand gitparams) { env = gitEnv repo }
|
let p = (proc "xargs" $ "-0":"git":toCommand gitparams)
|
||||||
|
{ env = gitEnv repo }
|
||||||
withHandle StdinHandle createProcessSuccess p $ \h -> do
|
withHandle StdinHandle createProcessSuccess p $ \h -> do
|
||||||
hPutStr h $ intercalate "\0" $ toCommand $ getFiles action
|
forM_ (getFiles action) $ \(f, check) ->
|
||||||
|
whenM check $ do
|
||||||
|
hPutStr h (toCommand' (File f))
|
||||||
|
hPutStr h "\0"
|
||||||
hClose h
|
hClose h
|
||||||
#else
|
#else
|
||||||
-- Using xargs on Windows is problematic, so just run the command
|
-- Using xargs on Windows is problematic, so just run the command
|
||||||
-- once per file (not as efficient.)
|
-- once per file (not as efficient.)
|
||||||
if null (getFiles action)
|
if null (getFiles action)
|
||||||
then void $ boolSystemEnv "git" gitparams (gitEnv repo)
|
then void $ boolSystemEnv "git" gitparams (gitEnv repo)
|
||||||
else forM_ (getFiles action) $ \f ->
|
else forM_ (getFiles action) $ \(f, check) ->
|
||||||
void $ boolSystemEnv "git" (gitparams ++ [f]) (gitEnv repo)
|
whenM check $
|
||||||
|
void $ boolSystemEnv "git" (gitparams ++ [File f]) (gitEnv repo)
|
||||||
#endif
|
#endif
|
||||||
where
|
where
|
||||||
gitparams = gitCommandLine
|
gitparams = gitCommandLine
|
||||||
|
|
|
@ -27,19 +27,21 @@ data CommandParam
|
||||||
-- | Used to pass a list of CommandParams to a function that runs
|
-- | Used to pass a list of CommandParams to a function that runs
|
||||||
-- a command and expects Strings. -}
|
-- a command and expects Strings. -}
|
||||||
toCommand :: [CommandParam] -> [String]
|
toCommand :: [CommandParam] -> [String]
|
||||||
toCommand = map unwrap
|
toCommand = map toCommand'
|
||||||
|
|
||||||
|
toCommand' :: CommandParam -> String
|
||||||
|
toCommand' (Param s) = s
|
||||||
|
-- Files that start with a non-alphanumeric that is not a path
|
||||||
|
-- separator are modified to avoid the command interpreting them as
|
||||||
|
-- options or other special constructs.
|
||||||
|
toCommand' (File s@(h:_))
|
||||||
|
| isAlphaNum h || h `elem` pathseps = s
|
||||||
|
| otherwise = "./" ++ s
|
||||||
where
|
where
|
||||||
unwrap (Param s) = s
|
|
||||||
-- Files that start with a non-alphanumeric that is not a path
|
|
||||||
-- separator are modified to avoid the command interpreting them as
|
|
||||||
-- options or other special constructs.
|
|
||||||
unwrap (File s@(h:_))
|
|
||||||
| isAlphaNum h || h `elem` pathseps = s
|
|
||||||
| otherwise = "./" ++ s
|
|
||||||
unwrap (File s) = s
|
|
||||||
-- '/' is explicitly included because it's an alternative
|
-- '/' is explicitly included because it's an alternative
|
||||||
-- path separator on Windows.
|
-- path separator on Windows.
|
||||||
pathseps = pathSeparator:"./"
|
pathseps = pathSeparator:"./"
|
||||||
|
toCommand' (File s) = s
|
||||||
|
|
||||||
-- | Run a system command, and returns True or False if it succeeded or failed.
|
-- | Run a system command, and returns True or False if it succeeded or failed.
|
||||||
--
|
--
|
||||||
|
|
Loading…
Reference in a new issue