packages feed

hpack 0.28.2 → 0.29.0

raw patch · 14 files changed

+333/−122 lines, 14 filesdep ~CabalPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Cabal

API changes (from Hackage documentation)

- Hpack.Config: instance (Data.Semigroup.Semigroup cSources, Data.Semigroup.Semigroup cxxSources, Data.Semigroup.Semigroup jsSources) => Data.Semigroup.Semigroup (Hpack.Config.CommonOptions cSources cxxSources jsSources a)
- Hpack.Config: instance (Data.Semigroup.Semigroup cSources, Data.Semigroup.Semigroup cxxSources, Data.Semigroup.Semigroup jsSources, GHC.Base.Monoid cSources, GHC.Base.Monoid cxxSources, GHC.Base.Monoid jsSources) => GHC.Base.Monoid (Hpack.Config.CommonOptions cSources cxxSources jsSources a)
- Hpack.Config: instance Data.Semigroup.Semigroup Hpack.Config.Empty
- Hpack.Config: instance Data.Semigroup.Semigroup Hpack.Config.ExecutableSection
- Hpack.Config: instance Data.Semigroup.Semigroup Hpack.Config.LibrarySection
+ Hpack.Config: [decodeResultCabalVersion] :: DecodeResult -> String
+ Hpack.Config: instance (GHC.Base.Semigroup cSources, GHC.Base.Semigroup cxxSources, GHC.Base.Semigroup jsSources) => GHC.Base.Semigroup (Hpack.Config.CommonOptions cSources cxxSources jsSources a)
+ Hpack.Config: instance (GHC.Base.Semigroup cSources, GHC.Base.Semigroup cxxSources, GHC.Base.Semigroup jsSources, GHC.Base.Monoid cSources, GHC.Base.Monoid cxxSources, GHC.Base.Monoid jsSources) => GHC.Base.Monoid (Hpack.Config.CommonOptions cSources cxxSources jsSources a)
+ Hpack.Config: instance GHC.Base.Semigroup Hpack.Config.Empty
+ Hpack.Config: instance GHC.Base.Semigroup Hpack.Config.ExecutableSection
+ Hpack.Config: instance GHC.Base.Semigroup Hpack.Config.LibrarySection
+ Hpack.Config: verbatimValueToString :: VerbatimValue -> String
- Hpack.Config: DecodeOptions :: FilePath -> Maybe FilePath -> (FilePath -> IO (Either String Value)) -> DecodeOptions
+ Hpack.Config: DecodeOptions :: FilePath -> Maybe FilePath -> FilePath -> IO (Either String Value) -> DecodeOptions
- Hpack.Config: DecodeResult :: Package -> FilePath -> [String] -> DecodeResult
+ Hpack.Config: DecodeResult :: Package -> String -> FilePath -> [String] -> DecodeResult

Files

