shake 0.17.2 → 0.17.3
raw patch · 8 files changed
+43/−20 lines, 8 files
Files
- CHANGES.txt +3/−0
- shake.cabal +1/−1
- src/Development/Shake/Internal/Args.hs +8/−5
- src/Development/Shake/Internal/Core/Action.hs +1/−1
- src/Development/Shake/Internal/Core/Rules.hs +6/−6
- src/Development/Shake/Internal/Core/Run.hs +6/−0
- src/Development/Shake/Internal/Core/Types.hs +9/−5
- src/General/TypeMap.hs +9/−2
CHANGES.txt view
@@ -1,5 +1,8 @@ Changelog for Shake (* = breaking change) +0.17.3, released 2018-12-04+ #632, remove O(n^2) behaviour when constructing user rules+ In diagnostic mode, show the number of actions/rules/user rules 0.17.2, released 2018-11-29 Make needHasChanged work even between runs 0.17.1, released 2018-11-14
shake.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.18 build-type: Simple name: shake-version: 0.17.2+version: 0.17.3 license: BSD3 license-file: LICENSE category: Development, Shake
src/Development/Shake/Internal/Args.hs view
@@ -100,6 +100,7 @@ -- be @[]@. -- -- * @argValues@ is a list of non-flag arguments, which are often treated as files and passed to 'want'.+-- If arguments are specified then typically the 'want' calls from the rules are discarded using 'withoutActions'. -- -- * @result@ should produce a 'Nothing' to indicate that no building needs to take place, or a 'Just' -- providing the rules that should be used.@@ -113,12 +114,14 @@ -- flags = [Option \"\" [\"distcc\"] (NoArg $ Right DistCC) \"Run distributed.\"] -- -- main = 'shakeArgsWith' 'shakeOptions' flags $ \\flags targets -> return $ Just $ do--- if null targets then 'want' [\"result.exe\"] else 'want' targets -- let compiler = if DistCC \`elem\` flags then \"distcc\" else \"gcc\"--- \"*.o\" '%>' \\out -> do--- 'need' ...--- 'cmd' compiler ...--- ...+-- let rules = do+-- \"*.o\" '%>' \\out -> do+-- 'need' ...+-- 'cmd' compiler ...+-- 'want' [\"target.exe\"]+-- ...+-- if null targets then rules else 'want' targets >> 'withoutActions' rules -- @ -- -- Now you can pass @--distcc@ to use the @distcc@ compiler.
src/Development/Shake/Internal/Core/Action.hs view
@@ -354,7 +354,7 @@ historyDisable = Action $ modifyRW $ \s -> s{localHistory = False} --- | This rule the following files, in addition to any defined by its target.+-- | This rule builds the following files, in addition to any defined by its target. -- At the end of the rule these files must have been written. produces :: [FilePath] -> Action () produces xs = Action $ modifyRW $ \s -> s{localProduces = map (True,) (reverse xs) ++ localProduces s}
src/Development/Shake/Internal/Core/Rules.hs view
@@ -115,8 +115,8 @@ newRules :: SRules -> Rules () newRules x = Rules $ liftIO . flip modifyIORef' (<> x) =<< asks snd -modifyRules :: (SRules -> SRules) -> Rules a -> Rules a-modifyRules f (Rules r) = Rules $ do+modifyRulesScoped :: (SRules -> SRules) -> Rules a -> Rules a+modifyRulesScoped f (Rules r) = Rules $ do (opts, refOld) <- ask liftIO $ do refNew <- newIORef mempty@@ -227,7 +227,7 @@ -- 'priority' p1 (r1 >> r2) === 'priority' p1 r1 >> 'priority' p1 r2 -- @ priority :: Double -> Rules a -> Rules a-priority d = modifyRules $ \s -> s{userRules = TMap.map (\(UserRuleVersioned b x) -> UserRuleVersioned b $ Priority d x) $ userRules s}+priority d = modifyRulesScoped $ \s -> s{userRules = TMap.map (\(UserRuleVersioned b x) -> UserRuleVersioned b $ Priority d x) $ userRules s} -- | Indicate that the nested rules have a given version. If you change the semantics of the rule then updating (or adding)@@ -241,7 +241,7 @@ -- You should only use 'versioned' to track changes in the build source, for standard runtime dependencies you should use -- other mechanisms, e.g. 'Development.Shake.addOracle'. versioned :: Int -> Rules a -> Rules a-versioned v = modifyRules $ \s -> s+versioned v = modifyRulesScoped $ \s -> s {userRules = TMap.map (\(UserRuleVersioned b x) -> UserRuleVersioned (b || v /= 0) $ Versioned (Ver v) x) $ userRules s ,builtinRules = Map.map (\b -> b{builtinVersion = Ver v}) $ builtinRules s }@@ -260,7 +260,7 @@ -- Inside 'alternatives' the 'priority' of each rule is not used to determine which rule matches, -- but the resulting match uses that priority compared to the rules outside the 'alternatives' block. alternatives :: Rules a -> Rules a-alternatives = modifyRules $ \r -> r{userRules = TMap.map (\(UserRuleVersioned b x) -> UserRuleVersioned b $ Alternative x) $ userRules r}+alternatives = modifyRulesScoped $ \r -> r{userRules = TMap.map (\(UserRuleVersioned b x) -> UserRuleVersioned b $ Alternative x) $ userRules r} -- | Run an action, usually used for specifying top-level requirements.@@ -287,4 +287,4 @@ -- | Remove all actions specified in a set of rules, usually used for implementing -- command line specification of what to build. withoutActions :: Rules a -> Rules a-withoutActions = modifyRules $ \x -> x{actions=mempty}+withoutActions = modifyRulesScoped $ \x -> x{actions=mempty}
src/Development/Shake/Internal/Core/Run.hs view
@@ -73,6 +73,12 @@ open cleanup opts rs = withInit opts $ \opts@ShakeOptions{..} diagnostic _ -> do diagnostic $ return "Starting run" (actions, ruleinfo, userRules) <- runRules opts rs++ diagnostic $ return $ "Number of actions = " ++ show (length actions)+ diagnostic $ return $ "Number of builtin rules = " ++ show (Map.size ruleinfo) ++ " " ++ show (Map.keys ruleinfo)+ diagnostic $ return $ "Number of user rule types = " ++ show (TMap.size userRules)+ diagnostic $ return $ "Number of user rules = " ++ show (sum (TMap.toList (userRuleSize . userRuleContents) userRules))+ checkShakeExtra shakeExtra curdir <- getCurrentDirectory
src/Development/Shake/Internal/Core/Types.hs view
@@ -5,7 +5,7 @@ module Development.Shake.Internal.Core.Types( BuiltinRun, BuiltinLint, BuiltinIdentity, RunMode(..), RunResult(..), RunChanged(..),- UserRule(..), UserRuleVersioned(..),+ UserRule(..), UserRuleVersioned(..), userRuleSize, BuiltinRule(..), Global(..), Local(..), Action(..), runAction, addDiscount, newLocal, localClearMutable, localMergeMutable, Stack, Step(..), Result(..), Database(..), Depends(..), Status(..), Trace(..), BS_Store,@@ -364,14 +364,18 @@ mappend = (<>) instance Semigroup (UserRule a) where- x <> y = Unordered $ fromUnordered x ++ fromUnordered y- where- fromUnordered (Unordered xs) = xs- fromUnordered x = [x]+ x <> y = Unordered [x,y] instance Monoid (UserRule a) where mempty = Unordered [] mappend = (<>)++userRuleSize :: UserRule a -> Int+userRuleSize UserRule{} = 1+userRuleSize (Unordered xs) = sum $ map userRuleSize xs+userRuleSize (Priority _ x) = userRuleSize x+userRuleSize (Alternative x) = userRuleSize x+userRuleSize (Versioned _ x) = userRuleSize x -- | Invariant: The database does not have any cycles where a Key depends on itself.
src/General/TypeMap.hs view
@@ -1,17 +1,18 @@ {-# LANGUAGE ExistentialQuantification, ConstraintKinds, KindSignatures, GADTs, ScopedTypeVariables, Rank2Types #-} module General.TypeMap(- Map, empty, singleton, insert, map, lookup, unionWith+ Map, empty, singleton, insert, map, lookup, unionWith, toList, size ) where import qualified Data.HashMap.Strict as Map import Data.Typeable.Extra import Unsafe.Coerce import Data.Functor+import qualified Prelude import Prelude hiding (lookup, map) -data F f = forall a . F (f a)+data F f = forall a . F !(f a) unF :: F f -> f a unF x = case x of F x -> unsafeCoerce x@@ -35,3 +36,9 @@ map :: (forall a . f1 a -> f2 a) -> Map f1 -> Map f2 map f (Map mp) = Map $ Map.map (\(F a) -> F $ f a) mp++toList :: (forall a . f a -> b) -> Map f -> [b]+toList f (Map mp) = Prelude.map (\(F a) -> f a) $ Map.elems mp++size :: Map f -> Int+size (Map mp) = Map.size mp