gipeda-0.1: src/Shake.hs
{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
module Shake where
import Prelude hiding ((*>))
import Development.Shake
import Development.Shake.FilePath
import Development.Shake.Classes
import Control.Monad
import qualified Data.Map as M
import Data.Functor
import Data.List
import Paths hiding (Hash)
import ParentMap
import BenchmarksInCSV
import qualified BenchmarkSettings as S
{- Global settings -}
cGRAPH_HISTORY :: Integer
cGRAPH_HISTORY = 50
git :: (CmdResult b) => String -> [String] -> Action b
git gitcmd args = do
cmd (Traced $ "git " ++ gitcmd) (words "git -C repository" ++ gitcmd : args)
self :: (CmdResult b) => String -> [String] -> Action b
self name args = do
-- orderOnly ["gipeda"]
cmd (Traced name) "./gipeda" name args
gitRange :: Action String
gitRange = do
s <- liftIO $ S.readSettings "settings.yaml"
let first = S.start s
[head] <- readFileLines "site/out/head.txt"
return $ first ++ ".." ++ head
needIfThere :: [FilePath] -> Action [FilePath]
needIfThere files = do
existing <- filterM doesFileExist files
need existing
return existing
findPred, findPredOrSelf :: ParentMap -> Hash -> Action (Maybe Hash)
findPredOrSelf m h = do
ex <- doesFileExist (logsOf h)
if ex then return (Just h)
else findPred m h
findPred m h = case M.lookup h m of
Just h' -> findPredOrSelf m h'
Nothing -> return Nothing
findRecent :: ParentMap -> Integer -> FilePath -> Action [FilePath]
findRecent _ 0 _ = return []
findRecent m n h = do
pM <- findPred m h
(h:) <$> case pM of
Nothing -> return []
Just p -> findRecent m (n-1) p
newtype LimitRecent = LimitRecent ()
deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
shakeMain :: IO ()
shakeMain = shakeArgs shakeOptions $ do
{-
"gipeda" *> \out -> do
sources <- getDirectoryFiles "src" ["*.hs"]
need (map ("src" </>) sources)
cmd "ghc -isrc --make -O src/gipeda.hs -o" out
want ["gipeda"]
-}
getLimitRecent <- addOracle $ \(LimitRecent _) -> do
need ["settings.yaml"]
S.limitRecent <$> liftIO (S.readSettings "settings.yaml")
"reports" ~> do
range <- gitRange
Stdout range <- git "log" ["--format=%H",range]
let hashes = words range
withLogs <- filterM (doesFileExist . logsOf) hashes
need $ map reportOf withLogs
want ["reports"]
"summaries" ~> do
range <- gitRange
Stdout range <- git "log" ["--format=%H",range]
let hashes = words range
withLogs <- filterM (doesFileExist . logsOf) hashes
need $ map summaryOf withLogs
want ["summaries"]
"site/out/head.txt" *> \ out -> do
alwaysRerun
Stdout stdout <- git "rev-parse" ["master"]
writeFileChanged out stdout
"site/out/history.csv" *> \out -> do
range <- gitRange
Stdout stdout <- git "log" ["--format=%H;%P",range]
writeFileChanged out stdout
want ["site/out/history.csv"]
history' <- newCache $ \() -> do
orderOnly ["site/out/history.csv"]
liftIO $ ssvFileToMap "site/out/history.csv"
let history = history' ()
let pred h = do { hist <- history; findPred hist h }
let predOrSelf h = do { hist <- history; findPredOrSelf hist h }
let recent n h = do { hist <- history; findRecent hist n h }
"site/out/latest.txt" *> \ out -> do
[head] <- readFileLines "site/out/head.txt"
latestM <- predOrSelf head
case latestM of
Just latest ->
writeFileChanged out latest
Nothing ->
fail "Head has no parent with logs?"
"graphs" ~> do
[latest] <- readFileLines "site/out/latest.txt"
need [resultsOf latest]
b <- liftIO $ benchmarksInCSVFile (resultsOf latest)
need (map graphFile b)
want ["graphs"]
"site/out/results/*.csv" *> \out -> do
let hash = takeBaseName out
need [logsOf hash]
Stdout csv <- cmd "./log2csv" (logsOf hash)
writeFile' out csv
"site/out/graphs//*.json" *> \out -> do
let bench = dropDirectory1 (dropDirectory1 (dropDirectory1 (dropExtension out)))
[latest] <- readFileLines "site/out/latest.txt"
limitRecent <- getLimitRecent (LimitRecent ())
r <- recent limitRecent latest
need (map resultsOf r)
Stdout json <- self "GraphReport" (bench : r)
writeFile' out json
"site/out/reports/*.json" *> \out -> do
let hash = takeBaseName out
need [resultsOf hash]
pred <- pred hash
need [resultsOf h | Just h <- return pred]
Stdout json <- self "RevReport" (hash : [h | Just h <- return pred])
writeFile' out json
"site/out/summaries/*.json" *> \out -> do
let hash = takeBaseName out
need [reportOf hash]
Stdout json <- self "Summary" [hash]
writeFile' out json
"site/out/latest-summaries.json" *> \out -> do
[latest] <- readFileLines "site/out/latest.txt"
r <- recent cGRAPH_HISTORY latest
need (map summaryOf r)
Stdout json <- self "IndexReport" r
writeFile' out json
want ["site/out/latest-summaries.json"]
"site/out/benchNames.json" *> \out -> do
[latest] <- readFileLines "site/out/latest.txt"
need [resultsOf latest]
b <- liftIO $ benchmarksInCSVFile (resultsOf latest)
need ["settings.yaml"]
Stdout json <- self "BenchNames" (nub b)
writeFile' out json
want ["site/out/benchNames.json"]
"site/out/all-summaries.json" *> \out -> do
range <- gitRange
Stdout range <- git "log" ["--format=%H",range]
let hashes = words range
withLogs <- filterM (doesFileExist . logsOf) hashes
need (map summaryOf withLogs)
Stdout json <- self "IndexReport" withLogs
writeFile' out json
want ["site/out/all-summaries.json"]
"site/out/settings.json" *> \out -> do
need ["settings.yaml"]
Stdout json <- self "JsonSettings" []
writeFile' out json
want ["site/out/settings.json"]
phony "clean" $ do
removeFilesAfter "site/out" ["//*"]