shake 0.17 → 0.17.1
raw patch · 10 files changed
+67/−9 lines, 10 files
Files
- CHANGES.txt +4/−0
- shake.cabal +2/−2
- src/Development/Shake.hs +1/−1
- src/Development/Shake/Internal/Core/Action.hs +16/−3
- src/Development/Shake/Internal/Core/Rules.hs +1/−1
- src/Development/Shake/Internal/Rules/Rerun.hs +1/−1
- src/Test/Batch.hs +6/−0
- src/Test/Cache.hs +16/−0
- src/Test/Errors.hs +12/−1
- src/Test/Parallel.hs +8/−0
CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Shake (* = breaking change) +0.17.1, released 2018-11-14+ Add actionCatch, to catch exceptions in Action+ #622, avoid potential maxBound overflow in batch+ Reduce the context required for addBuiltinRule 0.17, released 2018-10-15 Add Database module for repeated execution from one database * Don't export the body of the Typeable type class
shake.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.18 build-type: Simple name: shake-version: 0.17+version: 0.17.1 license: BSD3 license-file: LICENSE category: Development, Shake@@ -30,7 +30,7 @@ (e.g. compiler version). homepage: https://shakebuild.com bug-reports: https://github.com/ndmitchell/shake/issues-tested-with: GHC==8.6.1, GHC==8.4.3, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2+tested-with: GHC==8.6.1, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2, GHC==7.10.3, GHC==7.8.4, GHC==7.6.3, GHC==7.4.2 extra-doc-files: CHANGES.txt README.md
src/Development/Shake.hs view
@@ -54,7 +54,7 @@ shakeOptions, Rules, action, withoutActions, alternatives, priority, versioned, Action, traced,- liftIO, actionOnException, actionFinally, actionRetry, runAfter,+ liftIO, actionOnException, actionFinally, actionCatch, actionRetry, runAfter, ShakeException(..), -- * Configuration ShakeOptions(..), Rebuild(..), Lint(..), Change(..),
src/Development/Shake/Internal/Core/Action.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE RecordWildCards, NamedFieldPuns, ScopedTypeVariables, ConstraintKinds, TupleSections, ViewPatterns #-} module Development.Shake.Internal.Core.Action(- actionOnException, actionFinally, actionRetry,+ actionOnException, actionFinally, actionCatch, actionRetry, getShakeOptions, getProgress, runAfter, lintTrackRead, lintTrackWrite, lintTrackAllow, getVerbosity, putWhen, putLoud, putNormal, putQuiet, withVerbosity, quietly,@@ -102,7 +102,20 @@ actionFinally :: Action a -> IO b -> Action a actionFinally = actionBoom True +-- | If a syncronous exception is raised by the 'Action', perform some handler.+-- Note that there is no guarantee that the handler will run on shutdown (use 'actionFinally' for that),+-- and that 'actionCatch' /cannot/ catch exceptions thrown by dependencies, e.g. raised by 'need'+-- (to do so would allow untracked dependencies on failure conditions).+actionCatch :: Exception e => Action a -> (e -> Action a) -> Action a+actionCatch act hdl = Action $ catchRAW (fromAction act) $ \e ->+ case () of+ _ | not $ isAsyncException e+ , Nothing <- fromException e :: Maybe ShakeException+ , Just e <- fromException e+ -> fromAction $ hdl e+ _ -> throwRAW e + -- | Retry an 'Action' if it throws an exception, at most /n/ times (where /n/ must be positive). -- If you need to call this function, you should probably try and fix the underlying cause (but you also probably know that). actionRetry :: Int -> Action a -> Action a@@ -469,7 +482,7 @@ -- If Shake ever has nothing else to do it will run batches before they are at the maximum, -- so you may see much smaller batches, especially at high parallelism settings. batch- :: Int -- ^ Maximum number to run in a single batch, e.g. @3@.+ :: Int -- ^ Maximum number to run in a single batch, e.g. @3@, must be positive. -> ((a -> Action ()) -> Rules ()) -- ^ Way to match an entry, e.g. @\"*.ext\" '%>'@. -> (a -> Action b) -- ^ Preparation to run individually on each, e.g. using 'need'. -> ([b] -> Action ()) -- ^ Combination action to run on all, e.g. using 'cmd'.@@ -500,7 +513,7 @@ -- delete at most mx from the batch (now, count) <- liftIO $ atomicModifyIORef todo $ \(count, bs) -> let (now,later) = splitAt mx bs- count2 = max 0 $ count - mx+ count2 = if count > mx then count - mx else 0 in ((count2, later), (now, count2)) requeue todo (>=) count
src/Development/Shake/Internal/Core/Rules.hs view
@@ -183,7 +183,7 @@ -- -- Raises an error if any other rule exists at this type. addBuiltinRule- :: (RuleResult key ~ value, ShakeValue key, ShakeValue value, Partial)+ :: (RuleResult key ~ value, ShakeValue key, Typeable value, NFData value, Show value, Partial) => BuiltinLint key value -> BuiltinIdentity key value -> BuiltinRun key value -> Rules () addBuiltinRule = withFrozenCallStack $ addBuiltinRuleInternal $ BinaryOp (putEx . Bin.toLazyByteString . execPut . put)
src/Development/Shake/Internal/Rules/Rerun.hs view
@@ -31,7 +31,7 @@ -- 'Development.Shake.writeFileChanged' out stdout -- @ ----- In make, the @.PHONY@ attribute on file-producing rules has a similar effect.+-- In @make@, the @.PHONY@ attribute on file-producing rules has a similar effect. -- -- Note that 'alwaysRerun' is applied when a rule is executed. Modifying an existing rule -- to insert 'alwaysRerun' will /not/ cause that rule to rerun next time.
src/Test/Batch.hs view
@@ -35,7 +35,10 @@ o <- resultHasChanged out writeFileLines out $ xs ++ ["On" | o] + batch maxBound ("batch_max.*" %>) return $ \outs ->+ forM_ outs $ \out -> writeFile' out $ show $ length outs + test build = do forM_ [1..6] $ \i -> writeFile (show i <.> "in") $ show i build ["--sleep","-j2"]@@ -86,3 +89,6 @@ removeFile "On" build $ ["On", "--sleep"] ++ args assertContents "On" "On\n"++ build ["batch_max." ++ show i | i <- [1..100]]+ assertContents "batch_max.72" "100"
src/Test/Cache.hs view
@@ -3,6 +3,7 @@ import Development.Shake import Development.Shake.FilePath+import System.Directory import Data.Char import Test.Type @@ -15,7 +16,15 @@ "*.out*" %> \x -> writeFile' x . show =<< vowels (dropExtension x <.> "txt") + startCompiler <- newCache $ \() -> do+ liftIO $ writeFile "compiler.txt" "on"+ runAfter $ writeFile "compiler.txt" "off" + "*.lang" %> \out -> do+ startCompiler ()+ liftIO $ copyFile "compiler.txt" out++ test build = do writeFile "trace.txt" "" writeFile "vowels.txt" "abc123a"@@ -36,3 +45,10 @@ build ["vowels.out1","-j3","--sleep"] assertContents "trace.txt" "111" assertContents "vowels.out1" "4"++ build ["foo.lang","bar.lang"]+ assertContents "foo.lang" "on"+ assertContents "compiler.txt" "off"+ writeFile "compiler.txt" "unstarted"+ build ["foo.lang","bar.lang"]+ assertContents "compiler.txt" "unstarted"
src/Test/Errors.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TypeFamilies, GeneralizedNewtypeDeriving, DeriveDataTypeable #-}+{-# LANGUAGE TypeFamilies, GeneralizedNewtypeDeriving, DeriveDataTypeable, ScopedTypeVariables #-} module Test.Errors(main) where @@ -169,6 +169,12 @@ `actionFinally` (output "X" >> sleep 0.1) `actionFinally` output "Y" + let catching out = flip actionCatch $ \(e :: SomeException) -> writeFile' out $ show e+ "catch1" %> \out -> catching out $ fail "magic1"+ "catch2" %> \out -> catching out $ liftIO $ killThread =<< myThreadId+ "catch3.1" %> \out -> fail "magic3"+ "catch3.2" %> \out -> catching out $ need ["catch3.1"]+ -- not tested by default since only causes an error when idle GC is turned on phony "block" $ liftIO $ putStrLn $ let x = x in x@@ -286,3 +292,8 @@ killThread t sleep 0.3 assertContents "finalfinal" "XY"++ build ["catch1"]+ assertContents "catch1" "magic1"+ crash ["catch2"] [show ThreadKilled]+ crash ["catch3.2"] ["magic3"]
src/Test/Parallel.hs view
@@ -35,8 +35,13 @@ peak <- liftIO $ readIORef peak writeFile' "parallel" $ show peak + "parallels" %> \out -> do+ xs <- parallel $ replicate 5 $ parallel $ map return [1..5]+ writeFile' out $ show xs + test build = do+ build ["clean"] writeFile "A.txt" "AAA" writeFile "B.txt" "BBB" build ["AB.txt","--sleep"]@@ -51,3 +56,6 @@ assertContents "parallel" "1" build ["parallel","-j5"] assertContents "parallel" "5"++ build ["parallels"]+ assertContents "parallels" $ show $ replicate 5 [1..5]