shake 0.11 → 0.11.1
raw patch · 13 files changed
+152/−21 lines, 13 files
Files
- CHANGES.txt +4/−0
- Development/Make/Parse.hs +2/−1
- Development/Ninja/All.hs +1/−1
- Development/Ninja/Env.hs +4/−1
- Development/Ninja/Lexer.hs +2/−2
- Development/Ninja/Parse.hs +2/−2
- Development/Shake/Config.hs +80/−0
- Development/Shake/Core.hs +2/−2
- Development/Shake/Types.hs +1/−3
- Examples/Test/Config.hs +41/−0
- Examples/Test/Docs.hs +3/−3
- Test.hs +3/−1
- shake.cabal +7/−5
CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Shake +0.11.1+ #94, GHC 7.8 support+ Add a Config module+ #89, support :: as a build rule separator 0.11 Add alternatives to allow overlapping rules Make storedValue take a ShakeOptions structure
Development/Make/Parse.hs view
@@ -5,6 +5,7 @@ import Development.Make.Type import Data.Char import Data.List +import Data.Maybe trim = dropWhile isSpace . reverse . dropWhile isSpace . reverse @@ -44,7 +45,7 @@ | (a,':':b) <- break (== ':') x = case b of '=':b -> Assign (trim a) ColonEquals (parseExpr $ trim b) ':':'=':b -> Assign (trim a) ColonEquals (parseExpr $ trim b) - _ -> Rule (parseExpr $ trim a) (parseExpr $ trim b) [] + _ -> Rule (parseExpr $ trim a) (parseExpr $ trim $ fromMaybe b $ stripPrefix ":" b) [] | otherwise = error $ "Invalid statement: " ++ x
Development/Ninja/All.hs view
@@ -26,7 +26,7 @@ runNinja :: FilePath -> [String] -> IO (Rules ()) runNinja file args = do addTiming "Ninja parse" - ninja@Ninja{..} <- parse file + ninja@Ninja{..} <- parse file =<< newEnv return $ do needDeps <- return $ needDeps ninja -- partial application phonys <- return $ Map.fromList phonys
Development/Ninja/Env.hs view
@@ -2,7 +2,7 @@ -- | A Ninja style environment, basically a linked-list of mutable hash tables. module Development.Ninja.Env(- Env, newEnv, scopeEnv, addEnv, askEnv+ Env, newEnv, scopeEnv, addEnv, askEnv, fromEnv ) where import qualified Data.HashMap.Strict as Map@@ -34,3 +34,6 @@ Just v -> return $ Just v Nothing | Just e <- e -> askEnv e k _ -> return Nothing++fromEnv :: Env k v -> IO (Map.HashMap k v)+fromEnv (Env ref _) = readIORef ref
Development/Ninja/Lexer.hs view
@@ -44,7 +44,7 @@ return $! Ptr end `minusPtr` start go s@(Ptr a) | c == '\0' || f c = a- | otherwise = go $ inc s+ | otherwise = go (inc s) where c = chr s {-# INLINE break00 #-}@@ -58,7 +58,7 @@ return $! Ptr end `minusPtr` start go s@(Ptr a) | f c = a- | otherwise = go $ inc s+ | otherwise = go (inc s) where c = chr s head0 :: Str0 -> Char
Development/Ninja/Parse.hs view
@@ -9,8 +9,8 @@ import Control.Monad -parse :: FilePath -> IO Ninja -parse file = do env <- newEnv; parseFile file env newNinja +parse :: FilePath -> Env Str Str -> IO Ninja +parse file env = parseFile file env newNinja parseFile :: FilePath -> Env Str Str -> Ninja -> IO Ninja
+ Development/Shake/Config.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}++-- | A module for parsing and using config files in a Shake build system. Config files+-- consist of variable bindings, for example:+--+-- > # This is my Config file+-- > HEADERS_DIR = /path/to/dir+-- > CFLAGS = -g -I${HEADERS_DIR}+-- > CFLAGS = $CFLAGS -O2+-- > include extra/file.cfg+--+-- This defines the variable @HEADERS_DIR@ (equal to @\/path\/to\/dir@), and+-- @CFLAGS@ (equal to @-g -I\/path\/to\/dir -O2@), and also includes the configuration+-- statements in the file @extra/file.cfg@. The full lexical syntax for configuration+-- files is defined here: <http://martine.github.io/ninja/manual.html#_lexical_syntax>.+--+-- To use the configuration file either use 'readConfigFile' to parse the configuration file+-- and use the values directly, or 'usingConfigFile' and 'getConfig' to track the configuration+-- values, so they become build dependencies.+module Development.Shake.Config(+ readConfigFile,+ usingConfigFile, usingConfig,+ getConfig+ ) where++import Development.Shake+import Development.Shake.Classes+import qualified Development.Ninja.Parse as Ninja+import qualified Development.Ninja.Env as Ninja+import qualified Data.HashMap.Strict as Map+import qualified Data.ByteString.UTF8 as UTF8+import Control.Applicative+import Control.Arrow+++-- | Read a config file, returning a list of the variables and their bindings.+-- Config files use the Ninja lexical syntax:+-- <http://martine.github.io/ninja/manual.html#_lexical_syntax>+readConfigFile :: FilePath -> IO (Map.HashMap String String)+readConfigFile file = do+ env <- Ninja.newEnv+ Ninja.parse file env+ mp <- Ninja.fromEnv env+ return $ Map.fromList $ map (UTF8.toString *** UTF8.toString) $ Map.toList mp+++newtype Config = Config String deriving (Show,Typeable,Eq,Hashable,Binary,NFData)+++-- | Specify the file to use with 'getConfig'.+usingConfigFile :: FilePath -> Rules ()+usingConfigFile file = do+ mp <- newCache $ \() -> liftIO $ readConfigFile file+ addOracle $ \(Config x) -> Map.lookup x <$> mp ()+ return ()+++-- | Specify the values to use with 'getConfig', generally prefer+-- 'usingConfigFile' unless you also need access to the values+-- of variables outside 'Action'.+usingConfig :: Map.HashMap String String -> Rules ()+usingConfig mp = do+ addOracle $ \(Config x) -> return $ Map.lookup x mp+ return ()+++-- | Obtain the value of a configuration variable, returns 'Nothing' to indicate the variable+-- has no binding. Any build system using 'getConfig' /must/ call either 'usingConfigFile'+-- or 'usingConfig'. The 'getConfig' function will introduce a dependency on the configuration+-- variable (but not the whole configuration file), and if the configuration variable changes, the rule will be rerun.+-- As an example:+--+-- @+-- 'usingConfigFile' \"myconfiguration.cfg\"+-- \"*.o\" '*>' \\out -> do+-- cflags <- 'getConfig' \"CFLAGS\"+-- 'cmd' \"gcc\" [out '-<.>' \"c\"] (fromMaybe \"\" cflags)+-- @+getConfig :: String -> Action (Maybe String)+getConfig = askOracle . Config
Development/Shake/Core.hs view
@@ -95,7 +95,7 @@ ruleValue = err "ruleValue" --- | Define a set of rules. Rules can be created with calls to functions such as '*>' or 'action'. Rules are combined+-- | Define a set of rules. Rules can be created with calls to functions such as 'Development.Shake.*>' or 'action'. Rules are combined -- with either the 'Monoid' instance, or (more commonly) the 'Monad' instance and @do@ notation. To define your own -- custom types of rule, see "Development.Shake.Rule". newtype Rules a = Rules (WriterT SRules IO a) -- All IO must be associative/commutative (e.g. creating IORef/MVars)@@ -772,7 +772,7 @@ -- digits \<- 'newCache' $ \\file -> do -- src \<- readFile\' file -- return $ length $ filter isDigit src--- \"*.digits\" '*>' \\x -> do+-- \"*.digits\" 'Development.Shake.*>' \\x -> do -- v1 \<- digits ('dropExtension' x) -- v2 \<- digits ('dropExtension' x) -- 'Development.Shake.writeFile'' x $ show (v1,v2)
Development/Shake/Types.hs view
@@ -97,9 +97,7 @@ -- ^ Defaults to 'Nothing'. Write an HTML profiling report to a file, showing which -- rules rebuilt, why, and how much time they took. Useful for improving the speed of your build systems. ,shakeLint :: Maybe Lint- -- ^ Defaults to 'False'. Perform basic sanity checks during building, checking the current directory- -- is not modified and that output files are not modified by multiple rules.- -- These sanity checks do not check for missing or redundant dependencies.+ -- ^ Defaults to 'Nothing'. Perform sanity checks during building, see 'Lint' for details. ,shakeFlush :: Maybe Double -- ^ Defaults to @'Just' 10@. How often to flush Shake metadata files in seconds, or 'Nothing' to never flush explicitly. -- It is possible that on abnormal termination (not Haskell exceptions) any rules that completed in the last
+ Examples/Test/Config.hs view
@@ -0,0 +1,41 @@++module Examples.Test.Config(main) where++import Development.Shake+import Development.Shake.FilePath+import Development.Shake.Config+import Examples.Util+import Data.Char+import Data.Maybe+import System.Directory+++main = shaken test $ \args obj -> do+ want $ map obj ["hsflags.var","cflags.var","none.var"]+ usingConfigFile $ obj "config"+ obj "*.var" *> \out -> do+ cfg <- getConfig $ map toUpper $ takeBaseName out+ liftIO $ appendFile (out -<.> "times") "X"+ writeFile' out $ fromMaybe "" cfg+++test build obj = do+ build ["clean"]+ createDirectoryIfMissing True $ obj ""+ writeFile (obj "config") $ unlines+ ["HEADERS_DIR = /path/to/dir"+ ,"CFLAGS = -O2 -I${HEADERS_DIR} -g"+ ,"HSFLAGS = -O2"]+ build []+ assertContents (obj "cflags.var") "-O2 -I/path/to/dir -g"+ assertContents (obj "hsflags.var") "-O2"+ assertContents (obj "none.var") ""++ appendFile (obj "config") $ unlines+ ["CFLAGS = $CFLAGS -w"]+ build []+ assertContents (obj "cflags.var") "-O2 -I/path/to/dir -g -w"+ assertContents (obj "hsflags.var") "-O2"+ assertContents (obj "cflags.times") "XX"+ assertContents (obj "hsflags.times") "X"+ assertContents (obj "none.times") "X"
Examples/Test/Docs.hs view
@@ -21,7 +21,7 @@ want $ map (\x -> fromMaybe (obj x) $ stripPrefix "!" x) args - let needSource = need =<< getDirectoryFiles "." ["Development/Shake.hs","Development/Shake//*.hs","General//*.hs"]+ let needSource = need =<< getDirectoryFiles "." ["Development/Shake.hs","Development/Shake//*.hs","Development/Ninja/*.hs","General//*.hs"] index *> \_ -> do needSource@@ -89,7 +89,7 @@ obj "Files.lst" *> \out -> do need [index,obj "Paths_shake.hs"] files <- getDirectoryFiles "dist/doc/html/shake" ["Development-*.html"]- files <- return $ filter (not . isSuffixOf "-Classes.html") files+ files <- return $ filter (\x -> not ("-Classes.html" `isSuffixOf` x) && not ("Config.html" `isSuffixOf` x)) files writeFileLines out $ map ((++) "Part_" . reps '-' '_' . takeBaseName) files let needModules = do mods <- readFileLines $ obj "Files.lst"; need [obj m <.> "hs" | m <- mods]; return mods@@ -192,6 +192,6 @@ types = words $ "MVar IO Monad Monoid String FilePath Data [String] Eq Typeable Char ExitCode " ++- "Action Resource Assume FilePattern Verbosity Rules Rule CmdOption CmdResult Int Double"+ "Action Resource Assume FilePattern Lint Verbosity Rules Rule CmdOption CmdResult Int Double" dupes = words "main progressSimple rules"
Test.hs view
@@ -24,6 +24,7 @@ import qualified Examples.Test.Benchmark as Benchmark import qualified Examples.Test.Cache as Cache import qualified Examples.Test.Command as Command+import qualified Examples.Test.Config as Config import qualified Examples.Test.Directory as Directory import qualified Examples.Test.Docs as Docs import qualified Examples.Test.Errors as Errors@@ -51,7 +52,8 @@ where (*) = (,) mains = ["tar" * Tar.main, "self" * Self.main, "c" * C.main- ,"basic" * Basic.main, "cache" * Cache.main, "command" * Command.main, "directory" * Directory.main+ ,"basic" * Basic.main, "cache" * Cache.main, "command" * Command.main+ ,"config" * Config.main, "directory" * Directory.main ,"docs" * Docs.main, "errors" * Errors.main, "orderonly" * OrderOnly.main ,"filepath" * FilePath.main, "filepattern" * FilePattern.main, "files" * Files.main ,"journal" * Journal.main, "lint" * Lint.main, "makefile" * Makefile.main
shake.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.10 build-type: Simple name: shake-version: 0.11+version: 0.11.1 license: BSD3 license-file: LICENSE category: Development@@ -90,12 +90,17 @@ Development.Shake Development.Shake.Classes Development.Shake.Command+ Development.Shake.Config Development.Shake.FilePath Development.Shake.Rule Development.Shake.Sys Development.Shake.Util other-modules:+ Development.Ninja.Env+ Development.Ninja.Lexer+ Development.Ninja.Parse+ Development.Ninja.Type Development.Shake.Args Development.Shake.ByteString Development.Shake.Core@@ -160,10 +165,6 @@ Development.Make.Rules Development.Make.Type Development.Ninja.All- Development.Ninja.Env- Development.Ninja.Lexer- Development.Ninja.Parse- Development.Ninja.Type Start @@ -214,6 +215,7 @@ Examples.Test.Benchmark Examples.Test.Cache Examples.Test.Command+ Examples.Test.Config Examples.Test.Directory Examples.Test.Docs Examples.Test.Errors