hspec-stack-rerun (empty) → 0.1.0.0
raw patch · 4 files changed
+118/−0 lines, 4 filesdep +basedep +directorydep +hspecsetup-changed
Dependencies added: base, directory, hspec, safe, strict
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- hspec-stack-rerun.cabal +19/−0
- src/Rerun.hs +67/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Mark Wotton (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Mark Wotton nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hspec-stack-rerun.cabal view
@@ -0,0 +1,19 @@+name: hspec-stack-rerun+version: 0.1.0.0+synopsis: Simple project template from stack+description: Please see README.md+homepage: https://github.com/mwotton/hspec-stack-rerun#readme+license: BSD3+license-file: LICENSE+author: Mark Wotton+maintainer: mwotton@gmail.com+copyright: AllRightsReserved+category: Web+build-type: Simple+cabal-version: >=1.10++library+ hs-source-dirs: src+ default-language: Haskell2010+ build-depends: base >= 4.7 && < 5, hspec, strict, directory, safe+ exposed-modules: Rerun
+ src/Rerun.hs view
@@ -0,0 +1,67 @@+{-# LANGUAGE ScopedTypeVariables #-}+module Rerun where++import Test.Hspec.Runner+import Control.Exception+import Prelude+import System.Environment+import System.IO.Strict+import System.IO(withFile,IOMode(ReadMode))+import System.Directory(removeFile)+import Safe (lastMay)+import Control.Monad(when)++-- | We wrap this so that we can stash HSPEC_FAILURES in a file (which+-- comes from HSPEC_FAILURES_FILE).++main clientSpec = do+ stashFile <- lookupEnv "HSPEC_FAILURES_FILE"+ alreadySet <- lookupEnv "HSPEC_FAILURES"+ print ("startup", stashFile, alreadySet)+ case (stashFile,alreadySet) of+ (Just stash,Just failures) -> do+ -- if there's no stash set, we might as well write it so+ -- we have a starting point. it might get overwritten later,+ -- that's fine+ print ("writing stash optimistically", failures)+ writeFile stash failures+ (Just stash,Nothing) -> do+ print ("reading", stash)+ f <- safeReadFile stash+ print ("read", stash)+ case f of+ Nothing -> print ("couldn't read stash", stash)+ -- this should read all of contents, thereby closing the+ -- filehandle. Lazy IO is the devil.+ Just contents -> do+ when (contents /= "") $ do+ print ("read stash, setting env", contents)+ setEnv "HSPEC_FAILURES" contents+ _ -> return ()+ clientSpec `finally` do+ print "done with tests!"+ -- we don't remove the file until now, so that if ghcid gets+ -- interrupted, we still have the failures to run first.+ -- small race condition, obviously, but the worst case is that+ -- we run more tests than we should.+ case stashFile of+ Just stash -> logAndIgnore () $ removeFile stash+ Nothing -> return ()++ newSet <- lookupEnv "HSPEC_FAILURES"+ print ("spec failures", newSet,stashFile,alreadySet)+ case (stashFile,alreadySet,newSet) of+ -- only care if there is a stash file, the var wasn't set before,+ -- and there is a new value: here, we write the file+ (Just stash,Nothing,Just newset) ->+ writeFile stash newset+ _ -> return ()++-- LAZY IO IS THE DEVIL+safeReadFile :: FilePath -> IO (Maybe String)+safeReadFile fs = logAndIgnore Nothing $ do+ f <- withFile fs ReadMode (\h -> hGetContents h >>= \x -> seq (lastMay x) (return x))+ print ("saferead got", f)+ return (Just f)++logAndIgnore def f = handle (\(e::IOException) -> print ("saferead failed", e) >> return def) f