shake 0.13 → 0.13.1
raw patch · 11 files changed
+99/−50 lines, 11 filesdep ~deepseqdep ~hashabledep ~transformers
Dependency ranges changed: deepseq, hashable, transformers, unordered-containers
Files
- CHANGES.txt +4/−0
- Development/Shake/Core.hs +1/−1
- Development/Shake/Report.hs +47/−22
- Development/Shake/Rules/File.hs +3/−2
- Development/Shake/Rules/Files.hs +1/−0
- Development/Shake/Types.hs +15/−10
- Examples/Ninja/Main.hs +8/−0
- Examples/Ninja/nocreate.ninja +5/−0
- Examples/Test/Docs.hs +1/−1
- Start.hs +1/−1
- shake.cabal +13/−13
CHANGES.txt view
@@ -1,5 +1,9 @@ Changelog for Shake +0.13.1+ Remove all package upper bounds+ #126, Ninja compatibility if Ninja fails to create a file+ #123, generate Chrome compatible traces 0.13 #122, make --report=- write a report to stdout Improve the profile report summary
Development/Shake/Core.hs view
@@ -376,7 +376,7 @@ forM_ shakeReport $ \file -> do when (shakeVerbosity >= Normal) $ output Normal $ "Writing report to " ++ file- buildReport report file+ buildReport file report maybe (return ()) (throwIO . snd) =<< readIORef except sequence_ . reverse =<< readIORef after
Development/Shake/Report.hs view
@@ -21,17 +21,13 @@ -- | Generates an report given some build system profiling data.-buildReport :: [ReportEntry] -> FilePath -> IO ()-buildReport reports out- | takeExtension out == ".js" = writeFile out $ "var shake = \n" ++ showJSON reports- | takeExtension out == ".json" = writeFile out $ showJSON reports- | out == "-" = putStr $ unlines $ reportSummary reports- | otherwise = do- htmlDir <- getDataFileName "html"- report <- LBS.readFile $ htmlDir </> "report.html"- let f name | name == "data.js" = return $ LBS.pack $ "var shake = \n" ++ showJSON reports- | otherwise = LBS.readFile $ htmlDir </> name- LBS.writeFile out =<< runTemplate f report+buildReport :: FilePath -> [ReportEntry] -> IO ()+buildReport out xs+ | takeExtension out == ".js" = writeFile out $ "var shake = \n" ++ reportJSON xs+ | takeExtension out == ".json" = writeFile out $ reportJSON xs+ | takeExtension out == ".trace" = writeFile out $ reportTrace xs+ | out == "-" = putStr $ unlines $ reportSummary xs+ | otherwise = LBS.writeFile out =<< reportHTML xs reportSummary :: [ReportEntry] -> [String]@@ -52,19 +48,48 @@ where ls = filter ((==) 0 . repBuilt) xs -showJSON :: [ReportEntry] -> String-showJSON xs = "[" ++ intercalate "\n," (map showEntry xs) ++ "\n]"+reportHTML :: [ReportEntry] -> IO LBS.ByteString+reportHTML xs = do+ htmlDir <- getDataFileName "html"+ report <- LBS.readFile $ htmlDir </> "report.html"+ let f name | name == "data.js" = return $ LBS.pack $ "var shake = \n" ++ reportJSON xs+ | otherwise = LBS.readFile $ htmlDir </> name+ runTemplate f report+++reportTrace :: [ReportEntry] -> String+reportTrace xs = jsonListLines $+ showEntries 0 [y{repCommand=repName x} | x <- xs, y <- repTraces x] +++ showEntries 1 (concatMap repTraces xs) where- showEntry ReportEntry{..} = (\xs -> "{" ++ intercalate ", " xs ++ "}") $- ["\"name\":" ++ show repName- ,"\"built\":" ++ show repBuilt- ,"\"changed\":" ++ show repChanged- ,"\"depends\":" ++ show repDepends- ,"\"execution\":" ++ show repExecution] ++- ["\"traces\":[" ++ intercalate "," (map showTrace repTraces) ++ "]" | not $ null repTraces]- showTrace ReportTrace{..} =- "{\"command\":" ++ show repCommand ++ ",\"start\":" ++ show repStart ++ ",\"stop\":" ++ show repStop ++ "}"+ showEntries pid xs = map (showEntry pid) $ snd $ mapAccumL alloc [] $ sortBy (compare `on` repStart) xs+ alloc as r | (a1,an:a2) <- break (\a -> repStop a <= repStart r) as = (a1++r:a2, (length a1,r))+ | otherwise = (as++[r], (length as,r))+ showEntry pid (tid, ReportTrace{..}) = jsonObject+ [("args","{}"), ("ph",show "X"), ("cat",show "target")+ ,("name",show repCommand), ("tid",show tid), ("pid",show pid)+ ,("ts",show $ 1000000*repStart), ("dur",show $ 1000000*(repStop-repStart))] ++reportJSON :: [ReportEntry] -> String+reportJSON = jsonListLines . map showEntry+ where+ showEntry ReportEntry{..} = jsonObject $+ [("name", show repName)+ ,("built", show repBuilt)+ ,("changed", show repChanged)+ ,("depends", show repDepends)+ ,("execution", show repExecution)] +++ [("traces", jsonList $ map showTrace repTraces) | not $ null repTraces]+ showTrace ReportTrace{..} = jsonObject+ [("command",show repCommand), ("start",show repStart), ("stop",show repStop)]++jsonListLines xs = "[" ++ intercalate "\n," xs ++ "\n]"+jsonList xs = "[" ++ intercalate "," xs ++ "]"+jsonObject xs = "{" ++ intercalate ", " [show a ++ ":" ++ b | (a,b) <- xs] ++ "}"++---------------------------------------------------------------------+-- TEMPLATE ENGINE -- | Template Engine. Perform the following replacements on a line basis: --
Development/Shake/Rules/File.hs view
@@ -79,8 +79,9 @@ where bool b = if b then EqualCheap else NotEqual storedValueError :: ShakeOptions -> Bool -> String -> FileQ -> IO FileA-storedValueError opts input msg x = fromMaybe (error err) <$> storedValue opts2 x- where err = msg ++ "\n " ++ unpackU (fromFileQ x)+storedValueError opts input msg x = fromMaybe def <$> storedValue opts2 x+ where def = if shakeCreationCheck opts || input then error err else FileA fileInfoNeq fileInfoNeq fileInfoNeq+ err = msg ++ "\n " ++ unpackU (fromFileQ x) opts2 = if not input && shakeChange opts == ChangeModtimeAndDigestInput then opts{shakeChange=ChangeModtime} else opts
Development/Shake/Rules/Files.hs view
@@ -137,6 +137,7 @@ ys <- liftIO $ mapM (storedValue opts) xs case sequence ys of Just ys -> return $ FilesA ys+ Nothing | not $ shakeCreationCheck opts -> return $ FilesA [] Nothing -> do let missing = length $ filter isNothing ys error $ "Error, " ++ name ++ " rule failed to build " ++ show missing ++
Development/Shake/Types.hs view
@@ -96,9 +96,10 @@ -- ^ Defaults to 'False'. Operate in staunch mode, where building continues even after errors, -- similar to @make --keep-going@. ,shakeReport :: [FilePath]- -- ^ Defaults to '[]'. Write a profiling report to a file, showing which rules rebuilt,+ -- ^ Defaults to @[]@. Write a 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.- -- If the file extension is @.json@ it will write JSON data, if @.js@ it will write Javascript,+ -- If the file extension is @.json@ it will write JSON data; if @.js@ it will write Javascript;+ -- if @.trace@ it will write trace events (load into @about:\/\/tracing@ in Chrome); -- otherwise it will write HTML. ,shakeLint :: Maybe Lint -- ^ Defaults to 'Nothing'. Perform sanity checks during building, see 'Lint' for details.@@ -124,6 +125,9 @@ -- are not used. Useful for profiling the non-command portion of the build system. ,shakeChange :: Change -- ^ Default to 'ChangeModtime'. How to check if a file has changed, see 'Change' for details.+ ,shakeCreationCheck :: Bool+ -- ^ Default to 'True'. After running a rule to create a file, is it an error if the file does not exist.+ -- Provided for compatibility with @make@ and @ninja@ (which have ugly file creation semantics). ,shakeProgress :: IO Progress -> IO () -- ^ Defaults to no action. A function called when the build starts, allowing progress to be reported. -- The function is called on a separate thread, and that thread is killed when the build completes.@@ -138,24 +142,25 @@ -- | The default set of 'ShakeOptions'. shakeOptions :: ShakeOptions-shakeOptions = ShakeOptions ".shake" 1 "1" Normal False [] Nothing (Just 10) Nothing [] False True False True ChangeModtime+shakeOptions = ShakeOptions ".shake" 1 "1" Normal False [] Nothing (Just 10) Nothing [] False True False True ChangeModtime True (const $ return ()) (const $ BS.putStrLn . BS.pack) -- try and output atomically using BS fieldsShakeOptions = ["shakeFiles", "shakeThreads", "shakeVersion", "shakeVerbosity", "shakeStaunch", "shakeReport" ,"shakeLint", "shakeFlush", "shakeAssume", "shakeAbbreviations", "shakeStorageLog"- ,"shakeLineBuffering", "shakeTimings", "shakeRunCommands", "shakeChange", "shakeProgress", "shakeOutput"]+ ,"shakeLineBuffering", "shakeTimings", "shakeRunCommands", "shakeChange", "shakeCreationCheck"+ ,"shakeProgress", "shakeOutput"] tyShakeOptions = mkDataType "Development.Shake.Types.ShakeOptions" [conShakeOptions] conShakeOptions = mkConstr tyShakeOptions "ShakeOptions" fieldsShakeOptions Prefix-unhide x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 =- ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 (fromFunction x16) (fromFunction x17)+unhide x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 =+ ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 (fromFunction x17) (fromFunction x18) instance Data ShakeOptions where- gfoldl k z (ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17) =- z unhide `k` x1 `k` x2 `k` x3 `k` x4 `k` x5 `k` x6 `k` x7 `k` x8 `k` x9 `k` x10 `k` x11 `k` x12 `k` x13 `k` x14 `k` x15 `k`- Function x16 `k` Function x17- gunfold k z c = k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ z unhide+ gfoldl k z (ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18) =+ z unhide `k` x1 `k` x2 `k` x3 `k` x4 `k` x5 `k` x6 `k` x7 `k` x8 `k` x9 `k` x10 `k` x11 `k` x12 `k` x13 `k` x14 `k` x15 `k` x16 `k`+ Function x17 `k` Function x18+ gunfold k z c = k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ z unhide toConstr ShakeOptions{} = conShakeOptions dataTypeOf _ = tyShakeOptions
Examples/Ninja/Main.hs view
@@ -51,6 +51,14 @@ run "-f../../Examples/Ninja/test5.ninja" assertExists $ obj "output file" + writeFile (obj "nocreate.log") ""+ writeFile (obj "nocreate.in") ""+ run "-f../../Examples/Ninja/nocreate.ninja"+ assertNonSpace (obj "nocreate.log") "x"+ run "-f../../Examples/Ninja/nocreate.ninja"+ run "-f../../Examples/Ninja/nocreate.ninja"+ assertNonSpace (obj "nocreate.log") "xxx"+ writeFile (obj "input") "" runFail "-f../../Examples/Ninja/lint.ninja bad --lint" "'needed' file required rebuilding" run "-f../../Examples/Ninja/lint.ninja good --lint"
+ Examples/Ninja/nocreate.ninja view
@@ -0,0 +1,5 @@++rule gen+ command = echo x >> nocreate.log++build nocreate.out: gen nocreate.in
Examples/Test/Docs.hs view
@@ -204,7 +204,7 @@ ".. /./ /.. ./ // \\ ../ " ++ "ConstraintKinds GeneralizedNewtypeDeriving DeriveDataTypeable SetConsoleTitle " ++ "Data.List System.Directory Development.Shake.FilePath main.m run .rot13 " ++- "NoProgress Error src rot13 .js .json " +++ "NoProgress Error src rot13 .js .json .trace about://tracing " ++ ".make/i586-linux-gcc/output _make/.database foo/.. file.src file.out build " ++ "/usr/special /usr/special/userbinary $CFLAGS %PATH% -O2 -j8 -j -j1 " ++ "-threaded -rtsopts -I0 Function extension $OUT $C_LINK_FLAGS $PATH xterm $TERM main opts result flagValues argValues " ++
Start.hs view
@@ -17,7 +17,7 @@ resetTimings args <- getArgs withArgs ("--no-time":args) $- shakeArgsWith shakeOptions flags $ \opts targets -> do+ shakeArgsWith shakeOptions{shakeCreationCheck=False} flags $ \opts targets -> do let tool = listToMaybe [x | Tool x <- opts] makefile <- case reverse [x | UseMakefile x <- opts] of x:_ -> return x
shake.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.10 build-type: Simple name: shake-version: 0.13+version: 0.13.1 license: BSD3 license-file: LICENSE category: Development@@ -83,17 +83,17 @@ base == 4.*, old-time, directory,- hashable >= 1.1.2.3 && < 1.3,+ hashable >= 1.1.2.3, binary, filepath, process >= 1.1,- unordered-containers >= 0.2.1 && < 0.3,+ unordered-containers >= 0.2.1, bytestring, utf8-string >= 0.3, time, random,- transformers >= 0.2 && < 0.4,- deepseq >= 1.1 && < 1.4+ transformers >= 0.2,+ deepseq >= 1.1 if flag(portable) cpp-options: -DPORTABLE@@ -155,17 +155,17 @@ base == 4.*, old-time, directory,- hashable >= 1.1.2.3 && < 1.3,+ hashable >= 1.1.2.3, binary, filepath, process >= 1.1,- unordered-containers >= 0.2.1 && < 0.3,+ unordered-containers >= 0.2.1, bytestring, utf8-string >= 0.3, time, random,- transformers >= 0.2 && < 0.4,- deepseq >= 1.1 && < 1.4+ transformers >= 0.2,+ deepseq >= 1.1 if flag(portable) cpp-options: -DPORTABLE@@ -192,17 +192,17 @@ base == 4.*, old-time, directory,- hashable >= 1.1.2.3 && < 1.3,+ hashable >= 1.1.2.3, binary, filepath, process >= 1.1,- unordered-containers >= 0.2.1 && < 0.3,+ unordered-containers >= 0.2.1, bytestring, utf8-string >= 0.3, time, random,- transformers >= 0.2 && < 0.4,- deepseq >= 1.1 && < 1.4,+ transformers >= 0.2,+ deepseq >= 1.1, QuickCheck >= 2.0 if flag(portable)