packages feed

hscaffold 0.4.0.0 → 0.4.1.0

raw patch · 15 files changed

+257/−230 lines, 15 filesdep +exceptionssetup-changed

Dependencies added: exceptions

Files

Setup.hs view
@@ -1,2 +1,3 @@-import Distribution.Simple+import           Distribution.Simple+ main = defaultMain
bin/HsfilesFromDirectory.hs view
@@ -6,7 +6,7 @@ main = do     as <- getArgs     case as of-        (fp:_) -> go fp+        (fp : _) -> go fp         [] -> error "Usage: hsfiles-from-directory <DIRECTORY>"   where     go fp = do
hscaffold.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           hscaffold-version:        0.4.0.0+version:        0.4.1.0 synopsis:       Very simple file/directory structure scaffolding writer monad EDSL description:     See our README on GitHub at <https://github.com/yamadapc/hscaffold>  homepage:       https://github.com/yamadapc/hscaffold#readme@@ -34,6 +34,8 @@     , filepath     , unix     , regex-compat+    , temporary+    , exceptions   exposed-modules:       Hscaffold       Hscaffold.EDSL@@ -61,6 +63,8 @@     , filepath     , unix     , regex-compat+    , temporary+    , exceptions     , hscaffold   default-language: Haskell2010 @@ -78,10 +82,11 @@     , filepath     , unix     , regex-compat+    , temporary+    , exceptions     , hspec     , hscaffold     , QuickCheck-    , temporary   other-modules:       HscaffoldSpec       SanitySpec
src/Hscaffold.hs view
@@ -5,63 +5,60 @@ {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings     #-}+ module Hscaffold-    (-    -- * Running Hscaffold+    ( -- * Running Hscaffold       runHscaffold-    -- * Convert Hscaffold to HSFILES (@stack templates@)+      -- * Convert Hscaffold to HSFILES (@stack templates@)     , toHsfiles     , writeToHsfiles-    -- * Convert HSFILES to Hscaffold+      -- * Convert HSFILES to Hscaffold     , fromHsfiles     , fromHsfilesW     , readHsfiles--    -- * Convert a directory to Hscaffold+      -- * Convert a directory to Hscaffold     , hscaffoldFromDirectory-    -- * Compile Hscaffold to Haskell code+      -- * Compile Hscaffold to Haskell code     , hscaffoldToHaskell--    -- ** Finer grained runners+      -- ** Finer grained runners     , runAction     , runWriter     , runWriterT--    -- * EDSL Combinators+      -- * EDSL Combinators     , directory     , file     , link     , copy     , touch--    -- ** Setting permissions+      -- ** Setting permissions     , permissions     , fileWith     , directoryWith     , copyWith     , touchWith     , Permissions(..)--    -- * Types+      -- * Types     , ScaffoldMonadT     , ScaffoldMonadIO     , ScaffoldActionType(..)     , ScaffoldAction     , ScaffoldActionV     , ScaffoldMonadET--    -- * Helpers+      -- * Utilities+    , withTemporaryHscaffold+    , withTemporaryHscaffold'+    , withTemporaryHscaffoldIO+    , withTemporaryHscaffoldIO'+      -- * Helpers     , runHscaffoldIO     , mkActionPath--    -- * Re-exports+      -- * Re-exports     , Text     , module Control.Monad.IO.Class     , module Control.Monad.Writer     , module System.Directory     , module System.FilePath-    )-  where+    ) where  import           Control.Monad.IO.Class import           Control.Monad.Writer
src/Hscaffold/EDSL.hs view
@@ -2,9 +2,9 @@ {-# LANGUAGE FlexibleInstances     #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings     #-}-module Hscaffold.EDSL-  where +module Hscaffold.EDSL where+ import           Control.Monad.Writer import           Data.Text            (Text) import           System.Directory@@ -12,96 +12,72 @@ import           Hscaffold.Types  -- | Create a directory with the nested contents-directory-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> WriterT (ScaffoldAction e) m b-    -> m b+directory :: MonadWriter (ScaffoldAction e) m+          => FilePath+          -> WriterT (ScaffoldAction e) m b+          -> m b directory fp nested = do     (x, nested') <- runWriterT nested-    tell [Directory fp nested']+    tell [ Directory fp nested' ]     return x  -- | Create a directory with the nested contents and permissions-directoryWith-    :: MonadWriter (ScaffoldAction e) m-    => Permissions-    -> FilePath-    -> WriterT (ScaffoldAction e) m b-    -> m b+directoryWith :: MonadWriter (ScaffoldAction e) m+              => Permissions+              -> FilePath+              -> WriterT (ScaffoldAction e) m b+              -> m b directoryWith perms fp nested = do     x <- directory fp nested-    tell [SetPermissions perms fp]+    tell [ SetPermissions perms fp ]     return x  -- | Create a file with the given contents-file-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> Text-    -> m ()-file fp txt = tell [File fp txt]+file :: MonadWriter (ScaffoldAction e) m => FilePath -> Text -> m ()+file fp txt = tell [ File fp txt ]  -- | Create a file with the given contents and permissions-fileWith-    :: MonadWriter (ScaffoldAction e) m-    => Permissions-    -> FilePath-    -> Text-    -> m ()+fileWith :: MonadWriter (ScaffoldAction e) m+         => Permissions+         -> FilePath+         -> Text+         -> m () fileWith perms fp txt = do     file fp txt-    tell [SetPermissions perms fp]+    tell [ SetPermissions perms fp ]  -- | Set permissions on a filepath-permissions-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> Permissions-    -> m ()-permissions fp perms = tell [SetPermissions perms fp]+permissions :: MonadWriter (ScaffoldAction e) m+            => FilePath+            -> Permissions+            -> m ()+permissions fp perms = tell [ SetPermissions perms fp ]  -- | Create a symbolic link between two filepaths-link-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> FilePath-    -> m ()-link fp1 fp2 = tell [Link fp1 fp2]+link :: MonadWriter (ScaffoldAction e) m => FilePath -> FilePath -> m ()+link fp1 fp2 = tell [ Link fp1 fp2 ]  -- | Write the empty string to a file-touch-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> m ()+touch :: MonadWriter (ScaffoldAction e) m => FilePath -> m () touch fp = file fp ""  -- | Write the empty string to a file with given permissions-touchWith-    :: MonadWriter (ScaffoldAction e) m-    => Permissions-    -> FilePath-    -> m ()+touchWith :: MonadWriter (ScaffoldAction e) m => Permissions -> FilePath -> m () touchWith perms fp = fileWith perms fp ""  -- | Copy a file from A to B -- -- Non-absolute paths are treated relative to the *current* root, nested blocks -- change the root-copy-    :: MonadWriter (ScaffoldAction e) m-    => FilePath-    -> FilePath-    -> m ()-copy fp1 fp2 = tell [Copy fp1 fp2]+copy :: MonadWriter (ScaffoldAction e) m => FilePath -> FilePath -> m ()+copy fp1 fp2 = tell [ Copy fp1 fp2 ]  -- | Copy a file from A to B and set permissions on B, see 'copy'-copyWith-    :: MonadWriter (ScaffoldAction e) m-    => Permissions-    -> FilePath-    -> FilePath-    -> m ()+copyWith :: MonadWriter (ScaffoldAction e) m+         => Permissions+         -> FilePath+         -> FilePath+         -> m () copyWith perms fp1 fp2 = do     copy fp1 fp2     permissions fp2 perms
src/Hscaffold/Generator/Directory.hs view
@@ -1,5 +1,4 @@-module Hscaffold.Generator.Directory-  where+module Hscaffold.Generator.Directory where  import           Data.List import qualified Data.Text.IO     as Text@@ -15,16 +14,17 @@  -- | Converts a directory to scaffold actions with a custom filter function. By -- default we ignore directories starting with @.@-hscaffoldFromDirectoryWith-    :: ([FilePath] -> [FilePath]) -> FilePath -> IO (ScaffoldAction e)-hscaffoldFromDirectoryWith = hscaffoldFromDirectoryWith' False+hscaffoldFromDirectoryWith :: ([FilePath] -> [FilePath])+                           -> FilePath+                           -> IO (ScaffoldAction e)+hscaffoldFromDirectoryWith =+    hscaffoldFromDirectoryWith' False -hscaffoldFromDirectoryWith'-  :: Traversable t =>-     Bool-     -> ([FilePath] -> t FilePath)-     -> FilePath-     -> IO [ScaffoldActionType e]+hscaffoldFromDirectoryWith' :: Traversable t+                            => Bool+                            -> ([FilePath] -> t FilePath)+                            -> FilePath+                            -> IO [ScaffoldActionType e] hscaffoldFromDirectoryWith' isRecur p root = do     ls <- p <$> getDirectoryContents root     concat <$> mapM classify ls@@ -32,14 +32,11 @@     fromFile fp' fp = do         txt <- Text.readFile fp'         return [ File (normalise fp) txt ]-    fromDir =-        hscaffoldFromDirectoryWith' True p+    fromDir = hscaffoldFromDirectoryWith' True p     classify fp = do         let fp' = root </> fp         isfl <- doesFileExist fp'         isdir <- doesDirectoryExist fp'         if isfl             then fromFile fp' (if isRecur then fp' else fp)-            else if isdir-            then fromDir fp'-            else return []+            else if isdir then fromDir fp' else return []
src/Hscaffold/Generator/Hsfiles.hs view
@@ -1,12 +1,12 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE FlexibleContexts #-}-module Hscaffold.Generator.Hsfiles-  where+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings     #-} +module Hscaffold.Generator.Hsfiles where+ import           Control.Arrow import           Control.Monad.Writer-import qualified Data.Text                     as Text--- TODO - Disable this on Windows+import qualified Data.Text            as Text import           System.FilePath import           Text.Regex @@ -14,18 +14,12 @@  -- | Converts hsfiles to hscaffold actions fromHsfiles :: String -> ScaffoldAction e-fromHsfiles h =-    let (_, r) = foldr helper ("", []) matches-    in r+fromHsfiles h = snd $ foldr helper ("", []) matches   where-    helper (Just (fp:_), _) (lacc, current) =-        ( ""-        , File (normalise fp) lacc:current-        )+    helper (Just (fp : _), _) (lacc, current) =+        ("", File (normalise fp) lacc : current)     helper (_, l) (lacc, current) =-        ( Text.stripEnd (l <> "\n" <> lacc)-        , current-        )+        (Text.stripEnd (l <> "\n" <> lacc), current)     re = mkRegex "^{-# START_FILE (.+) #-}( +)?$"     matches = map (matchRegex re &&& Text.pack) (lines h) 
src/Hscaffold/Interpreter/Common.hs view
@@ -1,14 +1,14 @@-module Hscaffold.Interpreter.Common-  where+module Hscaffold.Interpreter.Common where  import           System.FilePath  -- | Very simple helper, if the second argument is absolute, returns it, -- otherwise, return it relative to the first argument-mkActionPath-    :: FilePath-    -- ^ The root-    -> FilePath-    -- ^ A filepath-    -> FilePath+mkActionPath :: FilePath+             ->+             -- ^ The root+             FilePath+             ->+             -- ^ A filepath+             FilePath mkActionPath root fp = if isAbsolute fp then fp else root </> fp
src/Hscaffold/Interpreter/Haskell.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-}-module Hscaffold.Interpreter.Haskell-  where +module Hscaffold.Interpreter.Haskell where+ import           Control.Monad.Writer import           Data.Text            (Text) import qualified Data.Text            as Text@@ -15,24 +15,26 @@         concatMap hscaffoldActionToHaskell hs  hscaffoldActionToHaskell :: ScaffoldActionType e -> [Text]-hscaffoldActionToHaskell h = case h of-    (File fp txt) ->-        [ "file " <> Text.pack (show fp <> " " <> show txt) ]-    (Directory fp nested) ->-        let nestedCode = concatMap hscaffoldActionToHaskell nested-            inestedCode = map ("    " <>) nestedCode-        in [ "directory " <> Text.pack (show fp) <> " $ do"-           ] <> inestedCode-    (Link fp1 fp2) ->-        [ "link " <> Text.pack (show fp1) <> " "-          <> Text.pack (show fp2)-        ]-    (SetPermissions p fp) ->-        [ "permissions " <> Text.pack (show fp)-            <> " (" <> Text.pack (show p) <> ")"-        ]-    (Copy fp1 fp2) ->-        [ "copy " <> Text.pack (show fp1)-            <> " " <> Text.pack (show fp2)-        ]-    _ -> []+hscaffoldActionToHaskell h =+    case h of+        (File fp txt) -> [ "file " <> Text.pack (show fp <> " " <> show txt) ]+        (Directory fp nested) ->+            let nestedCode = concatMap hscaffoldActionToHaskell nested+                inestedCode = map ("    " <>) nestedCode+            in+                [ "directory " <> Text.pack (show fp) <> " $ do" ] <>+                    inestedCode+        (Link fp1 fp2) -> [ "link " <> Text.pack (show fp1) <> " "+                              <> Text.pack (show fp2)+                          ]+        (SetPermissions p fp) ->+            [ "permissions " <> Text.pack (show fp)+                <> " (" <>+                Text.pack (show p) <>+                ")"+            ]+        (Copy fp1 fp2) -> [ "copy " <> Text.pack (show fp1)+                              <> " " <>+                              Text.pack (show fp2)+                          ]+        _ -> []
src/Hscaffold/Interpreter/Hsfiles.hs view
@@ -1,33 +1,35 @@ {-# LANGUAGE OverloadedStrings #-}-module Hscaffold.Interpreter.Hsfiles-  where +module Hscaffold.Interpreter.Hsfiles where+ import           Control.Monad.Writer import           Data.Text                    (Text) import qualified Data.Text                    as Text import qualified Data.Text.IO                 as Text -import           Hscaffold.Types- import           Hscaffold.Interpreter.Common+import           Hscaffold.Types  -- | Run the scaffolding writer and return an @.hsfiles@ 'Text' to use with -- @stack-templates@ toHsfiles :: Writer ScaffoldActionV a -> Text-toHsfiles w =-    let (_, ws) = runWriter w-    in Text.stripEnd $ Text.unlines $-       concatMap (actionToHsfile ".") ws+toHsfiles w = let (_, ws) = runWriter w+              in+                  Text.stripEnd $+                      Text.unlines $+                          concatMap (actionToHsfile ".") ws  -- | Convert a single scaffolding action to hsfiles -- -- Ignores everything but the 'file' directives actionToHsfile :: FilePath -> ScaffoldActionType e -> [Text] actionToHsfile root a = case a of-    (File fp txt) ->-        [ "{-# START_FILE " <> Text.pack (mkActionPath root fp) <> " #-}" ] <>+    (File fp txt) -> [ "{-# START_FILE " <> Text.pack (mkActionPath root fp) <>+                         " #-}"+                     ] <>         Text.lines txt-    (Directory fp nested) -> concatMap (actionToHsfile (mkActionPath root fp)) nested+    (Directory fp nested) ->+        concatMap (actionToHsfile (mkActionPath root fp)) nested     _ -> []  -- | Shortcut for
src/Hscaffold/Interpreter/IO.hs view
@@ -1,16 +1,18 @@-module Hscaffold.Interpreter.IO-  where+{-# LANGUAGE FlexibleContexts #-} +module Hscaffold.Interpreter.IO where++import           Control.Monad.Catch import           Control.Monad.IO.Class import           Control.Monad.Writer import qualified Data.Text.IO                 as Text import           System.Directory+import           System.IO.Temp -- TODO - Disable this on Windows import           System.Posix.Files -import           Hscaffold.Types- import           Hscaffold.Interpreter.Common+import           Hscaffold.Types  -- | Run the scaffolding writer on the IO monad with no extensions --@@ -35,7 +37,8 @@  -- | Run a single scaffolding action on the IO monad with no extensions runAction :: FilePath -> ScaffoldActionType e -> IO ()-runAction _ (ScaffoldActionTypeExtension _) = return ()+runAction _ (ScaffoldActionTypeExtension _) =+    return () runAction root (SetPermissions perms fp) =     setPermissions (mkActionPath root fp) perms runAction root (Link fp1 fp2) =@@ -50,3 +53,46 @@         fp2' = mkActionPath root fp2     copyFile fp1' fp2' +-- | Creates a temporary directory with the scaffold and runs an action that+-- takes it as its argument.+--+-- Uses 'withSystemTempDirectory' under the hood.+--+-- @+-- withTemporaryHscaffold+--     (do+--         file "something" "something"+--         directory "something" $ file "something-else" "something"+--     )+--     (\tmp -> do+--         undefined+--     )+-- @+withTemporaryHscaffold :: (MonadMask m, MonadIO m)+                       => ScaffoldMonadT m a+                       -> (FilePath -> m b)+                       -> m b+withTemporaryHscaffold =+    withTemporaryHscaffold' "hscaffold"++withTemporaryHscaffold' :: (MonadMask m, MonadIO m)+                        => String+                        -> ScaffoldMonadT m a+                        -> (FilePath -> m b)+                        -> m b+withTemporaryHscaffold' name scaffold action =+    withSystemTempDirectory name $+        \tmp -> do+            _ <- runHscaffold tmp scaffold+            action tmp++withTemporaryHscaffoldIO :: ScaffoldMonadIO a -> (FilePath -> IO b) -> IO b+withTemporaryHscaffoldIO =+    withTemporaryHscaffold++withTemporaryHscaffoldIO' :: String+                          -> ScaffoldMonadIO a+                          -> (FilePath -> IO b)+                          -> IO b+withTemporaryHscaffoldIO' =+    withTemporaryHscaffold'
src/Hscaffold/Types.hs view
@@ -1,5 +1,4 @@-module Hscaffold.Types-    where+module Hscaffold.Types where  import           Control.Monad.Writer import           Data.Text            (Text)@@ -22,11 +21,11 @@  -- | Type of actions scaffolding can make, 'ScaffoldActionTypeExtension' is open -- for extension through other data-types-data ScaffoldActionType e-    = File FilePath Text+data ScaffoldActionType e =+      File FilePath Text     | Link FilePath FilePath     | Directory FilePath (ScaffoldAction e)     | SetPermissions Permissions FilePath     | Copy FilePath FilePath     | ScaffoldActionTypeExtension e-  deriving(Show, Eq, Ord)+    deriving (Show, Eq, Ord)
test/HscaffoldSpec.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-}-module HscaffoldSpec-  where +module HscaffoldSpec where+ import           Control.Exception import           Control.Monad import           Data.Maybe@@ -61,78 +61,86 @@                     file "other/stuff-bang.hs" "stuff here"                     directory "other" $ do                         file "other-stuff-bang.hs" "even more stuff here"-            in h `shouldBe` Text.stripEnd-               (Text.unlines [ "{-# START_FILE ./stuff-bang.hs #-}"-                             , "stuff here"-                             , "{-# START_FILE ./other/stuff-bang.hs #-}"-                             , "stuff here"-                             , "{-# START_FILE ./other/other-stuff-bang.hs #-}"-                             , "even more stuff here"-                             ])+            in+                h `shouldBe`+                    Text.stripEnd (Text.unlines [ "{-# START_FILE ./stuff-bang.hs #-}"+                                                , "stuff here"+                                                , "{-# START_FILE ./other/stuff-bang.hs #-}"+                                                , "stuff here"+                                                , "{-# START_FILE ./other/other-stuff-bang.hs #-}"+                                                , "even more stuff here"+                                                ])      describe "fromHsfiles" $ do         it "works without surprises" $-            let h = (init-                     (unlines-                         [ "{-# START_FILE ./stuff-bang.hs #-}"-                         , "stuff here"-                         , "{-# START_FILE ./other/stuff-bang.hs #-}"-                         , "stuff here"-                         , "{-# START_FILE ./other/other-stuff-bang.hs #-}"-                         , "even more stuff here"-                         ]))-            in (fromHsfiles h :: ScaffoldActionV) `shouldBe`-               [ File "stuff-bang.hs" "stuff here"-               , File "other/stuff-bang.hs" "stuff here"-               , File "other/other-stuff-bang.hs" "even more stuff here"-               ]+            let h = (init (unlines [ "{-# START_FILE ./stuff-bang.hs #-}"+                                   , "stuff here"+                                   , "{-# START_FILE ./other/stuff-bang.hs #-}"+                                   , "stuff here"+                                   , "{-# START_FILE ./other/other-stuff-bang.hs #-}"+                                   , "even more stuff here"+                                   ]))+            in+                (fromHsfiles h :: ScaffoldActionV) `shouldBe`+                    [ File "stuff-bang.hs" "stuff here"+                    , File "other/stuff-bang.hs" "stuff here"+                    , File "other/other-stuff-bang.hs" "even more stuff here"+                    ]          it "works without surprises" $-            let h = (init-                     (unlines-                         [ "{-# START_FILE ./stuff-bang.hs #-}"-                         , "stuff here"-                         , "multiline"-                         , " ya"-                         , "{-# START_FILE ./other/stuff-bang.hs #-}"-                         , "stuff here"-                         , ""-                         , "{-# START_FILE ./other/other-stuff-bang.hs #-}      "-                         , "even more stuff here"-                         , "  here too"-                         ]))-            in (fromHsfiles h :: ScaffoldActionV) `shouldBe`-               [ File "stuff-bang.hs" "stuff here\nmultiline\n ya"-               , File "other/stuff-bang.hs" "stuff here"-               , File "other/other-stuff-bang.hs" "even more stuff here\n  here too"-               ]+            let h = (init (unlines [ "{-# START_FILE ./stuff-bang.hs #-}"+                                   , "stuff here"+                                   , "multiline"+                                   , " ya"+                                   , "{-# START_FILE ./other/stuff-bang.hs #-}"+                                   , "stuff here"+                                   , ""+                                   , "{-# START_FILE ./other/other-stuff-bang.hs #-}      "+                                   , "even more stuff here"+                                   , "  here too"+                                   ]))+            in+                (fromHsfiles h :: ScaffoldActionV) `shouldBe`+                    [ File "stuff-bang.hs" "stuff here\nmultiline\n ya"+                    , File "other/stuff-bang.hs" "stuff here"+                    , File "other/other-stuff-bang.hs"+                           "even more stuff here\n  here too"+                    ]      describe "hscaffoldToHaskell" $ do         it "works without surprises" $-            let h = hscaffoldToHaskell $ execWriter $ do-                    file "stuff-bang.hs" "stuff here"-                    file "other/stuff-bang.hs" "stuff here"-                    directory "other" $ do-                        file "other-stuff-bang.hs" "even more stuff here"-            in h `shouldBe` Text.stripEnd-               (Text.unlines [ "file \"stuff-bang.hs\" \"stuff here\""-                             , "file \"other/stuff-bang.hs\" \"stuff here\""-                             , "directory \"other\" $ do"-                             , "    file \"other-stuff-bang.hs\" \"even more stuff here\""-                             ])+            let h = hscaffoldToHaskell $+                    execWriter $ do+                        file "stuff-bang.hs" "stuff here"+                        file "other/stuff-bang.hs" "stuff here"+                        directory "other" $ do+                            file "other-stuff-bang.hs" "even more stuff here"+            in+                h `shouldBe`+                    Text.stripEnd (Text.unlines [ "file \"stuff-bang.hs\" \"stuff here\""+                                                , "file \"other/stuff-bang.hs\" \"stuff here\""+                                                , "directory \"other\" $ do"+                                                , "    file \"other-stuff-bang.hs\" \"even more stuff here\""+                                                ])      describe "hscaffoldFromDirectory" $ do         it "works without surprises" $ do             h <- hscaffoldFromDirectory "./src" :: IO (ScaffoldActionV)-            let ms = mapMaybe (\x -> case x of File fp _ -> Just fp; _ -> Nothing) h-            ms `shouldContain` ["Hscaffold.hs"]+            let ms = mapMaybe (\x -> case x of+                                   File fp _ -> Just fp+                                   _ -> Nothing)+                              h+            ms `shouldContain` [ "Hscaffold.hs" ]          it "ignores git" $ do             h <- hscaffoldFromDirectory "." :: IO (ScaffoldActionV)-            let ms = mapMaybe (\x -> case x of File fp _ -> Just fp; _ -> Nothing) h-            ms `shouldNotContain` [".git/index"]-            ms `shouldContain` ["README.md"]-            ms `shouldContain` ["test/Spec.hs"]+            let ms = mapMaybe (\x -> case x of+                                   File fp _ -> Just fp+                                   _ -> Nothing)+                              h+            ms `shouldNotContain` [ ".git/index" ]+            ms `shouldContain` [ "README.md" ]+            ms `shouldContain` [ "test/Spec.hs" ]      describe "the runner" $         describe "runAction" $ do
test/SanitySpec.hs view
@@ -1,6 +1,6 @@ module SanitySpec where -import Test.Hspec+import           Test.Hspec  spec = describe "when I have tests" $     it "I have sanity" $ True `shouldBe` True
test/Spec.hs view