packages feed

hpack 0.15.0 → 0.16.0

raw patch · 9 files changed

+355/−45 lines, 9 filesdep +bytestringPVP ok

version bump matches the API change (PVP)

Dependencies added: bytestring

API changes (from Hackage documentation)

Files

+ README.md view
@@ -0,0 +1,192 @@+# hpack: An alternative format for Haskell packages++## Examples++ * Given this [package.yaml](https://github.com/sol/hpack/blob/master/package.yaml) running `hpack` will generate [hpack.cabal](https://github.com/sol/hpack/blob/master/hpack.cabal)+ * Given this [package.yaml](https://github.com/zalora/getopt-generics/blob/master/package.yaml) running `hpack` will generate [getopt-generics.cabal](https://github.com/zalora/getopt-generics/blob/master/getopt-generics.cabal)+ * Given this [package.yaml](https://github.com/hspec/sensei/blob/master/package.yaml) running `hpack` will generate [sensei.cabal](https://github.com/hspec/sensei/blob/master/sensei.cabal)+ * Given this [package.yaml](https://github.com/haskell-compat/base-orphans/blob/master/package.yaml) running `hpack` will generate [base-orphans.cabal](https://github.com/haskell-compat/base-orphans/blob/master/base-orphans.cabal)++## Documentation++### Getting started++One easy way of getting started is to use+[hpack-convert](http://hackage.haskell.org/package/hpack-convert) to convert an+existing cabal file into a `package.yaml`.++### Quick-reference++#### Top-level fields++| Hpack | Cabal | Default | Notes | Example |+| --- | --- | --- | --- | --- |+| `name` | `name` | | | |+| `version` | `version` | `0.0.0` | | |+| `synopsis` | `synopsis` | | | |+| `description` | `description` | | | |+| `category` | `category` | | | |+| `stability` | `stability` | | | |+| `homepage` | `homepage` | If `github` given, `<repo>#readme` | | |+| `bug-reports` | `bug-reports` | If `github` given, `<repo>/issues` | | |+| `author` | `author` | | May be a list | |+| `maintainer` | `maintainer` | | May be a list | |+| `copyright` | `copyright` | | May be a list |+| `license` | `license` | | | |+| `license-file` | `license-file` | `LICENSE` if file exists | | |+| `tested-with` | `tested-with` | | | |+| `build-type` | `build-type` | `Simple` | Must be `Simple`, `Configure`, `Make`, or `Custom` | |+| | `cabal-version` | `>= 1.10` or `>= 1.21` | `>= 1.21` if library component has `reexported-modules` field | |+| `extra-source-files` | `extra-source-files` | | Accepts [glob patterns](#file-globbing) | |+| `data-files` | `data-files` | | Accepts [glob patterns](#file-globbing) | |+| `github` | `source-repository head` | | Accepts `user/repo` or `user/repo/subdir` | `github: foo/bar`+| `git`    | `source-repository head` | | No effect if `github` given | `git: https://my.repo.com/foo` |+| `flags`  | `flag <name>` | | Map from flag name to flag (see [Flags](#flags)) | |+| `library` | `library` | | See [Library fields](#library-fields) | |+| `executables` | `executable <name>` | | Map from executable name to executable (see [Executable fields](#executable-fields)) | |+| `tests` | `test-suite <name>` | | Map from test name to test (see [Test fields](#test-fields)) | |+| `benchmarks` | `benchmark <name>` | | Map from benchmark name to benchmark (see [Benchmark fields](#benchmark-fields)) | |++#### Global top-level fields++These fields are merged with all library, executable, test, and benchmark components.++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| `source-dirs` | `hs-source-dirs` | | |+| `default-extensions` | `default-extensions` | | |+| `other-extension` | `other-extensions` | | |+| `ghc-options` | `ghc-options` | | |+| `ghc-prof-options` | `ghc-prof-options` | | |+| `cpp-options` | `cpp-options` | | |+| `cc-options` | `cc-options` | | |+| `c-sources` | `c-sources` | | |+| `extra-lib-dirs` | `extra-lib-dirs` | | |+| `extra-libraries` | `extra-libraries` | | |+| `include-dirs` | `include-dirs` | | |+| `install-includes` | `install-includes` | | |+| `ld-options` | `ld-options` | | |+| `buildable` | `buildable` | | May be overridden by later stanza |+| `dependencies` | `build-depends` | | |+| `build-tools` | `build-tools` | | |+| `when` | | | Accepts a list of conditionals (see [Conditionals](#conditionals)) |++#### <a name="library-fields"></a>Library fields++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| `exposed` | `exposed` | | |+| `exposed-modules` | `exposed-modules` | All modules in `source-dirs` less `other-modules` | |+| `other-modules` | `other-modules` | All modules in `source-dirs` less `exposed-modules` | |+| `reexported-modules` | `reexported-modules` | | |+| | `default-language` | `Haskell2010` | |++#### <a name="executable-fields"></a>Executable fields++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| `main` | `main-is` | | |+| `other-modules` | `other-modules` | | |+| | `default-language` | `Haskell2010` | |++#### <a name="test-fields"></a>Test fields++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| | `type` | `exitcode-stdio-1.0` | |+| `main` | `main-is` | | |+| `other-modules` | `other-modules` | | |+| | `default-language` | `Haskell2010` | |++#### <a name="benchmark-fields"></a>Benchmark fields++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| | `type` | `exitcode-stdio-1.0` | |+| `main` | `main-is` | | |+| `other-modules` | `other-modules` | | |+| | `default-language` | `Haskell2010` | |++#### <a name="flags"></a>Flags++| Hpack | Cabal | Default | Notes |+| --- | --- | --- | --- |+| `description` | `description` | | Optional |+| `manual` | `manual` | | Required (unlike Cabal) |+| `default` | `default` | | Required (unlike Cabal) |++#### <a name="conditionals"></a> Conditionals++Conditionals with no else branch:++- Must have a `condition` field+- May have any number of other fields++For example,++    when:+      - condition: os(darwin)+        extra-lib-dirs: lib/darwin++becomes++    if os(darwin)+      extra-lib-dirs:+        lib/darwin++Conditionals with an else branch:++- Must have a `condition` field+- Must have a `then` field, itself an object containing any number of other fields+- Must have a `else` field, itself an object containing any number of other fields+- All other top-level fields are ignored++For example,++    when:+      - condition: flag(fast)+        then:+          ghc-options: -O2+        else:+          ghc-options: -O0++becomes++    if flag(fast)+      ghc-options: -O2+    else+      ghc-options: -O0+++### <a name="file-globbing"></a>File globbing++At place where you can specify a list of files you can also use glob patterns.+Glob patters and ordinary file names can be freely mixed, e.g.:++```yaml+extra-source-files:+  - static/*.js+  - static/site.css+```++Glob patterns are expanded according to the following rules:++ - `?` and `*` are expanded according to POSIX (they match arbitrary+   characters, except for directory separators)+ - `**` is expanded in a `zsh`-like fashion (matching across directory+   separators)+ - `?`, `*` and `**` do not match a `.` at the beginning of a file/directory++### Slides++ - Slides from my talk about `hpack` at the Singapore Haskell meetup:+   http://typeful.net/talks/hpack++## Vim integration++To run `hpack` automatically on modifications to `package.yaml` add the+following to your `~/.vimrc`:++```vim+autocmd BufWritePost package.yaml silent !hpack --silent+```
hpack.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.14.1.+-- This file has been generated from package.yaml by hpack version 0.15.0. -- -- see: https://github.com/sol/hpack  name:           hpack-version:        0.15.0+version:        0.16.0 synopsis:       An alternative format for Haskell packages category:       Development homepage:       https://github.com/sol/hpack#readme@@ -14,6 +14,9 @@ build-type:     Simple cabal-version:  >= 1.10 +extra-source-files:+    README.md+ source-repository head   type: git   location: https://github.com/sol/hpack@@ -25,6 +28,7 @@   build-depends:       base >= 4.7 && < 5     , base-compat >= 0.8+    , bytestring     , deepseq     , directory     , filepath@@ -56,6 +60,7 @@   build-depends:       base >= 4.7 && < 5     , base-compat >= 0.8+    , bytestring     , deepseq     , directory     , filepath@@ -73,12 +78,13 @@   main-is: Spec.hs   hs-source-dirs:       test-    , src+      src   ghc-options: -Wall   cpp-options: -DTEST   build-depends:       base >= 4.7 && < 5     , base-compat >= 0.8+    , bytestring     , deepseq     , directory     , filepath
src/Hpack.hs view
@@ -17,22 +17,23 @@ import           Prelude () import           Prelude.Compat -import           Control.DeepSeq-import           Control.Exception import           Control.Monad.Compat+import qualified Data.ByteString as B import           Data.List.Compat import           Data.Maybe+import qualified Data.Text as T+import           Data.Text.Encoding (encodeUtf8) import           Data.Version (Version) import qualified Data.Version as Version import           System.Environment import           System.Exit import           System.IO-import           System.IO.Error import           Text.ParserCombinators.ReadP  import           Paths_hpack (version) import           Hpack.Config import           Hpack.Run+import           Hpack.Util  programVersion :: Version -> String programVersion v = "hpack version " ++ Version.showVersion v@@ -113,14 +114,14 @@ hpackWithVersionResult :: Version -> FilePath -> IO Result hpackWithVersionResult v dir = do   (warnings, cabalFile, new) <- run dir-  old <- either (const Nothing) (Just . splitHeader) <$> tryJust (guard . isDoesNotExistError) (readFile cabalFile >>= (return $!!))+  old <- fmap splitHeader <$> tryReadFile cabalFile   let oldVersion = fmap fst old >>= extractVersion   status <-     if (oldVersion <= Just v) then       if (fmap snd old == Just (lines new)) then         return OutputUnchanged       else do-        writeFile cabalFile $ header v ++ new+        B.writeFile cabalFile $ encodeUtf8 $ T.pack $ header v ++ new         return Generated     else       return AlreadyGeneratedByNewerHpack
src/Hpack/Config.hs view
@@ -462,13 +462,19 @@  mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package) mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do-  let name = fromMaybe (takeBaseName dir) packageConfigName+  let+    (nameWarnings, name) = maybe (["Package name not specified, inferred " ++ show inferredName], inferredName) ((,) []) packageConfigName+      where inferredName = takeBaseName dir -  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)+  libraryResult <- mapM (toLibrary dir name globalOptions) mLibrarySection+  let+    mLibrary = fmap snd libraryResult+    libraryWarnings = maybe [] fst libraryResult +  (executablesWarnings, executables) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)+  (testsWarnings, tests) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) testsSections)+  (benchmarksWarnings, benchmarks) <- toExecutables dir globalOptions  (map (fmap captureUnknownFieldsValue) benchmarkSections)+   licenseFileExists <- doesFileExist (dir </> "LICENSE")    missingSourceDirs <- nub . sort <$> filterM (fmap not <$> doesDirectoryExist . (dir </>)) (@@ -479,10 +485,10 @@     )    (extraSourceFilesWarnings, extraSourceFiles) <--    expandGlobs dir (fromMaybeList packageConfigExtraSourceFiles)+    expandGlobs "extra-source-files" dir (fromMaybeList packageConfigExtraSourceFiles)    (dataFilesWarnings, dataFiles) <--    expandGlobs dir (fromMaybeList packageConfigDataFiles)+    expandGlobs "data-files" dir (fromMaybeList packageConfigDataFiles)    let pkg = Package {         packageName = name@@ -512,11 +518,16 @@        warnings =            formatUnknownFields "package description" unknownFields+        ++ nameWarnings         ++ flagWarnings         ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary)         ++ formatUnknownSectionFields "executable" executableSections         ++ formatUnknownSectionFields "test" testsSections         ++ formatMissingSourceDirs missingSourceDirs+        ++ libraryWarnings+        ++ executablesWarnings+        ++ testsWarnings+        ++ benchmarksWarnings         ++ extraSourceFilesWarnings         ++ dataFilesWarnings @@ -587,8 +598,13 @@       where         fromGithub = (++ "/issues") . sourceRepositoryUrl <$> github -toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO (Section Library)-toLibrary dir name globalOptions library = traverse fromLibrarySection sect+expandCSources :: FilePath -> Section a -> IO ([String], Section a)+expandCSources dir sect@Section{..} = do+  (warnings, files) <- expandGlobs "c-sources" dir sectionCSources+  return (warnings, sect {sectionCSources = files})++toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO ([String], Section Library)+toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandCSources dir   where     sect :: Section LibrarySection     sect = mergeSections globalOptions library@@ -603,8 +619,11 @@           reexportedModules = fromMaybeList librarySectionReexportedModules       return (Library librarySectionExposed exposedModules otherModules reexportedModules) -toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable]-toExecutables dir globalOptions executables = mapM toExecutable sections+toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO ([String], [Section Executable])+toExecutables dir globalOptions executables = do+  result <- mapM toExecutable sections >>= mapM (expandCSources dir)+  let (warnings, xs) = unzip result+  return (concat warnings, xs)   where     sections :: [(String, Section ExecutableSection)]     sections = map (fmap $ mergeSections globalOptions) executables
src/Hpack/Run.hs view
@@ -14,6 +14,7 @@ , renderConditional , renderFlag , renderSourceRepository+, renderDirectories , formatDescription #endif ) where@@ -203,17 +204,17 @@  renderSection :: Section a -> [Element] renderSection Section{..} = [-    renderSourceDirs sectionSourceDirs+    renderDirectories "hs-source-dirs" sectionSourceDirs   , renderDefaultExtensions sectionDefaultExtensions   , renderOtherExtensions sectionOtherExtensions   , renderGhcOptions sectionGhcOptions   , renderGhcProfOptions sectionGhcProfOptions   , renderCppOptions sectionCppOptions   , renderCcOptions sectionCcOptions-  , Field "include-dirs" (LineSeparatedList sectionIncludeDirs)+  , renderDirectories "include-dirs" sectionIncludeDirs   , Field "install-includes" (LineSeparatedList sectionInstallIncludes)   , Field "c-sources" (LineSeparatedList sectionCSources)-  , Field "extra-lib-dirs" (LineSeparatedList sectionExtraLibDirs)+  , renderDirectories "extra-lib-dirs" sectionExtraLibDirs   , Field "extra-libraries" (LineSeparatedList sectionExtraLibraries)   , renderLdOptions sectionLdOptions   , renderDependencies sectionDependencies@@ -232,8 +233,13 @@ defaultLanguage :: Element defaultLanguage = Field "default-language" "Haskell2010" -renderSourceDirs :: [String] -> Element-renderSourceDirs = Field "hs-source-dirs" . CommaSeparatedList+renderDirectories :: String -> [String] -> Element+renderDirectories name = Field name . LineSeparatedList . replaceDots+  where+    replaceDots = map replaceDot+    replaceDot xs = case xs of+      "." -> "./."+      _ -> xs  renderExposedModules :: [String] -> Element renderExposedModules = Field "exposed-modules" . LineSeparatedList
src/Hpack/Util.hs view
@@ -19,14 +19,18 @@ import           Prelude.Compat  import           Control.Applicative-import           Control.DeepSeq import           Control.Exception import           Control.Monad.Compat import           Data.Aeson.Types+import qualified Data.ByteString as B import           Data.Char import           Data.Data import           Data.List.Compat hiding (sort) import           Data.Ord+import qualified Data.Text as T+import           Data.Text.Encoding (decodeUtf8With)+import           Data.Text.Encoding.Error (lenientDecode)+import           System.IO.Error import           System.Directory import           System.FilePath import qualified System.FilePath.Posix as Posix@@ -95,20 +99,20 @@  tryReadFile :: FilePath -> IO (Maybe String) tryReadFile file = do-  r <- try (readFile file) :: IO (Either IOException String)-  return $!! either (const Nothing) Just r+  r <- tryJust (guard . isDoesNotExistError) (B.readFile file)+  return $ either (const Nothing) (Just . T.unpack . decodeUtf8With lenientDecode) r  toPosixFilePath :: FilePath -> FilePath toPosixFilePath = Posix.joinPath . splitDirectories -expandGlobs :: FilePath -> [String] -> IO ([String], [FilePath])-expandGlobs dir patterns = do+expandGlobs :: String -> FilePath -> [String] -> IO ([String], [FilePath])+expandGlobs name 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 . sort . map (toPosixFilePath . makeRelative dir) . concat-    warn pattern = "Specified pattern " ++ show pattern ++ " for extra-source-files does not match any files"+    warn pattern = "Specified pattern " ++ show pattern ++ " for " ++ name ++ " does not match any files"     compiledPatterns = map (compileWith options) patterns     removeDirectories = filterM doesFileExist     options = CompOptions {
test/Hpack/ConfigSpec.hs view
@@ -112,10 +112,10 @@         let input = [i|               c-sources:                 - foo.c-                - bar.c+                - bar/*.c               |]         captureUnknownFieldsValue <$> decodeEither input-          `shouldBe` Right (section Empty){sectionCSources = ["foo.c", "bar.c"]}+          `shouldBe` Right (section Empty){sectionCSources = ["foo.c", "bar/*.c"]}        it "accepts extra-lib-dirs" $ do         let input = [i|@@ -306,6 +306,7 @@   describe "readPackageConfig" $ do     it "warns on unknown fields" $ do       withPackageWarnings_ [i|+        name: foo         bar: 23         baz: 42         |]@@ -317,6 +318,7 @@      it "warns on unknown fields in when block, list" $ do       withPackageWarnings_ [i|+        name: foo         when:           - condition: impl(ghc)             bar: 23@@ -330,6 +332,7 @@      it "warns on unknown fields in when block, single" $ do       withPackageWarnings_ [i|+        name: foo         when:           condition: impl(ghc)           github: foo/bar@@ -342,6 +345,21 @@         ]         ) +    it "warns on missing name" $ do+      withPackageWarnings_ [i|+        {}+        |]+        (`shouldBe` [+          "Package name not specified, inferred \"foo\""+        ]+        )++    it "infers name" $ do+      withPackageConfig_ [i|+        {}+        |]+        (packageName >>> (`shouldBe` "foo"))+     it "accepts name" $ do       withPackageConfig_ [i|         name: bar@@ -496,6 +514,7 @@      it "warns on unknown fields in flag sections" $ do       withPackageWarnings_ [i|+        name: foo         flags:           integration-tests:             description: Run the integration test suite@@ -626,6 +645,7 @@     context "when reading library section" $ do       it "warns on unknown fields" $ do         withPackageWarnings_ [i|+          name: foo           library:             bar: 23             baz: 42@@ -690,6 +710,30 @@           |]           (packageLibrary >>> (`shouldBe` Just (section library) {sectionBuildTools = ["alex", "happy"]})) +      it "accepts c-sources" $ do+        withPackageConfig [i|+          library:+            c-sources:+              - cbits/*.c+          |]+          (do+          touch "cbits/foo.c"+          touch "cbits/bar.c"+          )+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}))++      it "accepts global c-sources" $ do+        withPackageConfig [i|+          c-sources:+            - cbits/*.c+          library: {}+          |]+          (do+          touch "cbits/foo.c"+          touch "cbits/bar.c"+          )+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}))+       it "allows to specify exposed" $ do         withPackageConfig_ [i|           library:@@ -755,6 +799,7 @@     context "when reading executable section" $ do       it "warns on unknown fields" $ do         withPackageWarnings_ [i|+          name: foo           executables:             foo:               main: Main.hs@@ -915,10 +960,38 @@           |]           (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionGhcProfOptions = ["-fprof-auto"]}]}) +      it "accepts c-sources" $ do+        withPackageConfig [i|+          executables:+            foo:+              main: driver/Main.hs+              c-sources:+                - cbits/*.c+          |]+          (do+          touch "cbits/foo.c"+          touch "cbits/bar.c"+          )+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}]}) +      it "accepts global c-sources" $ do+        withPackageConfig [i|+          c-sources:+            - cbits/*.c+          executables:+            foo:+              main: driver/Main.hs+          |]+          (do+          touch "cbits/foo.c"+          touch "cbits/bar.c"+          )+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}]})+     context "when reading test section" $ do       it "warns on unknown fields" $ do         withPackageWarnings_ [i|+          name: foo           tests:             foo:               main: Main.hs@@ -975,6 +1048,7 @@     context "when a specified source directory does not exist" $ do       it "warns" $ do         withPackageWarnings [i|+          name: foo           source-dirs:             - some-dir             - some-existing-dir
test/Hpack/RunSpec.hs view
@@ -323,3 +323,11 @@           , "  location: https://github.com/hspec/hspec"           , "  subdir: hspec-core"           ]++  describe "renderDirectories" $ do+    it "replaces . with ./. (for compatibility with cabal syntax)" $ do+      (render defaultRenderSettings 0 $ renderDirectories "name" ["."])+        `shouldBe` [+            "name:"+          , "    ./."+          ]
test/Hpack/UtilSpec.hs view
@@ -97,22 +97,22 @@   describe "expandGlobs" $ around withTempDirectory $ do     it "accepts simple files" $ \dir -> do         touch (dir </> "foo.js")-        expandGlobs dir ["foo.js"] `shouldReturn` ([], ["foo.js"])+        expandGlobs "field-name" dir ["foo.js"] `shouldReturn` ([], ["foo.js"])      it "removes duplicates" $ \dir -> do       touch (dir </> "foo.js")-      expandGlobs dir ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"])+      expandGlobs "field-name" dir ["foo.js", "*.js"] `shouldReturn` ([], ["foo.js"])      it "rejects directories" $ \dir -> do       touch (dir </> "foo")       createDirectory (dir </> "bar")-      expandGlobs dir ["*"] `shouldReturn` ([], ["foo"])+      expandGlobs "field-name" dir ["*"] `shouldReturn` ([], ["foo"])      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]"])+      expandGlobs "field-name" dir ["foo[1,2]"] `shouldReturn` ([], ["foo[1,2]"])      context "when expanding *" $ do       it "expands by extension" $ \dir -> do@@ -122,36 +122,36 @@               , "files/baz.js"]         mapM_ (touch . (dir </>)) files         touch (dir </> "files/foo.hs")-        expandGlobs dir ["files/*.js"] `shouldReturn` ([], sort files)+        expandGlobs "field-name" dir ["files/*.js"] `shouldReturn` ([], sort files)        it "rejects dot-files" $ \dir -> do         touch (dir </> "foo/bar")         touch (dir </> "foo/.baz")-        expandGlobs dir ["foo/*"] `shouldReturn` ([], ["foo/bar"])+        expandGlobs "field-name" dir ["foo/*"] `shouldReturn` ([], ["foo/bar"])        it "accepts dot-files when explicitly asked to" $ \dir -> do         touch (dir </> "foo/bar")         touch (dir </> "foo/.baz")-        expandGlobs dir ["foo/.*"] `shouldReturn` ([], ["foo/.baz"])+        expandGlobs "field-name" dir ["foo/.*"] `shouldReturn` ([], ["foo/.baz"])        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"])+        expandGlobs "field-name" dir ["*/*.js"] `shouldReturn` ([], ["foo/bar.js"])      context "when expanding **" $ do       it "matches arbitrary many directory components" $ \dir -> do         let file = "foo/bar/baz.js"         touch (dir </> file)-        expandGlobs dir ["**/*.js"] `shouldReturn` ([], [file])+        expandGlobs "field-name" dir ["**/*.js"] `shouldReturn` ([], [file])      context "when a pattern does not match anything" $ do       it "warns" $ \dir -> do-        expandGlobs dir ["foo"] `shouldReturn`-          (["Specified pattern \"foo\" for extra-source-files does not match any files"], [])+        expandGlobs "field-name" dir ["foo"] `shouldReturn`+          (["Specified pattern \"foo\" for field-name does not match any files"], [])      context "when a pattern only matches a directory" $ do       it "warns" $ \dir -> do         createDirectory (dir </> "foo")-        expandGlobs dir ["foo"] `shouldReturn`-          (["Specified pattern \"foo\" for extra-source-files does not match any files"], [])+        expandGlobs "field-name" dir ["foo"] `shouldReturn`+          (["Specified pattern \"foo\" for field-name does not match any files"], [])