Hello community, here is the log from the commit of package hpack for openSUSE:Factory checked in at 2017-03-03 17:53:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hpack (Old) and /work/SRC/openSUSE:Factory/.hpack.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "hpack" Fri Mar 3 17:53:02 2017 rev:5 rq:461705 version:0.17.0 Changes: -------- --- /work/SRC/openSUSE:Factory/hpack/hpack.changes 2016-08-28 12:18:08.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.hpack.new/hpack.changes 2017-03-03 17:53:03.336911782 +0100 @@ -1,0 +2,5 @@ +Sun Feb 12 14:16:09 UTC 2017 - psimons@suse.com + +- Update to version 0.17.0 with cabal2obs. + +------------------------------------------------------------------- Old: ---- 1.cabal hpack-0.14.1.tar.gz New: ---- hpack-0.17.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hpack.spec ++++++ --- /var/tmp/diff_new_pack.wURx9b/_old 2017-03-03 17:53:03.812844561 +0100 +++ /var/tmp/diff_new_pack.wURx9b/_new 2017-03-03 17:53:03.812844561 +0100 @@ -1,7 +1,7 @@ # # spec file for package hpack # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,19 +19,19 @@ %global pkg_name hpack %bcond_with tests Name: %{pkg_name} -Version: 0.14.1 +Version: 0.17.0 Release: 0 Summary: An alternative format for Haskell packages License: MIT Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{name} Source0: https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.tar.gz -Source1: https://hackage.haskell.org/package/%{name}-%{version}/revision/1.cabal BuildRequires: chrpath BuildRequires: ghc-Cabal-devel BuildRequires: ghc-Glob-devel BuildRequires: ghc-aeson-devel BuildRequires: ghc-base-compat-devel +BuildRequires: ghc-bytestring-devel BuildRequires: ghc-containers-devel BuildRequires: ghc-deepseq-devel BuildRequires: ghc-directory-devel @@ -51,7 +51,7 @@ %endif %description -An alternative format for Haskell packages. +See README at https://github.com/sol/hpack#readme. %package -n ghc-%{name} Summary: Haskell %{name} library @@ -73,14 +73,13 @@ %prep %setup -q -cp -p %{SOURCE1} %{name}.cabal %build %ghc_lib_build %install %ghc_lib_install -%ghc_fix_dynamic_rpath %{pkg_name} +%ghc_fix_rpath %{pkg_name}-%{version} %check %cabal_test ++++++ hpack-0.14.1.tar.gz -> hpack-0.17.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/hpack.cabal new/hpack-0.17.0/hpack.cabal --- old/hpack-0.14.1/hpack.cabal 2016-06-10 16:09:36.000000000 +0200 +++ new/hpack-0.17.0/hpack.cabal 2017-01-30 02:24:20.000000000 +0100 @@ -1,10 +1,11 @@ --- This file has been generated from package.yaml by hpack version 0.14.0. +-- This file has been generated from package.yaml by hpack version 0.15.0. -- -- see: https://github.com/sol/hpack name: hpack -version: 0.14.1 +version: 0.17.0 synopsis: An alternative format for Haskell packages +description: See README at https://github.com/sol/hpack#readme category: Development homepage: https://github.com/sol/hpack#readme bug-reports: https://github.com/sol/hpack/issues @@ -25,6 +26,7 @@ build-depends: base >= 4.7 && < 5 , base-compat >= 0.8 + , bytestring , deepseq , directory , filepath @@ -33,7 +35,7 @@ , containers , unordered-containers , yaml - , aeson >= 0.8 + , aeson >= 0.11 exposed-modules: Hpack Hpack.Config @@ -56,6 +58,7 @@ build-depends: base >= 4.7 && < 5 , base-compat >= 0.8 + , bytestring , deepseq , directory , filepath @@ -64,8 +67,8 @@ , containers , unordered-containers , yaml + , aeson >= 0.11 , hpack - , aeson >= 0.8 default-language: Haskell2010 test-suite spec @@ -79,6 +82,7 @@ build-depends: base >= 4.7 && < 5 , base-compat >= 0.8 + , bytestring , deepseq , directory , filepath @@ -87,13 +91,13 @@ , containers , unordered-containers , yaml + , aeson >= 0.11 , hspec == 2.* , QuickCheck , temporary , mockery >= 0.3 , interpolate , aeson-qq - , aeson >= 0.10 other-modules: Helper Hpack.ConfigSpec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/src/Hpack/Config.hs new/hpack-0.17.0/src/Hpack/Config.hs --- old/hpack-0.14.1/src/Hpack/Config.hs 2016-06-10 15:09:58.000000000 +0200 +++ new/hpack-0.17.0/src/Hpack/Config.hs 2017-01-30 00:09:54.000000000 +0100 @@ -5,6 +5,7 @@ {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -23,6 +24,7 @@ , GitUrl , GitRef , GhcOption +, CustomSetup(..) , Section(..) , Library(..) , Executable(..) @@ -36,6 +38,7 @@ , Empty(..) , getModules , determineModules +, BuildType(..) #endif ) where @@ -46,7 +49,7 @@ import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map import qualified Data.HashMap.Lazy as HashMap -import Data.List.Compat (nub, (\\), sortBy) +import Data.List.Compat (nub, (\\), sortBy, isPrefixOf) import Data.Maybe import Data.Ord import Data.String @@ -63,7 +66,32 @@ import Hpack.Yaml package :: String -> String -> Package -package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Nothing Nothing Nothing [] [] [] Nothing Nothing [] [] [] +package name version = Package { + packageName = name + , packageVersion = version + , packageSynopsis = Nothing + , packageDescription = Nothing + , packageHomepage = Nothing + , packageBugReports = Nothing + , packageCategory = Nothing + , packageStability = Nothing + , packageAuthor = [] + , packageMaintainer = [] + , packageCopyright = [] + , packageBuildType = Simple + , packageLicense = Nothing + , packageLicenseFile = Nothing + , packageTestedWith = Nothing + , packageFlags = [] + , packageExtraSourceFiles = [] + , packageDataFiles = [] + , packageSourceRepository = Nothing + , packageCustomSetup = Nothing + , packageLibrary = Nothing + , packageExecutables = [] + , packageTests = [] + , packageBenchmarks = [] + } renamePackage :: String -> Package -> Package renamePackage name p@Package{..} = p { @@ -91,7 +119,7 @@ ++ maybe [] sectionDependencies packageLibrary section :: a -> Section a -section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] +section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] [] packageConfig :: FilePath packageConfig = "package.yaml" @@ -99,7 +127,11 @@ githubBaseUrl :: String githubBaseUrl = "https://github.com/" +#if MIN_VERSION_aeson(1,0,0) +genericParseJSON_ :: forall a. (Generic a, GFromJSON Zero (Rep a), HasTypeName a) => Value -> Parser a +#else genericParseJSON_ :: forall a. (Generic a, GFromJSON (Rep a), HasTypeName a) => Value -> Parser a +#endif genericParseJSON_ = genericParseJSON defaultOptions {fieldLabelModifier = hyphenize name} where name :: String @@ -122,6 +154,9 @@ default fieldNames :: (HasTypeName a, Selectors (Rep a)) => Proxy a -> [String] fieldNames proxy = map (hyphenize $ typeName proxy) (selectors proxy) + ignoreUnderscoredUnknownFields :: Proxy a -> Bool + ignoreUnderscoredUnknownFields _ = False + data CaptureUnknownFields a = CaptureUnknownFields { captureUnknownFieldsFields :: [FieldName] , captureUnknownFieldsValue :: a @@ -139,18 +174,33 @@ where unknownSectionFields = getUnknownFields v (Proxy :: Proxy (Section a)) +instance FromJSON (CaptureUnknownFields CustomSetupSection) where + parseJSON = captureUnknownFields + instance FromJSON (CaptureUnknownFields FlagSection) where parseJSON = captureUnknownFields getUnknownFields :: forall a. HasFieldNames a => Value -> Proxy a -> [FieldName] getUnknownFields v _ = case v of - Object o -> unknown + Object o -> ignoreUnderscored unknown where unknown = keys \\ fields keys = map T.unpack (HashMap.keys o) fields = fieldNames (Proxy :: Proxy a) + ignoreUnderscored + | ignoreUnderscoredUnknownFields (Proxy :: Proxy a) = filter (not . isPrefixOf "_") + | otherwise = id _ -> [] +data CustomSetupSection = CustomSetupSection { + customSetupSectionDependencies :: Maybe (List Dependency) +} deriving (Eq, Show, Generic) + +instance HasFieldNames CustomSetupSection + +instance FromJSON CustomSetupSection where + parseJSON = genericParseJSON_ + data LibrarySection = LibrarySection { librarySectionExposed :: Maybe Bool , librarySectionExposedModules :: Maybe (List String) @@ -181,6 +231,7 @@ , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption) , commonOptionsCppOptions :: Maybe (List CppOption) +, commonOptionsCcOptions :: Maybe (List CcOption) , commonOptionsCSources :: Maybe (List FilePath) , commonOptionsExtraLibDirs :: Maybe (List FilePath) , commonOptionsExtraLibraries :: Maybe (List FilePath) @@ -241,6 +292,22 @@ instance HasFieldNames Empty where fieldNames _ = [] +-- From Cabal the library, copied here to avoid a dependency on Cabal. +data BuildType + = Simple + | Configure + | Make + | Custom + deriving (Eq, Show, Generic) + +instance FromJSON BuildType where + parseJSON = withText "String" $ \case + "Simple" -> return Simple + "Configure" -> return Configure + "Make" -> return Make + "Custom" -> return Custom + _ -> fail "build-type must be one of: Simple, Configure, Make, Custom" + data PackageConfig = PackageConfig { packageConfigName :: Maybe String , packageConfigVersion :: Maybe String @@ -253,6 +320,7 @@ , packageConfigAuthor :: Maybe (List String) , packageConfigMaintainer :: Maybe (List String) , packageConfigCopyright :: Maybe (List String) +, packageConfigBuildType :: Maybe BuildType , packageConfigLicense :: Maybe String , packageConfigLicenseFile :: Maybe String , packageConfigTestedWith :: Maybe String @@ -261,13 +329,15 @@ , packageConfigDataFiles :: Maybe (List FilePath) , packageConfigGithub :: Maybe Text , packageConfigGit :: Maybe String +, packageConfigCustomSetup :: Maybe (CaptureUnknownFields CustomSetupSection) , packageConfigLibrary :: Maybe (CaptureUnknownFields (Section LibrarySection)) , packageConfigExecutables :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) , packageConfigTests :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) , packageConfigBenchmarks :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) } deriving (Eq, Show, Generic) -instance HasFieldNames PackageConfig +instance HasFieldNames PackageConfig where + ignoreUnderscoredUnknownFields _ = True instance FromJSON PackageConfig where parseJSON value = handleNullValues <$> genericParseJSON_ value @@ -353,6 +423,7 @@ , packageAuthor :: [String] , packageMaintainer :: [String] , packageCopyright :: [String] +, packageBuildType :: BuildType , packageLicense :: Maybe String , packageLicenseFile :: Maybe FilePath , packageTestedWith :: Maybe String @@ -360,12 +431,17 @@ , packageExtraSourceFiles :: [FilePath] , packageDataFiles :: [FilePath] , packageSourceRepository :: Maybe SourceRepository +, packageCustomSetup :: Maybe CustomSetup , packageLibrary :: Maybe (Section Library) , packageExecutables :: [Section Executable] , packageTests :: [Section Executable] , packageBenchmarks :: [Section Executable] } deriving (Eq, Show) +data CustomSetup = CustomSetup { + customSetupDependencies :: [Dependency] +} deriving (Eq, Show) + data Library = Library { libraryExposed :: Maybe Bool , libraryExposedModules :: [String] @@ -388,6 +464,7 @@ , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption] , sectionCppOptions :: [CppOption] +, sectionCcOptions :: [CcOption] , sectionCSources :: [FilePath] , sectionExtraLibDirs :: [FilePath] , sectionExtraLibraries :: [FilePath] @@ -407,6 +484,7 @@ instance HasFieldNames a => HasFieldNames (Section a) where fieldNames Proxy = fieldNames (Proxy :: Proxy a) ++ fieldNames (Proxy :: Proxy CommonOptions) + ignoreUnderscoredUnknownFields _ = ignoreUnderscoredUnknownFields (Proxy :: Proxy a) data FlagSection = FlagSection { _flagSectionDescription :: Maybe String @@ -436,12 +514,26 @@ 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 :: [String] + name :: String + (nameWarnings, name) = maybe (["Package name not specified, inferred " ++ show inferredName], inferredName) ((,) []) packageConfigName + where inferredName = takeBaseName dir + + mCustomSetup :: Maybe CustomSetup + mCustomSetup = toCustomSetup <$> mCustomSetupSection - 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 :: Maybe (Section Library) + mLibrary = fmap snd libraryResult + + libraryWarnings :: [String] + 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") @@ -453,12 +545,15 @@ ) (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 defaultBuildType :: BuildType + defaultBuildType = maybe Simple (const Custom) mCustomSetup - let pkg = Package { + pkg = Package { packageName = name , packageVersion = fromMaybe "0.0.0" packageConfigVersion , packageSynopsis = packageConfigSynopsis @@ -470,6 +565,7 @@ , packageAuthor = fromMaybeList packageConfigAuthor , packageMaintainer = fromMaybeList packageConfigMaintainer , packageCopyright = fromMaybeList packageConfigCopyright + , packageBuildType = fromMaybe defaultBuildType packageConfigBuildType , packageLicense = packageConfigLicense , packageLicenseFile = packageConfigLicenseFile <|> (guard licenseFileExists >> Just "LICENSE") , packageTestedWith = packageConfigTestedWith @@ -477,6 +573,7 @@ , packageExtraSourceFiles = extraSourceFiles , packageDataFiles = dataFiles , packageSourceRepository = sourceRepository + , packageCustomSetup = mCustomSetup , packageLibrary = mLibrary , packageExecutables = executables , packageTests = tests @@ -485,11 +582,17 @@ warnings = formatUnknownFields "package description" unknownFields + ++ nameWarnings ++ flagWarnings + ++ maybe [] (formatUnknownFields "custom-setup section") (captureUnknownFieldsFields <$> packageConfigCustomSetup) ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary) ++ formatUnknownSectionFields "executable" executableSections ++ formatUnknownSectionFields "test" testsSections ++ formatMissingSourceDirs missingSourceDirs + ++ libraryWarnings + ++ executablesWarnings + ++ testsWarnings + ++ benchmarksWarnings ++ extraSourceFilesWarnings ++ dataFilesWarnings @@ -516,6 +619,9 @@ toList :: Maybe (Map String a) -> [(String, a)] toList = Map.toList . fromMaybe mempty + mCustomSetupSection :: Maybe CustomSetupSection + mCustomSetupSection = captureUnknownFieldsValue <$> packageConfigCustomSetup + mLibrarySection :: Maybe (Section LibrarySection) mLibrarySection = captureUnknownFieldsValue <$> packageConfigLibrary @@ -560,8 +666,17 @@ 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}) + +toCustomSetup :: CustomSetupSection -> CustomSetup +toCustomSetup CustomSetupSection{..} = CustomSetup + { customSetupDependencies = fromMaybeList customSetupSectionDependencies } + +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 @@ -576,8 +691,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 @@ -607,6 +725,7 @@ , sectionGhcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options , sectionGhcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options , sectionCppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options + , sectionCcOptions = sectionCcOptions globalOptions ++ sectionCcOptions options , sectionCSources = sectionCSources globalOptions ++ sectionCSources options , sectionExtraLibDirs = sectionExtraLibDirs globalOptions ++ sectionExtraLibDirs options , sectionExtraLibraries = sectionExtraLibraries globalOptions ++ sectionExtraLibraries options @@ -621,7 +740,7 @@ toSection :: a -> CommonOptions -> ([FieldName], Section a) toSection a CommonOptions{..} - = ( concat unknownFields + = ( concat unknownFields , Section { sectionData = a , sectionSourceDirs = fromMaybeList commonOptionsSourceDirs @@ -630,6 +749,7 @@ , sectionGhcOptions = fromMaybeList commonOptionsGhcOptions , sectionGhcProfOptions = fromMaybeList commonOptionsGhcProfOptions , sectionCppOptions = fromMaybeList commonOptionsCppOptions + , sectionCcOptions = fromMaybeList commonOptionsCcOptions , sectionCSources = fromMaybeList commonOptionsCSources , sectionExtraLibDirs = fromMaybeList commonOptionsExtraLibDirs , sectionExtraLibraries = fromMaybeList commonOptionsExtraLibraries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/src/Hpack/Run.hs new/hpack-0.17.0/src/Hpack/Run.hs --- old/hpack-0.14.1/src/Hpack/Run.hs 2016-05-09 11:10:56.000000000 +0200 +++ new/hpack-0.17.0/src/Hpack/Run.hs 2017-01-30 00:09:54.000000000 +0100 @@ -14,6 +14,7 @@ , renderConditional , renderFlag , renderSourceRepository +, renderDirectories , formatDescription #endif ) where @@ -67,8 +68,13 @@ dataFiles :: Element dataFiles = Field "data-files" (LineSeparatedList packageDataFiles) + sourceRepository :: [Element] sourceRepository = maybe [] (return . renderSourceRepository) packageSourceRepository + customSetup :: [Element] + customSetup = maybe [] (return . renderCustomSetup) packageCustomSetup + + library :: [Element] library = maybe [] (return . renderLibrary) packageLibrary stanzas :: [Element] @@ -77,7 +83,8 @@ : dataFiles : sourceRepository ++ concat [ - map renderFlag packageFlags + customSetup + , map renderFlag packageFlags , library , renderExecutables packageExecutables , renderTests packageTests @@ -100,7 +107,7 @@ , ("license", packageLicense) , ("license-file", packageLicenseFile) , ("tested-with", packageTestedWith) - , ("build-type", Just "Simple") + , ("build-type", Just (show packageBuildType)) , ("cabal-version", cabalVersion) ] @@ -188,6 +195,10 @@ mainIs = Field "main-is" (Literal executableMain) otherModules = renderOtherModules executableOtherModules +renderCustomSetup :: CustomSetup -> Element +renderCustomSetup CustomSetup{..} = + Stanza "custom-setup" [renderSetupDepends customSetupDependencies] + renderLibrary :: Section Library -> Element renderLibrary sect@(sectionData -> Library{..}) = Stanza "library" $ renderSection sect ++ @@ -203,16 +214,17 @@ renderSection :: Section a -> [Element] renderSection Section{..} = [ - renderSourceDirs sectionSourceDirs + renderDirectories "hs-source-dirs" sectionSourceDirs , renderDefaultExtensions sectionDefaultExtensions , renderOtherExtensions sectionOtherExtensions , renderGhcOptions sectionGhcOptions , renderGhcProfOptions sectionGhcProfOptions , renderCppOptions sectionCppOptions - , Field "include-dirs" (LineSeparatedList sectionIncludeDirs) + , renderCcOptions sectionCcOptions + , 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 @@ -231,8 +243,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 @@ -255,6 +272,9 @@ renderCppOptions :: [CppOption] -> Element renderCppOptions = Field "cpp-options" . WordList +renderCcOptions :: [CcOption] -> Element +renderCcOptions = Field "cc-options" . WordList + renderLdOptions :: [LdOption] -> Element renderLdOptions = Field "ld-options" . WordList @@ -269,3 +289,6 @@ renderBuildTools :: [Dependency] -> Element renderBuildTools = Field "build-tools" . CommaSeparatedList . map dependencyName + +renderSetupDepends :: [Dependency] -> Element +renderSetupDepends = Field "setup-depends" . CommaSeparatedList . map dependencyName diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/src/Hpack/Util.hs new/hpack-0.17.0/src/Hpack/Util.hs --- old/hpack-0.14.1/src/Hpack/Util.hs 2016-04-22 06:28:00.000000000 +0200 +++ new/hpack-0.17.0/src/Hpack/Util.hs 2017-01-24 15:56:26.000000000 +0100 @@ -4,6 +4,7 @@ , GhcOption , GhcProfOption , CppOption +, CcOption , LdOption , parseMain , toModule @@ -18,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 @@ -50,6 +55,7 @@ type GhcOption = String type GhcProfOption = String type CppOption = String +type CcOption = String type LdOption = String parseMain :: String -> (FilePath, [GhcOption]) @@ -71,7 +77,7 @@ toModule path = case reverse path of [] -> Nothing x : xs -> do - m <- stripSuffix ".hs" x <|> stripSuffix ".lhs" x + m <- stripSuffix ".hs" x <|> stripSuffix ".lhs" x <|> stripSuffix ".hsc" x let name = reverse (m : xs) guard (isModule name) >> return (intercalate "." name) where @@ -93,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 { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/src/Hpack/Yaml.hs new/hpack-0.17.0/src/Hpack/Yaml.hs --- old/hpack-0.14.1/src/Hpack/Yaml.hs 2015-09-25 19:02:44.000000000 +0200 +++ new/hpack-0.17.0/src/Hpack/Yaml.hs 2017-01-30 00:09:54.000000000 +0100 @@ -1,7 +1,8 @@ {-# LANGUAGE RecordWildCards #-} module Hpack.Yaml where -import Data.Yaml +import Data.Yaml hiding (decodeFile, decodeFileEither) +import Data.Yaml.Include decodeYaml :: FromJSON a => FilePath -> IO (Either String a) decodeYaml file = do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/src/Hpack.hs new/hpack-0.17.0/src/Hpack.hs --- old/hpack-0.14.1/src/Hpack.hs 2016-05-09 11:10:56.000000000 +0200 +++ new/hpack-0.17.0/src/Hpack.hs 2017-01-24 15:56:26.000000000 +0100 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/test/Hpack/ConfigSpec.hs new/hpack-0.17.0/test/Hpack/ConfigSpec.hs --- old/hpack-0.14.1/test/Hpack/ConfigSpec.hs 2016-05-09 11:10:56.000000000 +0200 +++ new/hpack-0.17.0/test/Hpack/ConfigSpec.hs 2017-01-30 00:09:54.000000000 +0100 @@ -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,8 +306,10 @@ describe "readPackageConfig" $ do it "warns on unknown fields" $ do withPackageWarnings_ [i| + name: foo bar: 23 baz: 42 + _qux: 66 |] (`shouldBe` [ "Ignoring unknown field \"bar\" in package description" @@ -317,19 +319,23 @@ it "warns on unknown fields in when block, list" $ do withPackageWarnings_ [i| + name: foo when: - condition: impl(ghc) bar: 23 baz: 42 + _qux: 66 |] (`shouldBe` [ - "Ignoring unknown field \"bar\" in package description" + "Ignoring unknown field \"_qux\" in package description" + , "Ignoring unknown field \"bar\" in package description" , "Ignoring unknown field \"baz\" in package description" ] ) it "warns on unknown fields in when block, single" $ do withPackageWarnings_ [i| + name: foo when: condition: impl(ghc) github: foo/bar @@ -342,6 +348,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 @@ -457,6 +478,33 @@ |] (packageLicenseFile >>> (`shouldBe` Just "FOO")) + it "accepts build-type: Simple" $ do + withPackageConfig_ [i| + build-type: Simple + |] + (`shouldBe` package {packageBuildType = Simple}) + + it "accepts build-type: Configure" $ do + withPackageConfig_ [i| + build-type: Configure + |] + (`shouldBe` package {packageBuildType = Configure}) + + it "accepts build-type: Make" $ do + withPackageConfig_ [i| + build-type: Make + |] + (`shouldBe` package {packageBuildType = Make}) + + it "accepts build-type: Custom" $ do + withPackageConfig_ [i| + build-type: Custom + |] + (`shouldBe` package {packageBuildType = Custom}) + + it "rejects unknown build-type" $ do + parseEither parseJSON (String "foobar") `shouldBe` (Left "Error in $: build-type must be one of: Simple, Configure, Make, Custom" :: Either String BuildType) + it "accepts flags" $ do withPackageConfig_ [i| flags: @@ -469,6 +517,7 @@ it "warns on unknown fields in flag sections" $ do withPackageWarnings_ [i| + name: foo flags: integration-tests: description: Run the integration test suite @@ -546,6 +595,30 @@ } ) + it "accepts cc-options" $ do + withPackageConfig_ [i| + cc-options: -Wall + library: + cc-options: -fLIB + + executables: + foo: + main: Main.hs + cc-options: -O2 + + + tests: + spec: + main: Spec.hs + cc-options: -O0 + |] + (`shouldBe` package { + packageLibrary = Just (section library) {sectionCcOptions = ["-Wall", "-fLIB"]} + , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionCcOptions = ["-Wall", "-O2"]}] + , packageTests = [(section $ executable "spec" "Spec.hs") {sectionCcOptions = ["-Wall", "-O0"]}] + } + ) + it "accepts ld-options" $ do withPackageConfig_ [i| library: @@ -572,9 +645,60 @@ } ) + context "when reading custom-setup section" $ do + it "warns on unknown fields" $ do + withPackageWarnings_ [i| + name: foo + custom-setup: + foo: 1 + bar: 2 + |] + (`shouldBe` [ + "Ignoring unknown field \"bar\" in custom-setup section" + , "Ignoring unknown field \"foo\" in custom-setup section" + ]) + + it "sets build-type: Custom, if missing" $ do + withPackageConfig_ [i| + custom-setup: + dependencies: + - base + |] + (packageBuildType >>> (`shouldBe` Custom)) + + it "leaves build-type alone, if it exists" $ do + withPackageConfig_ [i| + name: foo + build-type: Make + custom-setup: + dependencies: + - base + |] + (packageBuildType >>> (`shouldBe` Make)) + + it "accepts dependencies" $ do + withPackageConfig_ [i| + custom-setup: + dependencies: + - foo >1.0 + - bar ==2.0 + |] + (packageCustomSetup >>> fmap customSetupDependencies >>> (`shouldBe` Just ["foo >1.0", "bar ==2.0"])) + + it "allows yaml merging and overriding fields" $ do + withPackageConfig_ [i| + _common: &common + name: n1 + + <<: *common + name: n2 + |] + (packageName >>> (`shouldBe` "n2")) + context "when reading library section" $ do it "warns on unknown fields" $ do withPackageWarnings_ [i| + name: foo library: bar: 23 baz: 42 @@ -639,6 +763,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: @@ -704,6 +852,7 @@ context "when reading executable section" $ do it "warns on unknown fields" $ do withPackageWarnings_ [i| + name: foo executables: foo: main: Main.hs @@ -789,10 +938,8 @@ (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"]])) + (map (executableOtherModules . sectionData) . packageExecutables >>> (`shouldBe` [["Foo"]])) it "allows to specify other-modules" $ do withPackageConfig [i| @@ -866,10 +1013,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 @@ -926,6 +1101,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 @@ -969,7 +1145,7 @@ 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") + readPackageConfig file >>= (`shouldSatisfy` isLeft) context "when package.yaml does not exist" $ do it "returns an error" $ \dir -> do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/test/Hpack/RunSpec.hs new/hpack-0.17.0/test/Hpack/RunSpec.hs --- old/hpack-0.14.1/test/Hpack/RunSpec.hs 2016-04-22 06:28:00.000000000 +0200 +++ new/hpack-0.17.0/test/Hpack/RunSpec.hs 2017-01-30 00:09:54.000000000 +0100 @@ -103,6 +103,22 @@ , " default-language: Haskell2010" ] + context "when rendering custom-setup section" $ do + it "includes setup-depends" $ do + let setup = CustomSetup + { customSetupDependencies = ["foo >1.0", "bar ==2.0"] } + renderPackage_ package {packageCustomSetup = Just setup} `shouldBe` unlines [ + "name: foo" + , "version: 0.0.0" + , "build-type: Simple" + , "cabal-version: >= 1.10" + , "" + , "custom-setup" + , " setup-depends:" + , " foo >1.0" + , " , bar ==2.0" + ] + context "when rendering library section" $ do it "renders library section" $ do renderPackage_ package {packageLibrary = Just $ section library} `shouldBe` unlines [ @@ -323,3 +339,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:" + , " ./." + ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hpack-0.14.1/test/Hpack/UtilSpec.hs new/hpack-0.17.0/test/Hpack/UtilSpec.hs --- old/hpack-0.14.1/test/Hpack/UtilSpec.hs 2016-04-22 06:28:00.000000000 +0200 +++ new/hpack-0.17.0/test/Hpack/UtilSpec.hs 2017-01-09 22:10:01.000000000 +0100 @@ -37,8 +37,14 @@ parseMain "Foo.bar" `shouldBe` ("Foo.hs", ["-main-is Foo.bar"]) describe "toModule" $ do - it "maps paths to module names" $ do - toModule ["Foo", "Bar", "Baz.hs"] `shouldBe` Just "Foo.Bar.Baz" + it "maps .hs paths to module names" $ do + toModule ["Foo", "Bar", "Baz.hs"] `shouldBe` Just "Foo.Bar.Baz" + + it "maps .lhs paths to module names" $ do + toModule ["Foo", "Bar", "Baz.lhs"] `shouldBe` Just "Foo.Bar.Baz" + + it "maps .hsc paths to module names" $ do + toModule ["Foo", "Bar", "Baz.hsc"] `shouldBe` Just "Foo.Bar.Baz" it "rejects invalid module names" $ do toModule ["resources", "hello.hs"] `shouldBe` Nothing @@ -91,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 @@ -116,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"], [])