64 lines
2 KiB
Haskell
64 lines
2 KiB
Haskell
{- git check-ignore interface, with handle automatically stored in
|
|
- the Annex monad
|
|
-
|
|
- Copyright 2013-2020 Joey Hess <id@joeyh.name>
|
|
-
|
|
- Licensed under the GNU AGPL version 3 or higher.
|
|
-}
|
|
|
|
module Annex.CheckIgnore (
|
|
CheckGitIgnore(..),
|
|
checkIgnored,
|
|
checkIgnoreStop,
|
|
mkConcurrentCheckIgnoreHandle,
|
|
) where
|
|
|
|
import Annex.Common
|
|
import qualified Git.CheckIgnore as Git
|
|
import qualified Annex
|
|
import Utility.ResourcePool
|
|
import Types.Concurrency
|
|
import Annex.Concurrent.Utility
|
|
|
|
newtype CheckGitIgnore = CheckGitIgnore Bool
|
|
|
|
checkIgnored :: CheckGitIgnore -> FilePath -> Annex Bool
|
|
checkIgnored (CheckGitIgnore False) _ = pure False
|
|
checkIgnored (CheckGitIgnore True) file =
|
|
ifM (Annex.getState Annex.force)
|
|
( pure False
|
|
, withCheckIgnoreHandle $ \h -> liftIO $ Git.checkIgnored h file
|
|
)
|
|
|
|
withCheckIgnoreHandle :: (Git.CheckIgnoreHandle -> Annex a) -> Annex a
|
|
withCheckIgnoreHandle a =
|
|
maybe mkpool go =<< Annex.getState Annex.checkignorehandle
|
|
where
|
|
go p = withResourcePool p start a
|
|
start = inRepo Git.checkIgnoreStart
|
|
mkpool = do
|
|
-- This only runs in non-concurrent code paths;
|
|
-- a concurrent pool is set up earlier when needed.
|
|
p <- mkResourcePoolNonConcurrent start
|
|
Annex.changeState $ \s -> s { Annex.checkignorehandle = Just p }
|
|
go p
|
|
|
|
mkConcurrentCheckIgnoreHandle :: Concurrency -> Annex (ResourcePool Git.CheckIgnoreHandle)
|
|
mkConcurrentCheckIgnoreHandle c =
|
|
Annex.getState Annex.checkignorehandle >>= \case
|
|
Just p@(ResourcePool {}) -> return p
|
|
_ -> mkResourcePool =<< liftIO (maxCheckIgnores c)
|
|
|
|
{- git check-ignore is typically CPU bound, and is not likely to be the main
|
|
- bottleneck for any command. So limit to the number of CPU cores, maximum,
|
|
- while respecting the -Jn value.
|
|
-}
|
|
maxCheckIgnores :: Concurrency -> IO Int
|
|
maxCheckIgnores = concurrencyUpToCpus
|
|
|
|
checkIgnoreStop :: Annex ()
|
|
checkIgnoreStop = maybe noop stop =<< Annex.getState Annex.checkignorehandle
|
|
where
|
|
stop p = do
|
|
liftIO $ freeResourcePool p Git.checkIgnoreStop
|
|
Annex.changeState $ \s -> s { Annex.checkignorehandle = Nothing }
|