criterion 1.2.4.0 → 1.2.5.0
raw patch · 5 files changed
+127/−16 lines, 5 filesdep +file-embeddep +template-haskellPVP ok
version bump matches the API change (PVP)
Dependencies added: file-embed, template-haskell
API changes (from Hackage documentation)
Files
- Criterion/EmbeddedData.hs +28/−0
- Criterion/Report.hs +75/−11
- changelog.md +9/−2
- criterion.cabal +13/−1
- templates/default.tpl +2/−2
+ Criterion/EmbeddedData.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE TemplateHaskell #-}++-- |+-- Module : Criterion.EmbeddedData+-- Copyright : (c) 2017 Ryan Scott+--+-- License : BSD-style+-- Maintainer : bos@serpentine.com+-- Stability : experimental+-- Portability : GHC+--+-- When the @embed-data-files@ @Cabal@ flag is enabled, this module exports+-- the contents of various files (the @data-files@ from @criterion.cabal@, as+-- well as minimized versions of jQuery and Flot) embedded as 'ByteString's.+module Criterion.EmbeddedData (dataFiles, jQueryContents, flotContents) where++import Data.ByteString (ByteString)+import Data.FileEmbed (embedDir, embedFile)+import Language.Haskell.TH.Syntax (runIO)+import qualified Language.Javascript.Flot as Flot+import qualified Language.Javascript.JQuery as JQuery++dataFiles :: [(FilePath, ByteString)]+dataFiles = $(embedDir "templates")++jQueryContents, flotContents :: ByteString+jQueryContents = $(embedFile =<< runIO JQuery.file)+flotContents = $(embedFile =<< runIO (Flot.file Flot.Flot))
Criterion/Report.hs view
@@ -1,6 +1,10 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE Trustworthy #-}-{-# LANGUAGE DeriveDataTypeable, DeriveGeneric, OverloadedStrings,- RecordWildCards, ScopedTypeVariables #-} -- | -- Module : Criterion.Report@@ -56,8 +60,15 @@ import qualified Data.Text.Lazy.IO as TL import qualified Data.Vector.Generic as G import qualified Data.Vector.Unboxed as U++#if defined(EMBED)+import Criterion.EmbeddedData (dataFiles, flotContents, jQueryContents)+import qualified Data.ByteString.Lazy as BL+import qualified Data.Text.Encoding as TE+#else import qualified Language.Javascript.Flot as Flot import qualified Language.Javascript.JQuery as JQuery+#endif -- | Trim long flat tails from a KDE plot. tidyTails :: KDE -> KDE@@ -73,8 +84,15 @@ -- | Return the path to the template and other files used for -- generating reports.+--+-- When the @-fembed-data-files@ @Cabal@ flag is enabled, this simply+-- returns the empty path. getTemplateDir :: IO FilePath+#if defined(EMBED)+getTemplateDir = pure ""+#else getTemplateDir = getDataFileName "templates"+#endif -- | Write out a series of 'Report' values to a single file, if -- configured to do so.@@ -95,18 +113,22 @@ Left err -> fail (show err) -- TODO: throw a template exception? Right x -> return x - jQuery <- T.readFile =<< JQuery.file- flot <- T.readFile =<< Flot.file Flot.Flot+ jQuery <- jQueryFileContents+ flot <- flotFileContents+ jQueryCriterionJS <- readDataFile ("js" </> "jquery.criterion.js")+ criterionCSS <- readDataFile "criterion.css" -- includes, only top level templates <- getTemplateDir template <- includeTemplate (includeFile [templates]) template0 let context = object- [ "json" .= reports- , "report" .= map inner reports- , "js-jquery" .= jQuery- , "js-flot" .= flot+ [ "json" .= reports+ , "report" .= map inner reports+ , "js-jquery" .= jQuery+ , "js-flot" .= flot+ , "jquery-criterion-js" .= jQueryCriterionJS+ , "criterion-css" .= criterionCSS ] let (warnings, formatted) = renderMustacheW template context@@ -129,6 +151,25 @@ ] return formatted where+ jQueryFileContents, flotFileContents :: IO T.Text+#if defined(EMBED)+ jQueryFileContents = pure $ TE.decodeUtf8 jQueryContents+ flotFileContents = pure $ TE.decodeUtf8 flotContents+#else+ jQueryFileContents = T.readFile =<< JQuery.file+ flotFileContents = T.readFile =<< Flot.file Flot.Flot+#endif++ readDataFile :: FilePath -> IO T.Text+ readDataFile fp =+ (T.readFile =<< getDataFileName ("templates" </> fp))+#if defined(EMBED)+ `E.catch` \(e :: IOException) ->+ maybe (throwIO e)+ (pure . TE.decodeUtf8)+ (lookup fp dataFiles)+#endif+ includeTemplate :: (FilePath -> IO T.Text) -> Template -> IO Template includeTemplate f Template {..} = fmap (Template templateActual)@@ -240,19 +281,42 @@ -- If the name is an absolute or relative path, the search path is -- /not/ used, and the name is treated as a literal path. --+-- If the @-fembed-data-files@ @Cabal@ flag is enabled, this also checks+-- the embedded @data-files@ from @criterion.cabal@.+-- -- This function throws a 'TemplateException' if the template could -- not be found, or an 'IOException' if no template could be loaded. loadTemplate :: [FilePath] -- ^ Search path. -> FilePath -- ^ Name of template file. -> IO TL.Text loadTemplate paths name- | any isPathSeparator name = TL.readFile name+ | any isPathSeparator name = readFileCheckEmbedded name | otherwise = go Nothing paths where go me (p:ps) = do let cur = p </> name <.> "tpl"- x <- doesFileExist cur+ x <- doesFileExist' cur if x- then TL.readFile cur `E.catch` \e -> go (me `mplus` Just e) ps+ then readFileCheckEmbedded cur `E.catch` \e -> go (me `mplus` Just e) ps else go me ps go (Just e) _ = throwIO (e::IOException) go _ _ = throwIO . TemplateNotFound $ name++ doesFileExist' :: FilePath -> IO Bool+ doesFileExist' fp = do+ e <- doesFileExist fp+ pure $ e+#if defined(EMBED)+ || (fp `elem` map fst dataFiles)+#endif++-- A version of 'readFile' that falls back on the embedded 'dataFiles'+-- from @criterion.cabal@.+readFileCheckEmbedded :: FilePath -> IO TL.Text+readFileCheckEmbedded fp =+ TL.readFile fp+#if defined(EMBED)+ `E.catch` \(e :: IOException) ->+ maybe (throwIO e)+ (pure . TLE.decodeUtf8 . BL.fromStrict)+ (lookup fp dataFiles)+#endif
changelog.md view
@@ -1,10 +1,17 @@+1.2.5.0++* Add an `-fembed-data-files` flag. Enabling this option will embed the+ `data-files` from `criterion.cabal` directly into the binary, producing+ a relocatable executable. (This has the downside of increasing the binary+ size significantly, so be warned.)+ 1.2.4.0 -* Fix issue where `--help` would display duplicate options+* Fix issue where `--help` would display duplicate options. 1.2.3.0 -* Add a `Semigroup` instance for `Outliers`+* Add a `Semigroup` instance for `Outliers`. * Improve the error messages that are thrown when forcing nonexistent benchmark environments.
criterion.cabal view
@@ -1,5 +1,5 @@ name: criterion-version: 1.2.4.0+version: 1.2.5.0 synopsis: Robust, reliable performance measurement and analysis license: BSD3 license-file: LICENSE@@ -49,6 +49,12 @@ default: False manual: True +flag embed-data-files+ description: Embed the data files in the binary for a relocatable executable.+ (Warning: This will increase the executable size significantly.)+ default: False+ manual: True+ library exposed-modules: Criterion@@ -122,6 +128,12 @@ ghc-options: -O0 else ghc-options: -O2++ if flag(embed-data-files)+ other-modules: Criterion.EmbeddedData+ build-depends: file-embed < 0.1,+ template-haskell+ cpp-options: "-DEMBED" Executable criterion-report Default-Language: Haskell2010
templates/default.tpl view
@@ -10,10 +10,10 @@ {{{js-flot}}} </script> <script language="javascript" type="text/javascript">- {{#include}}js/jquery.criterion.js{{/include}}+ {{{jquery-criterion-js}}} </script> <style type="text/css">-{{#include}}criterion.css{{/include}}+ {{{criterion-css}}} </style> <!--[if !IE 7]> <style type="text/css">