packages feed

hpack 0.8.0 → 0.9.0

raw patch · 10 files changed

+436/−352 lines, 10 filesdep +temporarydep ~aesonPVP ok

version bump matches the API change (PVP)

Dependencies added: temporary

Dependency ranges changed: aeson

API changes (from Hackage documentation)

+ Hpack: hpack :: FilePath -> Bool -> IO ()
+ Hpack: main :: IO ()
+ Hpack: version :: Version
+ Hpack.Config: [sectionOtherExtensions] :: Section a -> [String]
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_6CommonOptions
- Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> Section a
+ Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> Section a
- Hpack.Run: run :: IO ([String], FilePath, String)
+ Hpack.Run: run :: FilePath -> IO ([String], FilePath, String)

Files

driver/Main.hs view
@@ -1,59 +1,6 @@ module Main (main) where -import           Prelude ()-import           Prelude.Compat--import           Control.DeepSeq-import           Control.Exception-import           Control.Monad.Compat-import           Data.List.Compat-import           Data.Version (showVersion)-import           System.Environment-import           System.Exit-import           System.IO-import           System.IO.Error--import           Paths_hpack (version)-import           Hpack.Config-import           Hpack.Run--programVersion :: String-programVersion = "hpack version " ++ showVersion version--header :: String-header = unlines [-    "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion ++ "."-  , "--"-  , "-- see: https://github.com/sol/hpack"-  , ""-  ]+import qualified Hpack  main :: IO ()-main = do-  args <- getArgs-  case args of-    ["--version"] -> putStrLn programVersion-    ["--silent"] -> hpack False-    [] -> hpack True-    _ -> do-      hPutStrLn stderr "Usage: hpack [ --version | --silent ]"-      exitFailure--hpack :: Bool -> IO ()-hpack verbose = do-  (warnings, name, new) <- run-  forM_ warnings $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)-  old <- force . either (const Nothing) (Just . stripHeader) <$> tryJust (guard . isDoesNotExistError) (readFile name)-  if (old == Just (lines new)) then do-    output (name ++ " is up-to-date")-  else do-    (writeFile name $ header ++ new)-    output ("generated " ++ name)-  where-    stripHeader :: String -> [String]-    stripHeader = dropWhile null . dropWhile ("--" `isPrefixOf`) . lines--    output :: String -> IO ()-    output message-      | verbose = putStrLn message-      | otherwise = return ()+main = Hpack.main
hpack.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.5.4.+-- This file has been generated from package.yaml by hpack version 0.8.0. -- -- see: https://github.com/sol/hpack  name:           hpack-version:        0.8.0+version:        0.9.0 synopsis:       An alternative format for Haskell packages category:       Development homepage:       https://github.com/sol/hpack#readme@@ -23,8 +23,7 @@       src   ghc-options: -Wall   build-depends:-      aeson >= 0.8-    , base >= 4.7 && < 5+      base >= 4.7 && < 5     , base-compat >= 0.8     , deepseq     , directory@@ -33,7 +32,9 @@     , text     , unordered-containers     , yaml+    , aeson >= 0.8   exposed-modules:+      Hpack       Hpack.Config       Hpack.Run       Hpack.Yaml@@ -42,6 +43,7 @@       Hpack.Haskell       Hpack.Render       Hpack.Util+      Paths_hpack   default-language: Haskell2010  executable hpack@@ -50,8 +52,7 @@       driver   ghc-options: -Wall   build-depends:-      aeson >= 0.8-    , base >= 4.7 && < 5+      base >= 4.7 && < 5     , base-compat >= 0.8     , deepseq     , directory@@ -61,6 +62,7 @@     , unordered-containers     , yaml     , hpack+    , aeson >= 0.8   default-language: Haskell2010  test-suite spec@@ -72,8 +74,7 @@   ghc-options: -Wall   cpp-options: -DTEST   build-depends:-      aeson >= 0.8-    , base >= 4.7 && < 5+      base >= 4.7 && < 5     , base-compat >= 0.8     , deepseq     , directory@@ -83,9 +84,11 @@     , unordered-containers     , yaml     , hspec == 2.*+    , temporary     , mockery >= 0.3     , interpolate     , aeson-qq+    , aeson >= 0.10   other-modules:       Helper       Hpack.ConfigSpec@@ -94,6 +97,8 @@       Hpack.RenderSpec       Hpack.RunSpec       Hpack.UtilSpec+      HpackSpec+      Hpack       Hpack.Config       Hpack.GenericsUtil       Hpack.Haskell
+ src/Hpack.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE CPP #-}+module Hpack (+  hpack+, version+, main+#ifdef TEST+, parseVerbosity+#endif+) where++import           Prelude ()+import           Prelude.Compat++import           Control.DeepSeq+import           Control.Exception+import           Control.Monad.Compat+import           Data.List.Compat+import           Data.Version (showVersion)+import           System.Environment+import           System.Exit+import           System.IO+import           System.IO.Error++import           Paths_hpack (version)+import           Hpack.Config+import           Hpack.Run++programVersion :: String+programVersion = "hpack version " ++ showVersion version++header :: String+header = unlines [+    "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion ++ "."+  , "--"+  , "-- see: https://github.com/sol/hpack"+  , ""+  ]++main :: IO ()+main = do+  args <- getArgs+  case args of+    ["--version"] -> putStrLn programVersion+    _ -> case parseVerbosity args of+      (verbose, [dir]) -> hpack dir verbose+      (verbose, []) -> hpack "." verbose+      _ -> do+        hPutStrLn stderr $ unlines [+            "Usage: hpack [ --silent ] [ dir ]"+          , "       hpack --version"+          ]+        exitFailure++parseVerbosity :: [String] -> (Bool, [String])+parseVerbosity xs = (verbose, ys)+  where+    silentFlag = "--silent"+    verbose = not (silentFlag `elem` xs)+    ys = filter (/= silentFlag) xs++hpack :: FilePath -> Bool -> IO ()+hpack dir verbose = do+  (warnings, name, new) <- run dir+  forM_ warnings $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)+  old <- force . either (const Nothing) (Just . stripHeader) <$> tryJust (guard . isDoesNotExistError) (readFile name)+  if (old == Just (lines new)) then do+    output (name ++ " is up-to-date")+  else do+    (writeFile name $ header ++ new)+    output ("generated " ++ name)+  where+    stripHeader :: String -> [String]+    stripHeader = dropWhile null . dropWhile ("--" `isPrefixOf`) . lines++    output :: String -> IO ()+    output message+      | verbose = putStrLn message+      | otherwise = return ()
src/Hpack/Config.hs view
@@ -26,6 +26,7 @@ , SourceRepository(..) #ifdef TEST , getModules+, determineModules #endif ) where @@ -55,7 +56,7 @@ package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Nothing Nothing Nothing [] [] Nothing Nothing [] [] []  section :: a -> Section a-section a = Section a [] [] [] [] [] []+section a = Section a [] [] [] [] [] [] []  packageConfig :: FilePath packageConfig = "package.yaml"@@ -124,6 +125,7 @@   commonOptionsSourceDirs :: Maybe (List FilePath) , commonOptionsDependencies :: Maybe (List Dependency) , commonOptionsDefaultExtensions :: Maybe (List String)+, commonOptionsOtherExtensions :: Maybe (List String) , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption) , commonOptionsCppOptions :: Maybe (List CppOption)@@ -188,8 +190,12 @@  readPackageConfig :: FilePath -> IO (Either String ([String], Package)) readPackageConfig file = do-  config <- decodeYaml file-  either (return . Left) (fmap Right . mkPackage) config+  r <- decodeYaml file+  case r of+    Left err -> return (Left err)+    Right config -> do+      dir <- takeDirectory <$> canonicalizePath file+      Right <$> mkPackage dir config  data Dependency = Dependency {   dependencyName :: String@@ -271,6 +277,7 @@ , sectionSourceDirs :: [FilePath] , sectionDependencies :: [Dependency] , sectionDefaultExtensions :: [String]+, sectionOtherExtensions :: [String] , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption] , sectionCppOptions :: [CppOption]@@ -287,18 +294,18 @@ , sourceRepositorySubdir :: Maybe String } deriving (Eq, Show) -mkPackage :: (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)-mkPackage (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do-  mLibrary <- mapM (toLibrary globalOptions) mLibrarySection-  executables <- toExecutables globalOptions (map (fmap captureUnknownFieldsValue) executableSections)-  tests <- toExecutables globalOptions (map (fmap captureUnknownFieldsValue) testsSections)-  benchmarks <- toExecutables globalOptions  (map (fmap captureUnknownFieldsValue) benchmarkSections)+mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)+mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do+  let name = fromMaybe (takeBaseName dir) packageConfigName -  name <- maybe (takeBaseName <$> getCurrentDirectory) return packageConfigName+  mLibrary <- mapM (toLibrary dir name globalOptions) mLibrarySection+  executables <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)+  tests <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) testsSections)+  benchmarks <- toExecutables dir globalOptions  (map (fmap captureUnknownFieldsValue) benchmarkSections) -  licenseFileExists <- doesFileExist "LICENSE"+  licenseFileExists <- doesFileExist (dir </> "LICENSE") -  missingSourceDirs <- nub . sort <$> filterM (fmap not <$> doesDirectoryExist) (+  missingSourceDirs <- nub . sort <$> filterM (fmap not <$> doesDirectoryExist . (dir </>)) (        maybe [] sectionSourceDirs mLibrary     ++ concatMap sectionSourceDirs executables     ++ concatMap sectionSourceDirs tests@@ -306,10 +313,10 @@     )    (extraSourceFilesWarnings, extraSourceFiles) <--    expandGlobs (fromMaybeList packageConfigExtraSourceFiles)+    expandGlobs dir (fromMaybeList packageConfigExtraSourceFiles)    (dataFilesWarnings, dataFiles) <--    expandGlobs (fromMaybeList packageConfigDataFiles)+    expandGlobs dir (fromMaybeList packageConfigDataFiles)    let pkg = Package {         packageName = name@@ -399,8 +406,8 @@       where         fromGithub = (++ "/issues") . sourceRepositoryUrl <$> sourceRepository -toLibrary :: Section global -> Section LibrarySection -> IO (Section Library)-toLibrary globalOptions library = traverse fromLibrarySection sect+toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO (Section Library)+toLibrary dir name globalOptions library = traverse fromLibrarySection sect   where     sect :: Section LibrarySection     sect = mergeSections globalOptions library@@ -410,12 +417,12 @@      fromLibrarySection :: LibrarySection -> IO Library     fromLibrarySection LibrarySection{..} = do-      modules <- concat <$> mapM getModules sourceDirs-      let (exposedModules, otherModules) = determineModules modules librarySectionExposedModules librarySectionOtherModules+      modules <- concat <$> mapM (getModules dir) sourceDirs+      let (exposedModules, otherModules) = determineModules name modules librarySectionExposedModules librarySectionOtherModules       return (Library exposedModules otherModules) -toExecutables :: Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable]-toExecutables globalOptions executables = mapM toExecutable sections+toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable]+toExecutables dir globalOptions executables = mapM toExecutable sections   where     sections :: [(String, Section ExecutableSection)]     sections = map (fmap $ mergeSections globalOptions) executables@@ -427,7 +434,7 @@       where         fromExecutableSection :: ExecutableSection -> IO (Executable, [GhcOption])         fromExecutableSection ExecutableSection{..} = do-          modules <- maybe (filterMain . concat <$> mapM getModules sectionSourceDirs) (return . fromList) executableSectionOtherModules+          modules <- maybe (filterMain . concat <$> mapM (getModules dir) sectionSourceDirs) (return . fromList) executableSectionOtherModules           return (Executable name mainSrcFile modules, ghcOptions)           where             filterMain :: [String] -> [String]@@ -437,11 +444,12 @@  mergeSections :: Section global -> Section a -> Section a mergeSections globalOptions options-  = Section a sourceDirs dependencies defaultExtensions ghcOptions ghcProfOptions cppOptions+  = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions   where     a = sectionData options     sourceDirs = sectionSourceDirs globalOptions ++ sectionSourceDirs options     defaultExtensions = sectionDefaultExtensions globalOptions ++ sectionDefaultExtensions options+    otherExtensions = sectionOtherExtensions globalOptions ++ sectionOtherExtensions options     ghcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options     ghcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options     cppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options@@ -449,39 +457,40 @@  toSection :: a -> CommonOptions -> Section a toSection a CommonOptions{..}-  = Section a sourceDirs dependencies defaultExtensions ghcOptions ghcProfOptions cppOptions+  = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions   where     sourceDirs = fromMaybeList commonOptionsSourceDirs     defaultExtensions = fromMaybeList commonOptionsDefaultExtensions+    otherExtensions = fromMaybeList commonOptionsOtherExtensions     ghcOptions = fromMaybeList commonOptionsGhcOptions     ghcProfOptions = fromMaybeList commonOptionsGhcProfOptions     cppOptions = fromMaybeList commonOptionsCppOptions     dependencies = fromMaybeList commonOptionsDependencies -determineModules :: [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String])-determineModules modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of+determineModules :: String -> [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String])+determineModules name modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of   (Nothing, Nothing) -> (modules, [])   _ -> (exposedModules, otherModules)   where-    otherModules   = maybe (modules \\ exposedModules) fromList mOtherModules+    otherModules   = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules     exposedModules = maybe (modules \\ otherModules)   fromList mExposedModules+    pathsModule = ["Paths_" ++ name] \\ exposedModules -getModules :: FilePath -> IO [String]-getModules src_ = sort <$> do-  exists <- doesDirectoryExist src_+getModules :: FilePath -> FilePath -> IO [String]+getModules dir src_ = sort <$> do+  exists <- doesDirectoryExist (dir </> src_)   if exists     then do-      src <- canonicalizePath src_-      cwd <- getCurrentDirectory-      removeSetup cwd src . toModules <$> getFilesRecursive src+      src <- canonicalizePath (dir </> src_)+      removeSetup src . toModules <$> getFilesRecursive src     else return []   where     toModules :: [[FilePath]] -> [String]     toModules = catMaybes . map toModule -    removeSetup :: FilePath -> FilePath -> [String] -> [String]-    removeSetup cwd src-      | src == cwd = filter (/= "Setup")+    removeSetup :: FilePath -> [String] -> [String]+    removeSetup src+      | src == dir = filter (/= "Setup")       | otherwise = id  fromMaybeList :: Maybe (List a) -> [a]
src/Hpack/Run.hs view
@@ -23,17 +23,18 @@ import           Data.Maybe import           Data.List.Compat import           System.Exit.Compat+import           System.FilePath  import           Hpack.Util import           Hpack.Config import           Hpack.Render -run :: IO ([String], FilePath, String)-run = do-  mPackage <- readPackageConfig packageConfig+run :: FilePath -> IO ([String], FilePath, String)+run dir = do+  mPackage <- readPackageConfig (dir </> packageConfig)   case mPackage of     Right (warnings, pkg) -> do-      let cabalFile = packageName pkg ++ ".cabal"+      let cabalFile = dir </> (packageName pkg ++ ".cabal")        old <- tryReadFile cabalFile @@ -185,6 +186,7 @@ renderSection Section{..} = [     renderSourceDirs sectionSourceDirs   , renderDefaultExtensions sectionDefaultExtensions+  , renderOtherExtensions sectionOtherExtensions   , renderGhcOptions sectionGhcOptions   , renderGhcProfOptions sectionGhcProfOptions   , renderCppOptions sectionCppOptions@@ -217,3 +219,6 @@  renderDefaultExtensions :: [String] -> Element renderDefaultExtensions = Field "default-extensions" . WordList++renderOtherExtensions :: [String] -> Element+renderOtherExtensions = Field "other-extensions" . WordList
src/Hpack/Util.hs view
@@ -119,13 +119,13 @@     isNameChar = (`elem` nameChars)     nameChars = ['a'..'z'] ++ ['A'..'Z'] ++ "-" -expandGlobs :: [String] -> IO ([String], [FilePath])-expandGlobs patterns = do-  files <- (fst <$> globDir compiledPatterns ".") >>= mapM removeDirectories+expandGlobs :: FilePath -> [String] -> IO ([String], [FilePath])+expandGlobs dir patterns = do+  files <- (fst <$> globDir compiledPatterns dir) >>= mapM removeDirectories   let warnings = [warn pattern | ([], pattern) <- zip files patterns]   return (warnings, combineResults files)   where-    combineResults = nub . map (makeRelative ".") . sort . concat+    combineResults = nub . map (makeRelative dir) . sort . concat     warn pattern = "Specified pattern " ++ show pattern ++ " for extra-source-files does not match any files"     compiledPatterns = map (compileWith options) patterns     removeDirectories = filterM doesFileExist
test/Helper.hs view
@@ -2,8 +2,21 @@   module Test.Hspec , module Test.Mockery.Directory , module Control.Applicative+, module System.IO.Temp+, module System.FilePath+, withCurrentDirectory ) where  import           Test.Hspec import           Test.Mockery.Directory import           Control.Applicative+import           System.Directory+import           Control.Exception+import           System.IO.Temp+import           System.FilePath++withCurrentDirectory :: FilePath -> IO a -> IO a+withCurrentDirectory dir action = do+  bracket (getCurrentDirectory) (setCurrentDirectory) $ \ _ -> do+    setCurrentDirectory dir+    action
test/Hpack/ConfigSpec.hs view
@@ -14,7 +14,10 @@ import           Data.Aeson.QQ import           Data.Aeson.Types import           Data.String.Interpolate+import           Control.Arrow+import           System.Directory (createDirectory) +import           Hpack.Util import           Hpack.Config hiding (package) import qualified Hpack.Config as Config @@ -27,6 +30,27 @@ library :: Library library = Library [] [] +withPackage :: String -> IO () -> (([String], Package) -> Expectation) -> Expectation+withPackage content beforeAction expectation = withSystemTempDirectory "hspec" $ \dir_ -> do+  let dir = dir_ </> "foo"+  createDirectory dir+  writeFile (dir </> "package.yaml") content+  withCurrentDirectory dir beforeAction+  r <- readPackageConfig (dir </> "package.yaml")+  either expectationFailure expectation r++withPackageConfig :: String -> IO () -> (Package -> Expectation) -> Expectation+withPackageConfig content beforeAction expectation = withPackage content beforeAction (expectation . snd)++withPackageConfig_ :: String -> (Package -> Expectation) -> Expectation+withPackageConfig_ content = withPackageConfig content (return ())++withPackageWarnings :: String -> IO () -> ([String] -> Expectation) -> Expectation+withPackageWarnings content beforeAction expectation = withPackage content beforeAction (expectation . fst)++withPackageWarnings_ :: String -> ([String] -> Expectation) -> Expectation+withPackageWarnings_ content = withPackageWarnings content (return ())+ spec :: Spec spec = do   describe "parseJSON" $ do@@ -83,199 +107,191 @@                 }|]             parseEither parseJSON value `shouldBe` (Left "Error in $: neither key \"git\" nor key \"github\" present" :: Either String Dependency) -  describe "getModules" $ around_ inTempDirectory $ do-    it "returns Haskell modules in specified source directory" $ do-      touch "src/Foo.hs"-      touch "src/Bar/Baz.hs"-      touch "src/Setup.hs"-      getModules "src" >>= (`shouldMatchList` ["Foo", "Bar.Baz", "Setup"])+  describe "getModules" $ around (withSystemTempDirectory "hspec") $ do+    it "returns Haskell modules in specified source directory" $ \dir -> do+      touch (dir </> "src/Foo.hs")+      touch (dir </> "src/Bar/Baz.hs")+      touch (dir </> "src/Setup.hs")+      getModules dir "src" >>= (`shouldMatchList` ["Foo", "Bar.Baz", "Setup"])      context "when source directory is '.'" $ do-      it "ignores Setup" $ do-        touch "Foo.hs"-        touch "Setup.hs"-        getModules "." `shouldReturn` ["Foo"]+      it "ignores Setup" $ \dir -> do+        touch (dir </> "Foo.hs")+        touch (dir </> "Setup.hs")+        getModules dir  "." `shouldReturn` ["Foo"]      context "when source directory is './.'" $ do-      it "ignores Setup" $ do-        touch "Foo.hs"-        touch "Setup.hs"-        getModules "./." `shouldReturn` ["Foo"]+      it "ignores Setup" $ \dir -> do+        touch (dir </> "Foo.hs")+        touch (dir </> "Setup.hs")+        getModules dir  "./." `shouldReturn` ["Foo"] -  describe "readPackageConfig" $ around_ (inTempDirectoryNamed "foo") $ do+  describe "determineModules" $ do+    it "adds the Paths_* module to the other-modules" $ do+      determineModules "foo" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo"])++    context "when the Paths_* module is part of the exposed-modules" $ do+      it "it does not add the Paths_* module to the other-modules" $ do+        determineModules "foo" [] (Just $ List ["Foo", "Paths_foo"]) Nothing `shouldBe` (["Foo", "Paths_foo"], [])++  describe "readPackageConfig" $ do     it "warns on unknown fields" $ do-      writeFile "package.yaml" [i|+      withPackageWarnings_ [i|         bar: 23         baz: 42         |]-      fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+        (`shouldBe` [           "Ignoring unknown field \"bar\" in package description"         , "Ignoring unknown field \"baz\" in package description"         ]+        )      it "accepts name" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         name: bar         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageName = "bar"}+        (packageName >>> (`shouldBe` "bar"))      it "accepts version" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         version: 0.1.0         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageVersion = "0.1.0"}+        (packageVersion >>> (`shouldBe` "0.1.0"))      it "accepts synopsis" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         synopsis: some synopsis         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageSynopsis = Just "some synopsis"}+        (packageSynopsis >>> (`shouldBe` Just "some synopsis"))      it "accepts description" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         description: some description         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageDescription = Just "some description"}+        (packageDescription >>> (`shouldBe` Just "some description"))      it "accepts category" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         category: Data         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageCategory = Just "Data"}+        (`shouldBe` package {packageCategory = Just "Data"})      it "accepts author" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         author: John Doe         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageAuthor = ["John Doe"]}+        (`shouldBe` package {packageAuthor = ["John Doe"]})      it "accepts maintainer" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         maintainer: John Doe <john.doe@example.com>         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageMaintainer = ["John Doe <john.doe@example.com>"]}+        (`shouldBe` package {packageMaintainer = ["John Doe <john.doe@example.com>"]})      it "accepts copyright" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         copyright: (c) 2015 John Doe         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageCopyright = ["(c) 2015 John Doe"]}+        (`shouldBe` package {packageCopyright = ["(c) 2015 John Doe"]})      it "accepts stability" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         stability: experimental         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageStability c `shouldBe` Just "experimental"+        (packageStability >>> (`shouldBe` Just "experimental"))      it "accepts homepage URL" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         homepage: https://example.com/         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageHomepage c `shouldBe` Just "https://example.com/"+        (packageHomepage >>> (`shouldBe` Just "https://example.com/"))      it "infers homepage URL from github" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageHomepage c `shouldBe` Just "https://github.com/hspec/hspec#readme"+        (packageHomepage >>> (`shouldBe` Just "https://github.com/hspec/hspec#readme"))      it "omits homepage URL if it is null" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         homepage: null         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageHomepage c `shouldBe` Nothing+        (packageHomepage >>> (`shouldBe` Nothing))      it "accepts bug-reports URL" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         bug-reports: https://example.com/issues         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageBugReports c `shouldBe` Just "https://example.com/issues"+        (packageBugReports >>> (`shouldBe` Just "https://example.com/issues"))      it "infers bug-reports URL from github" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageBugReports c `shouldBe` Just "https://github.com/hspec/hspec/issues"+        (packageBugReports >>> (`shouldBe` Just "https://github.com/hspec/hspec/issues"))      it "omits bug-reports URL if it is null" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         bug-reports: null         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageBugReports c `shouldBe` Nothing+        (packageBugReports >>> (`shouldBe` Nothing))      it "accepts license" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         license: MIT         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageLicense = Just "MIT"}+        (`shouldBe` package {packageLicense = Just "MIT"})      it "infers license file" $ do-      writeFile "package.yaml" [i|+      withPackageConfig [i|         name: foo         |]-      touch "LICENSE"-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {packageLicenseFile = Just "LICENSE"}+        (do+        touch "LICENSE"+        )+        (`shouldBe` package {packageLicenseFile = Just "LICENSE"})      it "accepts extra-source-files" $ do-      writeFile "package.yaml" [i|+      withPackageConfig [i|         extra-source-files:           - CHANGES.markdown           - README.markdown         |]-      touch "CHANGES.markdown"-      touch "README.markdown"-      Right (_, c) <- readPackageConfig "package.yaml"-      packageExtraSourceFiles c `shouldBe` ["CHANGES.markdown", "README.markdown"]+        (do+        touch "CHANGES.markdown"+        touch "README.markdown"+        )+        (packageExtraSourceFiles >>> (`shouldBe` ["CHANGES.markdown", "README.markdown"]))      it "accepts data-files" $ do-      writeFile "package.yaml" [i|+      withPackageConfig [i|         data-files:           - data/**/*.html         |]-      touch "data/foo/index.html"-      touch "data/bar/index.html"-      Right (_, c) <- readPackageConfig "package.yaml"-      packageDataFiles c `shouldMatchList` ["data/foo/index.html", "data/bar/index.html"]+        (do+        touch "data/foo/index.html"+        touch "data/bar/index.html"+        )+        (packageDataFiles >>> (`shouldMatchList` ["data/foo/index.html", "data/bar/index.html"]))      it "accepts github" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageSourceRepository c `shouldBe`-        Just (SourceRepository "https://github.com/hspec/hspec" Nothing)+        (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://github.com/hspec/hspec" Nothing)))      it "accepts third part of github URL as subdir" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         github: hspec/hspec/hspec-core         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      packageSourceRepository c `shouldBe`-        Just (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core"))+        (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core"))))      it "accepts CPP options" $ do-      writeFile "package.yaml" [i|+      withPackageConfig_ [i|         cpp-options: -DFOO         library:           cpp-options: -DLIB@@ -291,147 +307,146 @@             main: Spec.hs             cpp-options: -DTEST         |]-      Right (_, c) <- readPackageConfig "package.yaml"-      c `shouldBe` package {+        (`shouldBe` package {           packageLibrary = Just (section library) {sectionCppOptions = ["-DFOO", "-DLIB"]}         , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionCppOptions = ["-DFOO", "-DFOO"]}]         , packageTests = [(section $ executable "spec" "Spec.hs") {sectionCppOptions = ["-DFOO", "-DTEST"]}]         }+        )      context "when reading library section" $ do       it "warns on unknown fields" $ do-        writeFile "package.yaml" [i|+        withPackageWarnings_ [i|           library:             bar: 23             baz: 42           |]--        fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+          (`shouldBe` [             "Ignoring unknown field \"bar\" in library section"           , "Ignoring unknown field \"baz\" in library section"           ]+          )        it "accepts source-dirs" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           library:             source-dirs:               - foo               - bar           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}))        it "accepts default-extensions" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           library:             default-extensions:               - Foo               - Bar           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}))        it "accepts global default-extensions" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           default-extensions:             - Foo             - Bar           library: {}           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionDefaultExtensions = ["Foo", "Bar"]}))        it "accepts global source-dirs" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           source-dirs:             - foo             - bar           library: {}           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}))        it "allows to specify exposed-modules" $ do-        writeFile "package.yaml" [i|+        withPackageConfig [i|           library:             source-dirs: src             exposed-modules: Foo           |]-        touch "src/Foo.hs"-        touch "src/Bar.hs"-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+          (do+          touch "src/Foo.hs"+          touch "src/Bar.hs"+          )+          (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar", "Paths_foo"]}) {sectionSourceDirs = ["src"]}))        it "allows to specify other-modules" $ do-        writeFile "package.yaml" [i|+        withPackageConfig [i|           library:             source-dirs: src             other-modules: Bar           |]-        touch "src/Foo.hs"-        touch "src/Bar.hs"-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+          (do+          touch "src/Foo.hs"+          touch "src/Bar.hs"+          )+          (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}))        it "allows to specify both exposed-modules and other-modules" $ do-        writeFile "package.yaml" [i|+        withPackageConfig [i|           library:             source-dirs: src             exposed-modules: Foo             other-modules: Bar           |]-        touch "src/Baz.hs"-        Right (_, c) <- readPackageConfig "package.yaml"-        packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]}+          (do+          touch "src/Baz.hs"+          )+          (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Foo"], libraryOtherModules = ["Bar"]}) {sectionSourceDirs = ["src"]})) -      context "when neither exposed-module nor other-module are specified" $ do+      context "when neither exposed-modules nor other-modules are specified" $ do         it "exposes all modules" $ do-          writeFile "package.yaml" [i|+          withPackageConfig [i|             library:               source-dirs: src             |]-          touch "src/Foo.hs"-          touch "src/Bar.hs"-          Right (_, c) <- readPackageConfig "package.yaml"-          packageLibrary c `shouldBe` Just (section library{libraryExposedModules = ["Bar", "Foo"]}) {sectionSourceDirs = ["src"]}+            (do+            touch "src/Foo.hs"+            touch "src/Bar.hs"+            )+            (packageLibrary >>> (`shouldBe` Just (section library{libraryExposedModules = ["Bar", "Foo"]}) {sectionSourceDirs = ["src"]}))      context "when reading executable section" $ do       it "warns on unknown fields" $ do-        writeFile "package.yaml" [i|+        withPackageWarnings_ [i|           executables:             foo:               main: Main.hs               bar: 42               baz: 23           |]--        fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+          (`shouldBe` [             "Ignoring unknown field \"bar\" in executable section \"foo\""           , "Ignoring unknown field \"baz\" in executable section \"foo\""           ]+          )        it "reads executable section" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: driver/Main.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [section $ executable "foo" "driver/Main.hs"]+          (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"]))        it "accepts arbitrary entry points as main" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: Foo           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [+          (packageExecutables >>> (`shouldBe` [             (section $ executable "foo" "Foo.hs") {sectionGhcOptions = ["-main-is Foo"]}           ]+          ))        it "accepts source-dirs" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: Main.hs@@ -439,11 +454,10 @@                 - foo                 - bar           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]+          (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]))        it "accepts global source-dirs" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           source-dirs:             - foo             - bar@@ -451,38 +465,39 @@             foo:               main: Main.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]+          (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "Main.hs") {sectionSourceDirs = ["foo", "bar"]}]))        it "infers other-modules" $ do-        touch "src/Main.hs"-        touch "src/Foo.hs"-        touch "src/Bar.hs"-        touch "src/Baz.lhs"-        writeFile "package.yaml" [i|+        withPackageConfig [i|           executables:             foo:               main: Main.hs               source-dirs: src           |]-        Right (_, [r]) <- (fmap . fmap) packageExecutables <$> readPackageConfig "package.yaml"-        executableOtherModules (sectionData r) `shouldBe` ["Bar", "Baz", "Foo"]+          (do+          touch "src/Main.hs"+          touch "src/Foo.hs"+          touch "src/Bar.hs"+          touch "src/Baz.lhs"+          )+          (map (executableOtherModules . sectionData) . packageExecutables >>> (`shouldBe` [["Bar", "Baz", "Foo"]]))        it "allows to specify other-modules" $ do-        touch "src/Foo.hs"-        touch "src/Bar.hs"-        writeFile "package.yaml" [i|+        withPackageConfig [i|           executables:             foo:               main: Main.hs               source-dirs: src               other-modules: Baz           |]-        Right (_, [r]) <- (fmap . fmap) packageExecutables <$> readPackageConfig "package.yaml"-        executableOtherModules (sectionData r) `shouldBe` ["Baz"]+          (do+          touch "src/Foo.hs"+          touch "src/Bar.hs"+          )+          (map (executableOtherModules . sectionData) . packageExecutables >>> (`shouldBe` [["Baz"]]))        it "accepts default-extensions" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: driver/Main.hs@@ -490,11 +505,10 @@                 - Foo                 - Bar           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]+          (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]))        it "accepts global default-extensions" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           default-extensions:             - Foo             - Bar@@ -502,86 +516,79 @@             foo:               main: driver/Main.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        packageExecutables c `shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]+          (packageExecutables >>> (`shouldBe` [(section $ executable "foo" "driver/Main.hs") {sectionDefaultExtensions = ["Foo", "Bar"]}]))        it "accepts GHC options" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: driver/Main.hs               ghc-options: -Wall           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]})        it "accepts global GHC options" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           ghc-options: -Wall           executables:             foo:               main: driver/Main.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]}+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcOptions = ["-Wall"]}]})        it "accepts GHC profiling options" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           executables:             foo:               main: driver/Main.hs               ghc-prof-options: -fprof-auto           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]})        it "accepts global GHC profiling options" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           ghc-prof-options: -fprof-auto           executables:             foo:               main: driver/Main.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]})       context "when reading test section" $ do       it "warns on unknown fields" $ do-        writeFile "package.yaml" [i|+        withPackageWarnings_ [i|           tests:             foo:               main: Main.hs               bar: 42               baz: 23           |]--        fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+          (`shouldBe` [             "Ignoring unknown field \"bar\" in test section \"foo\""           , "Ignoring unknown field \"baz\" in test section \"foo\""           ]+          )        it "reads test section" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           tests:             spec:               main: test/Spec.hs           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageTests = [section $ executable "spec" "test/Spec.hs"]}+          (`shouldBe` package {packageTests = [section $ executable "spec" "test/Spec.hs"]})        it "accepts single dependency" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           tests:             spec:               main: test/Spec.hs               dependencies: hspec           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec"]}]}+          (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec"]}]})        it "accepts list of dependencies" $ do-        writeFile "package.yaml" [i|+        withPackageConfig_ [i|           tests:             spec:               main: test/Spec.hs@@ -589,12 +596,11 @@                 - hspec                 - QuickCheck           |]-        Right (_, c) <- readPackageConfig "package.yaml"-        c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec", "QuickCheck"]}]}+          (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["hspec", "QuickCheck"]}]})        context "when both global and section specific dependencies are specified" $ do         it "combines dependencies" $ do-          writeFile "package.yaml" [i|+          withPackageConfig_ [i|             dependencies:               - base @@ -603,12 +609,11 @@                 main: test/Spec.hs                 dependencies: hspec             |]-          Right (_, c) <- readPackageConfig "package.yaml"-          c `shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["base", "hspec"]}]}+            (`shouldBe` package {packageTests = [(section $ executable "spec" "test/Spec.hs") {sectionDependencies = ["base", "hspec"]}]})      context "when a specified source directory does not exist" $ do       it "warns" $ do-        writeFile "package.yaml" [i|+        withPackageWarnings [i|           source-dirs:             - some-dir             - some-existing-dir@@ -623,31 +628,38 @@               main: Main.hs               source-dirs: some-test-dir           |]-        touch "some-existing-dir/foo"-        fmap fst <$> readPackageConfig "package.yaml" `shouldReturn` Right [+          (do+          touch "some-existing-dir/foo"+          )+          (`shouldBe` [             "Specified source-dir \"some-dir\" does not exist"           , "Specified source-dir \"some-exec-dir\" does not exist"           , "Specified source-dir \"some-lib-dir\" does not exist"           , "Specified source-dir \"some-test-dir\" does not exist"           ]+          ) -    context "when package.yaml can not be parsed" $ do-      it "returns an error" $ do-        writeFile "package.yaml" [i|-          foo: bar-          foo baz-          |]-        readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml:3:10: could not find expected ':' while scanning a simple key"+    around (withSystemTempDirectory "hspec") $ do+      context "when package.yaml can not be parsed" $ do+        it "returns an error" $ \dir -> do+          let file = dir </> "package.yaml"+          writeFile file [i|+            foo: bar+            foo baz+            |]+          readPackageConfig file `shouldReturn` Left (file ++ ":3:12: could not find expected ':' while scanning a simple key") -    context "when package.yaml is invalid" $ do-      it "returns an error" $ do-        writeFile "package.yaml" [i|-          executables:-            foo:-              ain: driver/Main.hs-          |]-        readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml: Error in $.executables.foo: failed to parse field executables: The key \"main\" was not found"+      context "when package.yaml is invalid" $ do+        it "returns an error" $ \dir -> do+          let file = dir </> "package.yaml"+          writeFile file [i|+            executables:+              foo:+                ain: driver/Main.hs+            |]+          readPackageConfig file `shouldReturn` Left (file ++ ": Error in $.executables.foo: failed to parse field executables: The key \"main\" was not found") -    context "when package.yaml does not exist" $ do-      it "returns an error" $-        readPackageConfig "package.yaml" `shouldReturn` Left "package.yaml: Yaml file not found: package.yaml"+      context "when package.yaml does not exist" $ do+        it "returns an error" $ \dir -> do+          let file = dir </> "package.yaml"+          readPackageConfig file `shouldReturn` Left [i|#{file}: Yaml file not found: #{file}|]
test/Hpack/UtilSpec.hs view
@@ -142,64 +142,64 @@     it "rejects invalid fields" $ do       splitField "foo bar" `shouldBe` Nothing -  describe "expandGlobs" $ around_ inTempDirectory $ do-    it "accepts simple files" $ do-      touch "foo.js"-      expandGlobs ["foo.js"] `shouldReturn` ([], ["foo.js"])+  describe "expandGlobs" $ around (withSystemTempDirectory "hspec") $ do+    it "accepts simple files" $ \dir -> do+        touch (dir </> "foo.js")+        expandGlobs dir ["foo.js"] `shouldReturn` ([], ["foo.js"]) -    it "removes duplicates" $ do-      touch "foo.js"-      expandGlobs ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"])+    it "removes duplicates" $ \dir -> do+      touch (dir </> "foo.js")+      expandGlobs dir ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"]) -    it "rejects directories" $ do-      touch "foo"-      createDirectory "bar"-      expandGlobs ["*"] `shouldReturn` ([], ["foo"])+    it "rejects directories" $ \dir -> do+      touch (dir </> "foo")+      createDirectory (dir </> "bar")+      expandGlobs dir ["*"] `shouldReturn` ([], ["foo"]) -    it "rejects character ranges" $ do-      touch "foo1"-      touch "foo2"-      touch "foo[1,2]"-      expandGlobs ["foo[1,2]"] `shouldReturn` ([], ["foo[1,2]"])+    it "rejects character ranges" $ \dir -> do+      touch (dir </> "foo1")+      touch (dir </> "foo2")+      touch (dir </> "foo[1,2]")+      expandGlobs dir ["foo[1,2]"] `shouldReturn` ([], ["foo[1,2]"])      context "when expanding *" $ do-      it "expands by extension" $ do+      it "expands by extension" $ \dir -> do         let files = [                 "files/foo.js"               , "files/bar.js"               , "files/baz.js"]-        mapM_ touch files-        touch "files/foo.hs"-        expandGlobs ["files/*.js"] `shouldReturn` ([], sort files)+        mapM_ (touch . (dir </>)) files+        touch (dir </> "files/foo.hs")+        expandGlobs dir ["files/*.js"] `shouldReturn` ([], sort files) -      it "rejects dot-files" $ do-        touch "foo/bar"-        touch "foo/.baz"-        expandGlobs ["foo/*"] `shouldReturn` ([], ["foo/bar"])+      it "rejects dot-files" $ \dir -> do+        touch (dir </> "foo/bar")+        touch (dir </> "foo/.baz")+        expandGlobs dir ["foo/*"] `shouldReturn` ([], ["foo/bar"]) -      it "accepts dot-files when explicitly asked to" $ do-        touch "foo/bar"-        touch "foo/.baz"-        expandGlobs ["foo/.*"] `shouldReturn` ([], ["foo/.baz"])+      it "accepts dot-files when explicitly asked to" $ \dir -> do+        touch (dir </> "foo/bar")+        touch (dir </> "foo/.baz")+        expandGlobs dir ["foo/.*"] `shouldReturn` ([], ["foo/.baz"]) -      it "matches at most one directory component" $ do-        touch "foo/bar/baz.js"-        touch "foo/bar.js"-        expandGlobs ["*/*.js"] `shouldReturn` ([], ["foo/bar.js"])+      it "matches at most one directory component" $ \dir -> do+        touch (dir </> "foo/bar/baz.js")+        touch (dir </> "foo/bar.js")+        expandGlobs dir ["*/*.js"] `shouldReturn` ([], ["foo/bar.js"])      context "when expanding **" $ do-      it "matches arbitrary many directory components" $ do+      it "matches arbitrary many directory components" $ \dir -> do         let file = "foo/bar/baz.js"-        touch file-        expandGlobs ["**/*.js"] `shouldReturn` ([], [file])+        touch (dir </> file)+        expandGlobs dir ["**/*.js"] `shouldReturn` ([], [file])      context "when a pattern does not match anything" $ do-      it "warns" $ do-        expandGlobs ["foo"] `shouldReturn`+      it "warns" $ \dir -> do+        expandGlobs dir ["foo"] `shouldReturn`           (["Specified pattern \"foo\" for extra-source-files does not match any files"], [])      context "when a pattern only matches a directory" $ do-      it "warns" $ do-        createDirectory "foo"-        expandGlobs ["foo"] `shouldReturn`+      it "warns" $ \dir -> do+        createDirectory (dir </> "foo")+        expandGlobs dir ["foo"] `shouldReturn`           (["Specified pattern \"foo\" for extra-source-files does not match any files"], [])
+ test/HpackSpec.hs view
@@ -0,0 +1,15 @@+module HpackSpec (spec) where++import           Test.Hspec++import           Hpack++spec :: Spec+spec = do+  describe "parseVerbosity" $ do+    it "returns True by default" $ do+      parseVerbosity ["foo"] `shouldBe` (True, ["foo"])++    context "with --silent" $ do+      it "returns False" $ do+        parseVerbosity ["--silent"] `shouldBe` (False, [])