CHANGELOG.md view
@@ -1,4 +1,12 @@-## next+## Changes in 0.29.0+  - Put the `cabal-version` at the beginning of the generated file. This Is+    required with `cabal-version: 2.1` and higher. (see #292)+  - With `cabal-version: 2.1` or higher omit `>=` when rendering (see #292)+  - Require `cabal-version: 2.2` when SPDX license identifiers are used (see #292)+  - Map cabal-style licenses to SPDX license identifiers when `cabal-version`+    is 2.2 or higher (see #292)++## Changes in 0.28.2   - Exit with `exitFailure` on `AlreadyGeneratedByNewerHpack` or     `ExistingCabalFileWasModifiedManually` in `Hpack.printResult` 
hpack.cabal view
@@ -1,11 +1,13 @@--- This file has been generated from package.yaml by hpack version 0.27.0.+cabal-version: >= 1.10++-- This file has been generated from package.yaml by hpack version 0.29.0. -- -- see: https://github.com/sol/hpack ----- hash: 5391105d37fea2b976290b95e847c0d2da5ea7e0ef9ae9e5cf8945911dd983a1+-- hash: cfd597be64fbc0242e6c338653cce17e853d1ce5843d07785f81ce0f208ee198  name:           hpack-version:        0.28.2+version:        0.29.0 synopsis:       An alternative format for Haskell packages description:    See README at <https://github.com/sol/hpack#readme> category:       Development@@ -15,8 +17,6 @@ license:        MIT license-file:   LICENSE build-type:     Simple-cabal-version:  >= 1.10- extra-source-files:     CHANGELOG.md @@ -29,7 +29,7 @@       src   ghc-options: -Wall   build-depends:-      Cabal+      Cabal >=2.2     , Glob >=0.9.0     , aeson >=1.2.1.0     , base >=4.9 && <5@@ -63,6 +63,7 @@       Hpack.CabalFile       Hpack.Defaults       Hpack.Haskell+      Hpack.License       Hpack.Options       Hpack.Render.Dsl       Hpack.Render.Hints@@ -80,7 +81,7 @@       driver   ghc-options: -Wall   build-depends:-      Cabal+      Cabal >=2.2     , Glob >=0.9.0     , aeson >=1.2.1.0     , base >=4.9 && <5@@ -115,7 +116,7 @@   ghc-options: -Wall   cpp-options: -DTEST   build-depends:-      Cabal+      Cabal >=2.2     , Glob >=0.9.0     , HUnit >=1.6.0.0     , QuickCheck@@ -153,6 +154,7 @@       Hpack.ConfigSpec       Hpack.DefaultsSpec       Hpack.HaskellSpec+      Hpack.LicenseSpec       Hpack.OptionsSpec       Hpack.Render.DslSpec       Hpack.Render.HintsSpec@@ -172,6 +174,7 @@       Hpack.Config       Hpack.Defaults       Hpack.Haskell+      Hpack.License       Hpack.Options       Hpack.Render       Hpack.Render.Dsl
src/Hpack.hs view
@@ -164,19 +164,21 @@  hpackResultWithVersion :: Version -> Options -> IO Result hpackResultWithVersion v (Options options force toStdout) = do-  DecodeResult pkg cabalFile warnings <- readPackageConfig options >>= either die return+  DecodeResult pkg cabalVersion cabalFile warnings <- readPackageConfig options >>= either die return   oldCabalFile <- readCabalFile cabalFile-  let new = renderPackage (maybe [] cabalFileContents oldCabalFile) pkg   let+    body = renderPackage (maybe [] cabalFileContents oldCabalFile) pkg+    withoutHeader = cabalVersion ++ body+  let     status = case force of       Force -> Generated-      NoForce -> maybe Generated (mkStatus (lines new) v) oldCabalFile+      NoForce -> maybe Generated (mkStatus (lines withoutHeader) v) oldCabalFile   case status of     Generated -> do-      let hash = sha256 new+      let hash = sha256 withoutHeader       if toStdout-        then Utf8.putStr new-        else Utf8.writeFile cabalFile (header (decodeOptionsTarget options) v hash ++ new)+        then Utf8.putStr withoutHeader+        else Utf8.writeFile cabalFile (cabalVersion ++ header (decodeOptionsTarget options) v hash ++ body)     _ -> return ()   return Result {       resultWarnings = warnings
src/Hpack/CabalFile.hs view
@@ -28,7 +28,12 @@     parse (splitHeader -> (h, c)) = CabalFile (extractVersion h) (extractHash h) c      splitHeader :: String -> ([String], [String])-    splitHeader = fmap (dropWhile null) . span ("--" `isPrefixOf`) . removeGitConflictMarkers . lines+    splitHeader (removeGitConflictMarkers . lines -> c) =+      case span (not . isComment) c of+        (cabalVersion, xs) -> case span isComment xs of+          (header, body) -> (header, cabalVersion ++ dropWhile null body)++    isComment = ("--" `isPrefixOf`)  extractHash :: [String] -> Maybe Hash extractHash = extract "-- hash: " Just
src/Hpack/Config.hs view
@@ -44,6 +44,7 @@ , GhcOption , Verbatim(..) , VerbatimValue(..)+, verbatimValueToString , CustomSetup(..) , Section(..) , Library(..)@@ -71,7 +72,7 @@ ) where  import           Control.Applicative-import           Control.Arrow ((>>>))+import           Control.Arrow ((>>>), (&&&)) import           Control.Monad import           Data.Bifunctor import           Data.Bitraversable@@ -91,7 +92,10 @@ import           Control.Monad.Trans.Writer import           Control.Monad.Trans.Except import           Control.Monad.IO.Class+import           Data.Version +import           Distribution.Pretty (prettyShow)+ import           Data.Aeson.Config.Types import           Data.Aeson.Config.FromValue hiding (decodeValue) import qualified Data.Aeson.Config.FromValue as Config@@ -102,6 +106,7 @@ import           Hpack.Defaults import qualified Hpack.Yaml as Yaml import           Hpack.Syntax.Dependency+import           Hpack.License  package :: String -> String -> Package package name version = Package {@@ -562,6 +567,7 @@  data DecodeResult = DecodeResult {   decodeResultPackage :: Package+, decodeResultCabalVersion :: String , decodeResultCabalFile :: FilePath , decodeResultWarnings :: [String] } deriving (Eq, Show)@@ -575,12 +581,123 @@   toPackage userDataDir dir config   where     addCabalFile :: (Package, [String]) -> DecodeResult-    addCabalFile (pkg, warnings) = DecodeResult pkg (takeDirectory_ file </> (packageName pkg ++ ".cabal")) warnings+    addCabalFile (pkg, warnings) = uncurry DecodeResult (cabalVersion pkg) (takeDirectory_ file </> (packageName pkg ++ ".cabal")) warnings      takeDirectory_ :: FilePath -> FilePath     takeDirectory_ p       | takeFileName p == p = ""       | otherwise = takeDirectory p++deleteVerbatimField :: String -> [Verbatim] -> [Verbatim]+deleteVerbatimField name = map $ \ case+  literal@VerbatimLiteral {} -> literal+  VerbatimObject o -> VerbatimObject (Map.delete name o)++verbatimValueToString :: VerbatimValue -> String+verbatimValueToString = \ case+  VerbatimString s -> s+  VerbatimNumber n -> scientificToVersion n+  VerbatimBool b -> show b+  VerbatimNull -> ""++cabalVersion :: Package -> (Package, String)+cabalVersion pkg@Package{..} = (+    pkg {+        packageVerbatim = deleteVerbatimField "cabal-version" packageVerbatim+      , packageLicense = formatLicense <$> parsedLicense+      }+  , "cabal-version: " ++ fromMaybe inferredCabalVersion verbatimCabalVersion ++ "\n\n"+  )+  where+    parsedLicense = (fmap prettyShow . parseLicense &&& id) <$> packageLicense++    formatLicense = \ case+      (MustSPDX spdx, _) -> spdx+      (CanSPDX spdx, _) | version >= makeVersion [2,2] -> spdx+      (CanSPDX _, original) -> original+      (DontTouch, original) -> original++    mustSPDX :: Bool+    mustSPDX = maybe False (f . fst) parsedLicense+      where+        f = \case+          DontTouch -> False+          CanSPDX _ -> False+          MustSPDX _ -> True++    verbatimCabalVersion :: Maybe String+    verbatimCabalVersion = listToMaybe (mapMaybe f packageVerbatim)+      where+        f :: Verbatim -> Maybe String+        f = \ case+          VerbatimLiteral _ -> Nothing+          VerbatimObject o -> case Map.lookup "cabal-version" o of+            Just v -> Just (verbatimValueToString v)+            Nothing -> Nothing++    inferredCabalVersion :: String+    inferredCabalVersion+      | version >= makeVersion [2,1] = showVersion version+      | otherwise = (">= " ++) . showVersion $ version++    version = fromMaybe (makeVersion [1,10]) $ maximum [+        packageCabalVersion+      , packageLibrary >>= libraryCabalVersion+      , internalLibsCabalVersion packageInternalLibraries+      , executablesCabalVersion packageExecutables+      , executablesCabalVersion packageTests+      , executablesCabalVersion packageBenchmarks+      ]++    packageCabalVersion :: Maybe Version+    packageCabalVersion = maximum [+        Nothing+      , makeVersion [2,2] <$ guard mustSPDX+      , makeVersion [1,24] <$ packageCustomSetup+      , makeVersion [1,18] <$ guard (not (null packageExtraDocFiles))+      ]++    libraryCabalVersion :: Section Library -> Maybe Version+    libraryCabalVersion sect = maximum [+        makeVersion [1,22] <$ guard hasReexportedModules+      , makeVersion [2,0]  <$ guard hasSignatures+      , makeVersion [2,0] <$ guard hasGeneratedModules+      , makeVersion [2,2] <$ guard (hasCxxParams sect)+      ]+      where+        hasReexportedModules = any (not . null . libraryReexportedModules) sect+        hasSignatures = any (not . null . librarySignatures) sect+        hasGeneratedModules = any (not . null . libraryGeneratedModules) sect++    internalLibsCabalVersion :: Map String (Section Library) -> Maybe Version+    internalLibsCabalVersion internalLibraries+      | Map.null internalLibraries = Nothing+      | otherwise = foldr max (Just $ makeVersion [2,0]) versions+      where+        versions = libraryCabalVersion <$> Map.elems internalLibraries++    executablesCabalVersion :: Map String (Section Executable) -> Maybe Version+    executablesCabalVersion = foldr max Nothing . map executableCabalVersion . Map.elems++    executableCabalVersion :: Section Executable -> Maybe Version+    executableCabalVersion sect = maximum [+        makeVersion [2,0] <$ guard (executableHasGeneratedModules sect)+      , makeVersion [2,2] <$ guard (hasCxxParams sect)+      ]++    executableHasGeneratedModules :: Section Executable -> Bool+    executableHasGeneratedModules = any (not . null . executableGeneratedModules)++    hasCxxParams :: Section a -> Bool+    hasCxxParams sect = or [+        check sect+      , any (any check) (sectionConditionals sect)+      ]+      where+        check s = or [+            (not . null . sectionCxxOptions) s+          , (not . null . sectionCxxSources) s+          ]  decodeValue :: FromValue a => FilePath -> Value -> Warnings (Errors IO) a decodeValue file value = do
+ src/Hpack/License.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE DeriveFunctor #-}+module Hpack.License where++import qualified Distribution.License as Cabal+import qualified Distribution.SPDX.License as SPDX+import           Distribution.Parsec.Class (eitherParsec)++data License a = DontTouch | CanSPDX a | MustSPDX a+  deriving (Eq, Show, Functor)++parseLicense :: String -> License SPDX.License+parseLicense license = case spdxLicense of+  Right l | isUnknown -> MustSPDX l+  Left  _ | isUnknown -> DontTouch+  Right l -> CanSPDX l+  Left  _ -> case cabalLicense of+    Right l -> CanSPDX (Cabal.licenseToSPDX l)+    Left _ -> DontTouch+  where+    spdxLicense :: Either String SPDX.License+    spdxLicense  = eitherParsec license++    cabalLicense :: Either String Cabal.License+    cabalLicense = eitherParsec license++    isUnknown = license `notElem` knownLicenses++    knownLicenses = [+        "GPL"+      , "GPL-2"+      , "GPL-3"+      , "LGPL"+      , "LGPL-2.1"+      , "LGPL-3"+      , "AGPL"+      , "AGPL-3"+      , "BSD2"+      , "BSD3"+      , "BSD4"+      , "MIT"+      , "ISC"+      , "MPL-2.0"+      , "Apache"+      , "Apache-2.0"+      , "PublicDomain"+      , "AllRightsReserved"+      , "OtherLicense"+      ]
src/Hpack/Render.hs view
@@ -38,13 +38,11 @@ import           Data.Char import           Data.Maybe import           Data.List-import           Data.Version import           Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map  import           Hpack.Util import           Hpack.Config-import           Hpack.Syntax.Dependency (scientificToVersion) import           Hpack.Render.Hints import           Hpack.Render.Dsl @@ -112,7 +110,6 @@           files  -> ("license-files", formatList files)       , ("tested-with", packageTestedWith)       , ("build-type", Just (show packageBuildType))-      , ("cabal-version", cabalVersion)       ]      formatList :: [String] -> Maybe String@@ -120,66 +117,6 @@       where         separator = let Alignment n = headerFieldsAlignment in ",\n" ++ replicate n ' ' -    cabalVersion :: Maybe String-    cabalVersion = (">= " ++) . showVersion <$> maximum [-        Just (makeVersion [1,10])-      , packageCabalVersion-      , packageLibrary >>= libraryCabalVersion-      , internalLibsCabalVersion packageInternalLibraries-      , executablesCabalVersion packageExecutables-      , executablesCabalVersion packageTests-      , executablesCabalVersion packageBenchmarks-      ]-     where-      packageCabalVersion :: Maybe Version-      packageCabalVersion = maximum [-          Nothing-        , makeVersion [1,24] <$ packageCustomSetup-        , makeVersion [1,18] <$ guard (not (null packageExtraDocFiles))-        ]--      libraryCabalVersion :: Section Library -> Maybe Version-      libraryCabalVersion sect = maximum [-          makeVersion [1,22] <$ guard hasReexportedModules-        , makeVersion [2,0]  <$ guard hasSignatures-        , makeVersion [2,0] <$ guard hasGeneratedModules-        , makeVersion [2,2] <$ guard (hasCxxParams sect)-        ]-        where-          hasReexportedModules = any (not . null . libraryReexportedModules) sect-          hasSignatures = any (not . null . librarySignatures) sect-          hasGeneratedModules = any (not . null . libraryGeneratedModules) sect--      internalLibsCabalVersion :: Map String (Section Library) -> Maybe Version-      internalLibsCabalVersion internalLibraries-        | Map.null internalLibraries = Nothing-        | otherwise = foldr max (Just $ makeVersion [2,0]) versions-        where-          versions = libraryCabalVersion <$> Map.elems internalLibraries--      executablesCabalVersion :: Map String (Section Executable) -> Maybe Version-      executablesCabalVersion = foldr max Nothing . map executableCabalVersion . Map.elems--      executableCabalVersion :: Section Executable -> Maybe Version-      executableCabalVersion sect = maximum [-          makeVersion [2,0] <$ guard (executableHasGeneratedModules sect)-        , makeVersion [2,2] <$ guard (hasCxxParams sect)-        ]--      executableHasGeneratedModules :: Section Executable -> Bool-      executableHasGeneratedModules = any (not . null . executableGeneratedModules)--      hasCxxParams :: Section a -> Bool-      hasCxxParams sect = or [-          check sect-        , any (any check) (sectionConditionals sect)-        ]-        where-          check s = or [-              (not . null . sectionCxxOptions) s-            , (not . null . sectionCxxSources) s-            ]- sortStanzaFields :: [(String, [String])] -> [Element] -> [Element] sortStanzaFields sectionsFieldOrder = go   where@@ -336,13 +273,9 @@ renderVerbatimObject :: Map String VerbatimValue -> [Element] renderVerbatimObject = map renderPair . Map.toList   where-    renderPair (key, value) = case value of-      VerbatimString s -> case lines s of-        [x] -> Field key (Literal x)-        xs -> Field key (LineSeparatedList xs)-      VerbatimNumber n -> Field key (Literal $ scientificToVersion n)-      VerbatimBool b -> Field key (Literal $ show b)-      VerbatimNull -> Field key (Literal "")+    renderPair (key, value) = case lines (verbatimValueToString value) of+      [x] -> Field key (Literal x)+      xs -> Field key (LineSeparatedList xs)  renderConditional :: (a -> [Element]) -> Conditional (Section a) -> Element renderConditional renderSectionData (Conditional condition sect mElse) = case mElse of
test/EndToEndSpec.hs view
@@ -299,6 +299,58 @@         version: {}         |] `shouldFailWith` "package.yaml: Error while parsing $.version - expected Number or String, encountered Object" +    describe "license" $ do+      it "accepts cabal-style licenses" $ do+        [i|+        license: BSD3+        |] `shouldRenderTo` (package [i|+        license: BSD3+        |])++      it "accepts SPDX licenses" $ do+        [i|+        license: BSD-3-Clause+        |] `shouldRenderTo` (package [i|+        license: BSD-3-Clause+        |]) {packageCabalVersion = "2.2"}++      context "with an ambiguous license" $ do+        it "treats it as a cabal-style license" $ do+          [i|+          license: MIT+          |] `shouldRenderTo` (package [i|+          license: MIT+          |])++      context "when cabal-version >= 2.2" $ do+        it "maps license to SPDX license identifier" $ do+          [i|+          license: BSD3+          library:+            cxx-options: -Wall+          |] `shouldRenderTo` (package [i|+          license: BSD-3-Clause+          library+            other-modules:+                Paths_foo+            cxx-options: -Wall+            default-language: Haskell2010+          |]) {packageCabalVersion = "2.2"}++        it "doesn't touch unknown licenses" $ do+          [i|+          license: some-license+          library:+            cxx-options: -Wall+          |] `shouldRenderTo` (package [i|+          license: some-license+          library+            other-modules:+                Paths_foo+            cxx-options: -Wall+            default-language: Haskell2010+          |]) {packageCabalVersion = "2.2"}+     describe "build-type" $ do       it "accept Simple" $ do         [i|@@ -476,7 +528,7 @@           cxx-options: -Wall         |] `shouldRenderTo` (executable_ "foo" [i|         cxx-options: -Wall-        |]) {packageCabalVersion = ">= 2.2"}+        |]) {packageCabalVersion = "2.2"}      describe "cxx-sources" $ before_ (touch "foo.cc" >> touch "cxxbits/bar.cc") $ do       it "accepts cxx-sources" $ do@@ -489,7 +541,7 @@         cxx-sources:             cxxbits/bar.cc             foo.cc-        |]) {packageCabalVersion = ">= 2.2"}+        |]) {packageCabalVersion = "2.2"}      describe "extra-lib-dirs" $ do       it "accepts extra-lib-dirs" $ do@@ -1240,12 +1292,12 @@ run_ userDataDir c old = do   mPackage <- readPackageConfig defaultDecodeOptions {decodeOptionsTarget = c, decodeOptionsUserDataDir = Just userDataDir}   return $ case mPackage of-    Right (DecodeResult pkg _ warnings) ->+    Right (DecodeResult pkg cabalVersion _ warnings) ->       let         FormattingHints{..} = sniffFormattingHints (lines old)         alignment = fromMaybe 0 formattingHintsAlignment         settings = formattingHintsRenderSettings-        output = Hpack.renderPackageWith settings alignment formattingHintsFieldOrder formattingHintsSectionsFieldOrder pkg+        output = cabalVersion ++ Hpack.renderPackageWith settings alignment formattingHintsFieldOrder formattingHintsSectionsFieldOrder pkg       in         Right (warnings, output)     Left err -> Left err@@ -1349,10 +1401,10 @@  renderPackage :: Package -> String renderPackage Package{..} = unindent [i|+cabal-version: #{packageCabalVersion} name: #{packageName} version: #{packageVersion} build-type: #{packageBuildType}-cabal-version: #{packageCabalVersion}  #{unindent packageContent} |]
test/Helper.hs view
@@ -3,6 +3,7 @@ module Helper (   module Test.Hspec , module Test.Mockery.Directory+, module Control.Monad , module Control.Applicative , withTempDirectory , module System.FilePath@@ -12,6 +13,7 @@  import           Test.Hspec import           Test.Mockery.Directory+import           Control.Monad import           Control.Applicative import           System.Directory (getCurrentDirectory, setCurrentDirectory, canonicalizePath) import           Control.Exception
test/Hpack/CabalFileSpec.hs view
@@ -4,7 +4,6 @@ import           Helper import           Test.QuickCheck import           Data.Version (showVersion)-import           Control.Monad import           Data.String.Interpolate import           Data.String.Interpolate.Util @@ -17,12 +16,18 @@ spec = do   describe "readCabalFile" $ do     let-      file = "package.yaml"+      file = "hello.cabal"       hash = "some-hash"+     it "includes hash" $ do       inTempDirectory $ do-        writeFile file $ header file version hash+        writeFile file $ header "package.yaml" version hash         readCabalFile file `shouldReturn` Just (CabalFile (Just version) (Just hash) [])++    it "accepts cabal-version at the beginning of the file" $ do+      inTempDirectory $ do+        writeFile file $ ("cabal-version: 2.2\n" ++ header "package.yaml" version hash)+        readCabalFile file `shouldReturn` Just (CabalFile (Just version) (Just hash) ["cabal-version: 2.2"])    describe "extractVersion" $ do     it "extracts Hpack version from a cabal file" $ do
test/Hpack/ConfigSpec.hs view
@@ -59,7 +59,7 @@   writeFile (dir </> "package.yaml") content   withCurrentDirectory dir beforeAction   r <- readPackageConfig (testDecodeOptions $ dir </> "package.yaml")-  either expectationFailure (\ (DecodeResult p _ warnings) -> expectation (p, warnings)) r+  either expectationFailure (\ (DecodeResult p _ _ warnings) -> expectation (p, warnings)) r  withPackageConfig :: String -> IO () -> (Package -> Expectation) -> Expectation withPackageConfig content beforeAction expectation = withPackage content beforeAction (expectation . fst)
+ test/Hpack/LicenseSpec.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE QuasiQuotes #-}+module Hpack.LicenseSpec (spec) where++import           Helper+import           Data.String.Interpolate++import           Distribution.Pretty (prettyShow)++import           Hpack.License++cabalLicenses :: [(String, License String)]+cabalLicenses = [+    ("GPL",               CanSPDX "LicenseRef-GPL")+  , ("GPL-2",             CanSPDX "GPL-2.0-only")+  , ("GPL-3",             CanSPDX "GPL-3.0-only")++  , ("LGPL",              CanSPDX "LicenseRef-LGPL")+  , ("LGPL-2.1",          CanSPDX "LGPL-2.1-only")+  , ("LGPL-3",            CanSPDX "LGPL-3.0-only")++  , ("AGPL",              CanSPDX "LicenseRef-AGPL")+  , ("AGPL-3",            CanSPDX "AGPL-3.0-only")+++  , ("BSD2",              CanSPDX "BSD-2-Clause")+  , ("BSD3",              CanSPDX "BSD-3-Clause")+  , ("BSD4",              CanSPDX "BSD-4-Clause")++  , ("MIT",               CanSPDX "MIT")+  , ("ISC",               CanSPDX "ISC")++  , ("MPL-2.0",           CanSPDX "MPL-2.0")++  , ("Apache",            CanSPDX "LicenseRef-Apache")+  , ("Apache-2.0",        CanSPDX "Apache-2.0")++  , ("PublicDomain",      CanSPDX "LicenseRef-PublicDomain")+  , ("OtherLicense",      CanSPDX "LicenseRef-OtherLicense")+  , ("AllRightsReserved", CanSPDX "NONE")+  ]++spdxLicenses :: [(String, License String)]+spdxLicenses = [+    ("GPL-2.0-or-later",  MustSPDX "GPL-2.0-or-later")+  ]++unknownLicenses :: [(String, License String)]+unknownLicenses = [+    ("some-license",      DontTouch)+  ]++spec :: Spec+spec = do+  describe "parseLicense" $ do+    forM_ (cabalLicenses ++ spdxLicenses ++ unknownLicenses) $ \ (license, expected) -> do+      it [i|parses #{license}|] $ do+        prettyShow <$> parseLicense license `shouldBe` expected
test/Hpack/RenderSpec.hs view
@@ -28,7 +28,6 @@           "name: foo"         , "version: 0.0.0"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         ]      it "aligns fields" $ do@@ -36,7 +35,6 @@           "name:           foo"         , "version:        0.0.0"         , "build-type:     Simple"-        , "cabal-version:  >= 1.10"         ]      it "includes description" $ do@@ -47,7 +45,6 @@         , "             ."         , "             bar"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         ]      it "aligns description" $ do@@ -58,7 +55,6 @@         , "                ."         , "                bar"         , "build-type:     Simple"-        , "cabal-version:  >= 1.10"         ]      it "includes stability" $ do@@ -67,7 +63,6 @@         , "version: 0.0.0"         , "stability: experimental"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         ]      it "includes license-file" $ do@@ -76,7 +71,6 @@         , "version: 0.0.0"         , "license-file: FOO"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         ]      it "aligns license-files" $ do@@ -86,7 +80,6 @@         , "license-files:  FOO,"         , "                BAR"         , "build-type:     Simple"-        , "cabal-version:  >= 1.10"         ]      it "includes copyright holder" $ do@@ -95,7 +88,6 @@         , "version: 0.0.0"         , "copyright: (c) 2015 Simon Hengel"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         ]      it "aligns copyright holders" $ do@@ -105,7 +97,6 @@         , "copyright:      (c) 2015 Foo,"         , "                (c) 2015 Bar"         , "build-type:     Simple"-        , "cabal-version:  >= 1.10"         ]      it "includes extra-source-files" $ do@@ -113,7 +104,6 @@           "name: foo"         , "version: 0.0.0"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         , "extra-source-files:"         , "    foo"         , "    bar"@@ -124,7 +114,6 @@           "name: foo"         , "version: 0.0.0"         , "build-type: Simple"-        , "cabal-version: >= 1.10"         , ""         , "library"         , "  buildable: False"@@ -137,7 +126,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "library"           , "  default-language: Haskell2010"@@ -145,19 +133,17 @@      context "when given list of existing fields" $ do       it "retains field order" $ do-        renderPackageWith defaultRenderSettings 16 ["cabal-version", "version", "name", "build-type"] [] package `shouldBe` unlines [-            "cabal-version:  >= 1.10"-          , "version:        0.0.0"-          , "name:           foo"+        renderPackageWith defaultRenderSettings 16 ["version", "build-type", "name"] [] package `shouldBe` unlines [+            "version:        0.0.0"           , "build-type:     Simple"+          , "name:           foo"           ]        it "uses default field order for new fields" $ do-        renderPackageWith defaultRenderSettings 16 ["name", "version", "cabal-version"] [] package `shouldBe` unlines [+        renderPackageWith defaultRenderSettings 16 [] [] package `shouldBe` unlines [             "name:           foo"           , "version:        0.0.0"           , "build-type:     Simple"-          , "cabal-version:  >= 1.10"           ]        it "retains section field order" $ do@@ -165,7 +151,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  default-language: Haskell2010"@@ -180,7 +165,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  main-is: Main.hs"@@ -195,7 +179,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  main-is: Main.hs"@@ -208,7 +191,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  main-is: Main.hs"@@ -223,7 +205,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  main-is: Main.hs"@@ -238,7 +219,6 @@             "name: foo"           , "version: 0.0.0"           , "build-type: Simple"-          , "cabal-version: >= 1.10"           , ""           , "executable foo"           , "  main-is: Main.hs"
test/Hpack/Syntax/GitSpec.hs view
@@ -3,7 +3,6 @@  import           Helper import           Data.String.Interpolate-import           Control.Monad  import           Hpack.Syntax.Git