1{- git check-ignore interface, with handle automatically stored in 2 - the Annex monad 3 - 4 - Copyright 2013-2020 Joey Hess <id@joeyh.name> 5 - 6 - Licensed under the GNU AGPL version 3 or higher. 7 -} 8 9module Annex.CheckIgnore ( 10 CheckGitIgnore(..), 11 checkIgnored, 12 checkIgnoreStop, 13 mkConcurrentCheckIgnoreHandle, 14) where 15 16import Annex.Common 17import qualified Git.CheckIgnore as Git 18import qualified Annex 19import Utility.ResourcePool 20import Types.Concurrency 21import Annex.Concurrent.Utility 22 23newtype CheckGitIgnore = CheckGitIgnore Bool 24 25checkIgnored :: CheckGitIgnore -> RawFilePath -> Annex Bool 26checkIgnored (CheckGitIgnore False) _ = pure False 27checkIgnored (CheckGitIgnore True) file = 28 ifM (Annex.getState Annex.force) 29 ( pure False 30 , withCheckIgnoreHandle $ \h -> liftIO $ Git.checkIgnored h file 31 ) 32 33withCheckIgnoreHandle :: (Git.CheckIgnoreHandle -> Annex a) -> Annex a 34withCheckIgnoreHandle a = 35 maybe mkpool go =<< Annex.getState Annex.checkignorehandle 36 where 37 go p = withResourcePool p start a 38 start = inRepo Git.checkIgnoreStart 39 mkpool = do 40 -- This only runs in non-concurrent code paths; 41 -- a concurrent pool is set up earlier when needed. 42 p <- mkResourcePoolNonConcurrent start 43 Annex.changeState $ \s -> s { Annex.checkignorehandle = Just p } 44 go p 45 46mkConcurrentCheckIgnoreHandle :: Concurrency -> Annex (ResourcePool Git.CheckIgnoreHandle) 47mkConcurrentCheckIgnoreHandle c = 48 Annex.getState Annex.checkignorehandle >>= \case 49 Just p@(ResourcePool {}) -> return p 50 _ -> mkResourcePool =<< liftIO (maxCheckIgnores c) 51 52{- git check-ignore is typically CPU bound, and is not likely to be the main 53 - bottleneck for any command. So limit to the number of CPU cores, maximum, 54 - while respecting the -Jn value. 55 -} 56maxCheckIgnores :: Concurrency -> IO Int 57maxCheckIgnores = concurrencyUpToCpus 58 59checkIgnoreStop :: Annex () 60checkIgnoreStop = maybe noop stop =<< Annex.getState Annex.checkignorehandle 61 where 62 stop p = do 63 liftIO $ freeResourcePool p Git.checkIgnoreStop 64 Annex.changeState $ \s -> s { Annex.checkignorehandle = Nothing } 65