From e70eae6c3a04671ce006708ee52cbad3210e1473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Mon, 27 Feb 2023 21:11:19 +0100 Subject: [PATCH] [FLORA-345] Store and display deprecated release information --- flora.cabal | 1 - src/core/Flora/Import/Package.hs | 1 + src/core/Flora/Model/Job.hs | 7 +- src/core/Flora/Model/Release/Query.hs | 57 +++- src/core/Flora/Model/Release/Types.hs | 1 + src/core/Flora/Model/Release/Update.hs | 16 +- src/jobs-worker/FloraJobs/Runner.hs | 41 ++- src/jobs-worker/FloraJobs/Scheduler.hs | 21 +- .../FloraJobs/ThirdParties/Hackage/API.hs | 15 + .../FloraJobs/ThirdParties/Hackage/Client.hs | 9 +- src/web/FloraWeb/Server/Pages/Admin.hs | 11 +- src/web/FloraWeb/Templates/Pages/Packages.hs | 2 +- test/Flora/PackageSpec.hs | 16 +- test/fixtures/Cabal/binary-0.10.0.0.cabal | 268 ++++++++++++++++++ .../{binary.cabal => binary-0.8.9.0.cabal} | 0 15 files changed, 437 insertions(+), 29 deletions(-) create mode 100644 test/fixtures/Cabal/binary-0.10.0.0.cabal rename test/fixtures/Cabal/{binary.cabal => binary-0.8.9.0.cabal} (100%) diff --git a/flora.cabal b/flora.cabal index 915d0ed49..f6bdbd50b 100644 --- a/flora.cabal +++ b/flora.cabal @@ -71,7 +71,6 @@ library extra-libraries: stdc++ cxx-options: -std=c++17 -Wall -D__EMBEDDED_SOUFFLE__ cxx-sources: cbits/categorise.cpp - cabal-fmt: expand src hs-source-dirs: ./src/core ./src/orphans -- cabal-fmt: expand src/core diff --git a/src/core/Flora/Import/Package.hs b/src/core/Flora/Import/Package.hs index 91f3977f4..daf29032e 100644 --- a/src/core/Flora/Import/Package.hs +++ b/src/core/Flora/Import/Package.hs @@ -300,6 +300,7 @@ extractPackageDataFromCabal userId genericDesc = do , description = display packageDesc.description , flags = flags , testedWith = getVersions . extractTestedWith . Vector.fromList $! packageDesc.testedWith + , deprecated = Nothing } let release = diff --git a/src/core/Flora/Model/Job.hs b/src/core/Flora/Model/Job.hs index 5ba4c48ed..5bde2c7b8 100644 --- a/src/core/Flora/Model/Job.hs +++ b/src/core/Flora/Model/Job.hs @@ -13,6 +13,7 @@ import OddJobs.Job (Job, LogEvent (..)) import OddJobs.Types (FailureMode) import Servant (ToHttpApiData) +import Data.Vector (Vector) import Flora.Import.Package.Types (ImportOutput) import Flora.Model.Package (PackageName (..)) import Flora.Model.Release.Types (ReleaseId (..)) @@ -63,7 +64,8 @@ data FloraOddJobs | FetchChangelog ChangelogJobPayload | ImportHackageIndex ImportHackageIndexPayload | ImportPackage ImportOutput - | FetchDeprecationList + | FetchPackageDeprecationList + | FetchReleaseDeprecationList PackageName (Vector ReleaseId) deriving stock (Generic) deriving anyclass (ToJSON, FromJSON) @@ -75,7 +77,8 @@ instance ToJSON LogEvent where toJSON = \case LogJobStart job -> toJSON ("start" :: Text, job) LogJobSuccess job time -> toJSON ("success" :: Text, job, time) - LogJobFailed job exception failuremode finishTime -> toJSON ("failed" :: Text, show exception, job, failuremode, finishTime) + LogJobFailed job exception failuremode finishTime -> + toJSON ("failed" :: Text, show exception, job, failuremode, finishTime) LogJobTimeout job -> toJSON ("timed-out" :: Text, job) LogPoll -> toJSON ("poll" :: Text) LogWebUIRequest -> toJSON ("web-ui-request" :: Text) diff --git a/src/core/Flora/Model/Release/Query.hs b/src/core/Flora/Model/Release/Query.hs index b43cf1e6d..c586c485c 100644 --- a/src/core/Flora/Model/Release/Query.hs +++ b/src/core/Flora/Model/Release/Query.hs @@ -11,6 +11,8 @@ module Flora.Model.Release.Query , getAllReleases , getNumberOfReleases , getReleaseComponents + , getPackagesWithoutReleaseDeprecationInformation + , getVersionFromManyReleaseIds ) where @@ -18,9 +20,9 @@ import Data.Vector (Vector) import Data.Vector qualified as Vector import Data.Vector.Algorithms.Intro as MVector import Database.PostgreSQL.Entity -import Database.PostgreSQL.Entity.DBT (QueryNature (..), query, queryOne) +import Database.PostgreSQL.Entity.DBT (QueryNature (..), query, queryOne, query_) import Database.PostgreSQL.Entity.Types (field) -import Database.PostgreSQL.Simple (Only (..), Query) +import Database.PostgreSQL.Simple (In (..), Only (..), Query) import Database.PostgreSQL.Simple.SqlQQ (sql) import Distribution.Version (Version) import Effectful @@ -48,6 +50,20 @@ getAllReleases pid = then pure results else pure $! Vector.reverse $! Vector.modify MVector.sort results +getVersionFromManyReleaseIds + :: (DB :> es) + => Vector ReleaseId + -> Eff es (Vector (ReleaseId, Version)) +getVersionFromManyReleaseIds releaseIds = do + dbtToEff $! query Select q (Only (In (Vector.toList releaseIds))) + where + q = + [sql| + select (r0.release_id, r0.version) + from releases as r0 + where r0.release_id in ? + |] + getPackageReleases :: (DB :> es) => Eff es (Vector (ReleaseId, Version, PackageName)) getPackageReleases = dbtToEff $ @@ -62,7 +78,9 @@ getPackageReleases = on p.package_id = r.package_id |] -getPackageReleasesWithoutReadme :: (DB :> es) => Eff es (Vector (ReleaseId, Version, PackageName)) +getPackageReleasesWithoutReadme + :: (DB :> es) + => Eff es (Vector (ReleaseId, Version, PackageName)) getPackageReleasesWithoutReadme = dbtToEff $ query Select querySpec () @@ -77,7 +95,9 @@ getPackageReleasesWithoutReadme = where r.readme_status = 'not-imported' |] -getPackageReleasesWithoutUploadTimestamp :: (DB :> es) => Eff es (Vector (ReleaseId, Version, PackageName)) +getPackageReleasesWithoutUploadTimestamp + :: (DB :> es) + => Eff es (Vector (ReleaseId, Version, PackageName)) getPackageReleasesWithoutUploadTimestamp = dbtToEff $ query Select querySpec () @@ -92,7 +112,9 @@ getPackageReleasesWithoutUploadTimestamp = where r.uploaded_at is null |] -getPackageReleasesWithoutChangelog :: (DB :> es) => Eff es (Vector (ReleaseId, Version, PackageName)) +getPackageReleasesWithoutChangelog + :: (DB :> es) + => Eff es (Vector (ReleaseId, Version, PackageName)) getPackageReleasesWithoutChangelog = dbtToEff $ query Select querySpec () @@ -107,8 +129,29 @@ getPackageReleasesWithoutChangelog = where r.changelog_status = 'not-imported' |] -getReleaseByVersion :: (DB :> es) => PackageId -> Version -> Eff es (Maybe Release) -getReleaseByVersion packageId version = dbtToEff $! queryOne Select (_selectWhere @Release [[field| package_id |], [field| version |]]) (packageId, version) +getPackagesWithoutReleaseDeprecationInformation + :: (DB :> es) + => Eff es (Vector (PackageName, Vector ReleaseId)) +getPackagesWithoutReleaseDeprecationInformation = + dbtToEff $! query_ Select q + where + q = + [sql| + select p1.name, array_agg(r0.release_id) + from releases as r0 + join packages as p1 on r0.package_id = p1.package_id + where r0.metadata ->> 'deprecated' is null + group by p1.name; + |] + +getReleaseByVersion + :: (DB :> es) + => PackageId + -> Version + -> Eff es (Maybe Release) +getReleaseByVersion packageId version = + dbtToEff $! + queryOne Select (_selectWhere @Release [[field| package_id |], [field| version |]]) (packageId, version) getNumberOfReleases :: (DB :> es) => PackageId -> Eff es Word getNumberOfReleases pid = diff --git a/src/core/Flora/Model/Release/Types.hs b/src/core/Flora/Model/Release/Types.hs index 1c354be1a..042b575cd 100644 --- a/src/core/Flora/Model/Release/Types.hs +++ b/src/core/Flora/Model/Release/Types.hs @@ -151,6 +151,7 @@ data ReleaseMetadata = ReleaseMetadata , description :: Text , flags :: Vector PackageFlag , testedWith :: Vector Version + , deprecated :: Maybe Bool } deriving stock (Eq, Show, Generic, Typeable) deriving anyclass (ToJSON, FromJSON, NFData) diff --git a/src/core/Flora/Model/Release/Update.hs b/src/core/Flora/Model/Release/Update.hs index acc036421..14c72664b 100644 --- a/src/core/Flora/Model/Release/Update.hs +++ b/src/core/Flora/Model/Release/Update.hs @@ -5,7 +5,7 @@ module Flora.Model.Release.Update where import Control.Monad (void) import Database.PostgreSQL.Entity -import Database.PostgreSQL.Entity.DBT (QueryNature (Update), execute) +import Database.PostgreSQL.Entity.DBT (QueryNature (Update), execute, executeMany) import Database.PostgreSQL.Entity.Types (field) import Database.PostgreSQL.Simple (Only (..)) import Database.PostgreSQL.Simple.SqlQQ (sql) @@ -13,6 +13,8 @@ import Effectful import Effectful.PostgreSQL.Transact.Effect import Data.Time (UTCTime) +import Data.Vector (Vector) +import Data.Vector qualified as Vector import Flora.Model.Release.Types (ImportStatus (..), Release, ReleaseId, TextHtml (..)) insertRelease :: (DB :> es) => Release -> Eff es () @@ -54,3 +56,15 @@ updateChangelog releaseId changelogBody status = ] ([field| release_id |], releaseId) (changelogBody, status) + +setReleasesDeprecationMarker :: (DB :> es) => Vector (Bool, ReleaseId) -> Eff es () +setReleasesDeprecationMarker releaseVersions = + dbtToEff $! void $! executeMany Update q (Vector.toList releaseVersions) + where + q = + [sql| + UPDATE releases as r0 + SET metadata = jsonb_set(r0.metadata, '{deprecated}', to_jsonb(upd.x), true) + FROM (VALUES (?,?)) as upd(x,y) + WHERE r0.release_id = (upd.y :: uuid) + |] diff --git a/src/jobs-worker/FloraJobs/Runner.hs b/src/jobs-worker/FloraJobs/Runner.hs index f032e1d66..46139cc1b 100644 --- a/src/jobs-worker/FloraJobs/Runner.hs +++ b/src/jobs-worker/FloraJobs/Runner.hs @@ -28,7 +28,7 @@ import Flora.Model.Release.Types import Flora.Model.Release.Update qualified as Update import FloraJobs.Render (renderMarkdown) import FloraJobs.Scheduler -import FloraJobs.ThirdParties.Hackage.API (VersionedPackage (..)) +import FloraJobs.ThirdParties.Hackage.API (HackagePreferredVersions (..), VersionedPackage (..)) import FloraJobs.ThirdParties.Hackage.Client qualified as Hackage import FloraJobs.Types @@ -47,8 +47,7 @@ fetchNewIndex = forkIO $! forM_ releases - ( \(releaseId, version, packagename) -> do - scheduleReadmeJob pool releaseId packagename version + ( \(releaseId, version, packagename) -> scheduleReadmeJob pool releaseId packagename version ) liftIO $! void $! scheduleIndexImportJob pool @@ -62,7 +61,9 @@ runner job = localDomain "job-runner" $ FetchChangelog x -> fetchChangeLog x ImportHackageIndex _ -> fetchNewIndex ImportPackage x -> persistImportOutput x - FetchDeprecationList -> fetchDeprecationList + FetchPackageDeprecationList -> fetchPackageDeprecationList + FetchReleaseDeprecationList packageName releases -> + fetchReleaseDeprecationList packageName releases fetchChangeLog :: ChangelogJobPayload -> JobsRunner () fetchChangeLog payload@ChangelogJobPayload{packageName, packageVersion, releaseId} = @@ -124,8 +125,8 @@ fetchUploadTime payload@UploadTimeJobPayload{packageName, packageVersion, releas Left e -> throw e -- | This job fetches the deprecation list and inserts the appropriate metadata in the packages -fetchDeprecationList :: JobsRunner () -fetchDeprecationList = do +fetchPackageDeprecationList :: JobsRunner () +fetchPackageDeprecationList = do result <- Hackage.request $! Hackage.getDeprecatedPackages case result of Right deprecationList -> do @@ -136,15 +137,35 @@ fetchDeprecationList = do DeprecatedPackage package (assignNamespace inFavourOf) ) & Update.deprecatePackages - Left _ -> do - logAttention_ "Could not fetch deprecation list from Hackage" + Left _ -> logAttention_ "Could not fetch deprecation list from Hackage" + +fetchReleaseDeprecationList :: PackageName -> Vector ReleaseId -> JobsRunner () +fetchReleaseDeprecationList packageName releases = do + result <- Hackage.request $! Hackage.getDeprecatedReleasesList packageName + case result of + Right deprecationList -> do + logInfo "Release deprecation list retrieved" $ + object ["package" .= display packageName] + releasesAndVersions <- Query.getVersionFromManyReleaseIds releases + let (deprecatedVersions', preferredVersions') = + Vector.unstablePartition + ( \(_, v) -> + Vector.elem v deprecationList.deprecatedVersions + ) + releasesAndVersions + let deprecatedVersions = fmap (\(releaseId, _) -> (True, releaseId)) deprecatedVersions' + let preferredVersions = fmap (\(releaseId, _) -> (False, releaseId)) preferredVersions' + Update.setReleasesDeprecationMarker deprecatedVersions + Update.setReleasesDeprecationMarker preferredVersions + Left _ -> + logAttention "Could not fetch release deprecation list from Hackage" $ + object ["package" .= display packageName] assignNamespace :: Vector PackageName -> Vector PackageAlternative -assignNamespace packages = +assignNamespace = Vector.map ( \p -> if Set.member p coreLibraries then PackageAlternative (Namespace "haskell") p else PackageAlternative (Namespace "hackage") p ) - packages diff --git a/src/jobs-worker/FloraJobs/Scheduler.hs b/src/jobs-worker/FloraJobs/Scheduler.hs index 43b14aa37..c8ac012c2 100644 --- a/src/jobs-worker/FloraJobs/Scheduler.hs +++ b/src/jobs-worker/FloraJobs/Scheduler.hs @@ -6,7 +6,8 @@ module FloraJobs.Scheduler , scheduleChangelogJob , scheduleUploadTimeJob , scheduleIndexImportJob - , scheduleDeprecationListJob + , schedulePackageDeprecationListJob + , scheduleReleaseDeprecationListJob , checkIfIndexImportJobIsNotRunning , jobTableName -- prefer using smart constructors. @@ -18,6 +19,7 @@ where import Data.Pool import Data.Time qualified as Time +import Data.Vector (Vector) import Database.PostgreSQL.Entity.DBT import Database.PostgreSQL.Simple (Only (..)) import Database.PostgreSQL.Simple qualified as PG @@ -79,15 +81,26 @@ scheduleIndexImportJob pool = runAt ) -scheduleDeprecationListJob :: Pool PG.Connection -> IO Job -scheduleDeprecationListJob pool = +schedulePackageDeprecationListJob :: Pool PG.Connection -> IO Job +schedulePackageDeprecationListJob pool = withResource pool ( \conn -> createJob conn jobTableName - FetchDeprecationList + FetchPackageDeprecationList + ) + +scheduleReleaseDeprecationListJob :: Pool PG.Connection -> (PackageName, Vector ReleaseId) -> IO Job +scheduleReleaseDeprecationListJob pool (package, releaseIds) = + withResource + pool + ( \conn -> + createJob + conn + jobTableName + (FetchReleaseDeprecationList package releaseIds) ) checkIfIndexImportJobIsNotRunning :: JobsRunner Bool diff --git a/src/jobs-worker/FloraJobs/ThirdParties/Hackage/API.hs b/src/jobs-worker/FloraJobs/ThirdParties/Hackage/API.hs index 996dd609b..bb3531ef7 100644 --- a/src/jobs-worker/FloraJobs/ThirdParties/Hackage/API.hs +++ b/src/jobs-worker/FloraJobs/ThirdParties/Hackage/API.hs @@ -15,6 +15,7 @@ import Servant.API import Servant.API.Generic import Distribution.Orphans () +import Distribution.Types.Version (Version) import Flora.Model.Job (IntAesonVersion) import Flora.Model.Package.Types (DeprecatedPackage' (..), PackageName) @@ -44,6 +45,7 @@ data HackageAPI' mode = HackageAPI' , withUser :: mode :- "user" :> Capture "username" Text :> NamedRoutes HackageUserAPI , packages :: mode :- "packages" :> NamedRoutes HackagePackagesAPI , withPackage :: mode :- "package" :> Capture "versioned_package" VersionedPackage :> NamedRoutes HackagePackageAPI + , withPackageName :: mode :- "package" :> Capture "pacakgeName" PackageName :> NamedRoutes HackagePackageAPI } deriving stock (Generic) @@ -56,6 +58,7 @@ data HackagePackageAPI mode = HackagePackageAPI { getReadme :: mode :- "readme.txt" :> Get '[PlainerText] Text , getUploadTime :: mode :- "upload-time" :> Get '[PlainText] UTCTime , getChangelog :: mode :- "changelog.txt" :> Get '[PlainerText] Text + , getDeprecatedReleases :: mode :- "preferred" :> Get '[JSON] HackagePreferredVersions } deriving stock (Generic) @@ -78,3 +81,15 @@ data HackageUserDetailsObject = HackageUserDetailsOject } deriving stock (Eq, Show, Generic) deriving anyclass (FromJSON) + +data HackagePreferredVersions = HackagePreferredVersions + { deprecatedVersions :: Vector Version + , normalVersions :: Vector Version + } + deriving stock (Eq, Show, Generic) + +instance FromJSON HackagePreferredVersions where + parseJSON = withObject "Hacakge preferred versions" $ \o -> do + deprecatedVersions <- o .: "deprecated-version" + normalVersions <- o .: "normal-version" + pure HackagePreferredVersions{..} diff --git a/src/jobs-worker/FloraJobs/ThirdParties/Hackage/Client.hs b/src/jobs-worker/FloraJobs/ThirdParties/Hackage/Client.hs index 25c75a0b0..1f9802c2e 100644 --- a/src/jobs-worker/FloraJobs/ThirdParties/Hackage/Client.hs +++ b/src/jobs-worker/FloraJobs/ThirdParties/Hackage/Client.hs @@ -13,7 +13,7 @@ import Effectful.Reader.Static import Servant.API () import Servant.Client -import Flora.Model.Package.Types (DeprecatedPackage') +import Flora.Model.Package.Types import FloraJobs.ThirdParties.Hackage.API as API import FloraJobs.Types (JobsRunner, JobsRunnerEnv (..)) @@ -61,3 +61,10 @@ getDeprecatedPackages = hackageClient // API.packages // getDeprecated + +getDeprecatedReleasesList :: PackageName -> ClientM HackagePreferredVersions +getDeprecatedReleasesList packageName = + hackageClient + // API.withPackageName + /: packageName + // getDeprecatedReleases diff --git a/src/web/FloraWeb/Server/Pages/Admin.hs b/src/web/FloraWeb/Server/Pages/Admin.hs index d2dc5c146..ae1f4844c 100644 --- a/src/web/FloraWeb/Server/Pages/Admin.hs +++ b/src/web/FloraWeb/Server/Pages/Admin.hs @@ -74,7 +74,7 @@ fetchMetadataHandler = do session <- getSession FloraEnv{jobsPool} <- liftIO $! fetchFloraEnv (session.webEnvStore) - liftIO $! scheduleDeprecationListJob jobsPool + liftIO $! schedulePackageDeprecationListJob jobsPool releasesWithoutReadme <- Query.getPackageReleasesWithoutReadme liftIO $! @@ -103,6 +103,15 @@ fetchMetadataHandler = do scheduleChangelogJob jobsPool releaseId packagename version ) + packagesWithoutDeprecationInformation <- Query.getPackagesWithoutReleaseDeprecationInformation + liftIO $! + forkIO $! + Async.forConcurrently_ + packagesWithoutDeprecationInformation + ( \a -> do + scheduleReleaseDeprecationListJob jobsPool a + ) + pure $! redirect "/admin" indexImportJobHandler :: FloraAdmin ImportIndexResponse diff --git a/src/web/FloraWeb/Templates/Pages/Packages.hs b/src/web/FloraWeb/Templates/Pages/Packages.hs index e9d94011e..87f9ea8c7 100644 --- a/src/web/FloraWeb/Templates/Pages/Packages.hs +++ b/src/web/FloraWeb/Templates/Pages/Packages.hs @@ -161,7 +161,7 @@ displayLinks namespace packageName release meta@ReleaseMetadata{..} = h3_ [class_ "package-body-section links"] "Links" ul_ [class_ "links"] $! do li_ [class_ "package-link"] $! a_ [href_ (getHomepage meta)] "Homepage" - li_ [class_ "package-link"] $! a_ [href_ ("https://hackage.haskell.org/package/" <> display packageName)] "Documentation" + li_ [class_ "package-link"] $! a_ [href_ ("https://hackage.haskell.org/package/" <> display packageName <> "-" <> display release.version)] "Documentation" li_ [class_ "package-link"] $! displaySourceRepos sourceRepos li_ [class_ "package-link"] $! displayChangelog namespace packageName release.version release.changelog diff --git a/test/Flora/PackageSpec.hs b/test/Flora/PackageSpec.hs index 0888989b6..33cdfad70 100644 --- a/test/Flora/PackageSpec.hs +++ b/test/Flora/PackageSpec.hs @@ -15,6 +15,7 @@ import Distribution.Types.Condition import Distribution.Types.ConfVar import Distribution.Types.Version qualified as Cabal +import Distribution.Version (mkVersion) import Flora.Import.Package import Flora.Model.Category (Category (..)) import Flora.Model.Category.Query qualified as Query @@ -24,6 +25,7 @@ import Flora.Model.Package.Query qualified as Query import Flora.Model.Package.Update qualified as Update import Flora.Model.Release.Query qualified as Query import Flora.Model.Release.Types +import Flora.Model.Release.Update qualified as Update import Flora.Model.Requirement import Flora.TestUtils @@ -41,7 +43,8 @@ spec _fixtures = , testThis "Searching for `text` returns unique results by namespace/package name" testSearchResultUnicity , testThis "@hackage/time has the correct number of components of each type" testTimeComponents , testThis "Packages get deprecated" testPackagesDeprecation - , testThis "Test getting non-deprecated packages" testGetNonDeprecatedPackages + , testThis "Get non-deprecated packages" testGetNonDeprecatedPackages + , testThis "Get and set release deprecation markers" testReleaseDeprecation -- Disable until conditions are properly supported everywhere -- , testThis "@hackage/time components have the correct conditions in their metadata" testTimeConditions ] @@ -212,6 +215,17 @@ testGetNonDeprecatedPackages = do nonDeprecatedPackages <- fmap (.name) <$> Query.getNonDeprecatedPackages assertBool $ Vector.notElem (PackageName "ansi-wl-pprint") nonDeprecatedPackages +testReleaseDeprecation :: TestEff () +testReleaseDeprecation = do + result <- Query.getPackagesWithoutReleaseDeprecationInformation + assertEqual 62 (length result) + + binary <- fromJust <$> Query.getPackageByNamespaceAndName (Namespace "haskell") (PackageName "binary") + Just deprecatedBinaryVersion' <- Query.getReleaseByVersion (binary.packageId) (mkVersion [0, 10, 0, 0]) + Update.setReleasesDeprecationMarker (Vector.singleton (True, deprecatedBinaryVersion'.releaseId)) + Just deprecatedBinaryVersion <- Query.getReleaseByVersion (binary.packageId) (mkVersion [0, 10, 0, 0]) + assertEqual deprecatedBinaryVersion.metadata.deprecated (Just True) + --- countBy :: (Foldable t) => (a -> Bool) -> t a -> Int diff --git a/test/fixtures/Cabal/binary-0.10.0.0.cabal b/test/fixtures/Cabal/binary-0.10.0.0.cabal new file mode 100644 index 000000000..343903c97 --- /dev/null +++ b/test/fixtures/Cabal/binary-0.10.0.0.cabal @@ -0,0 +1,268 @@ +name: binary +version: 0.10.0.0 +license: BSD3 +license-file: LICENSE +author: Lennart Kolmodin +maintainer: Lennart Kolmodin, Don Stewart +homepage: /~https://github.com/kolmodin/binary +description: Efficient, pure binary serialisation using lazy ByteStrings. + Haskell values may be encoded to and from binary formats, + written to disk as binary, or sent over the network. + The format used can be automatically generated, or + you can choose to implement a custom format if needed. + Serialisation speeds of over 1 G\/sec have been observed, + so this library should be suitable for high performance + scenarios. +synopsis: Binary serialisation for Haskell values using lazy ByteStrings +category: Data, Parsing +stability: provisional +build-type: Simple +cabal-version: >= 1.8 +tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2 +extra-source-files: + README.md changelog.md docs/hcar/binary-Lb.tex tools/derive/*.hs + +-- from the benchmark 'bench' +extra-source-files: + benchmarks/CBenchmark.h + +source-repository head + type: git + location: git://github.com/kolmodin/binary.git + +library + build-depends: base >= 4.5.0.0 && < 5, bytestring >= 0.10.4, containers, array + hs-source-dirs: src + exposed-modules: Data.Binary, + Data.Binary.Put, + Data.Binary.Get, + Data.Binary.Get.Internal, + Data.Binary.Builder + + other-modules: Data.Binary.Class, + Data.Binary.Internal, + Data.Binary.Generic, + Data.Binary.FloatCast + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + + ghc-options: -O2 -Wall -fliberate-case-threshold=1000 + + if impl(ghc >= 8.0) + ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances + +-- Due to circular dependency, we cannot make any of the test-suites or +-- benchmark depend on the binary library. Instead, for each test-suite and +-- benchmark, we include the source directory of binary and build-depend on all +-- the dependencies binary has. + +test-suite qc + type: exitcode-stdio-1.0 + hs-source-dirs: src tests + main-is: QC.hs + other-modules: + Action + Arbitrary + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + random>=1.0.1.0, + test-framework, + test-framework-quickcheck2 >= 0.3, + QuickCheck >= 2.9 + + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -Wall -O2 -threaded + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + + +test-suite read-write-file + type: exitcode-stdio-1.0 + hs-source-dirs: src tests + main-is: File.hs + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + Cabal, + directory, + filepath, + HUnit + + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -Wall + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + + +benchmark bench + type: exitcode-stdio-1.0 + hs-source-dirs: src benchmarks + main-is: Benchmark.hs + other-modules: + MemBench + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4 + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + c-sources: benchmarks/CBenchmark.c + include-dirs: benchmarks + ghc-options: -O2 + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + + +benchmark get + type: exitcode-stdio-1.0 + hs-source-dirs: src benchmarks + main-is: Get.hs + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + attoparsec, + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + cereal, + criterion == 1.*, + deepseq, + mtl + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -O2 -Wall + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + + +benchmark put + type: exitcode-stdio-1.0 + hs-source-dirs: src benchmarks + main-is: Put.hs + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + criterion == 1.*, + deepseq + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -O2 -Wall + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + +benchmark generics-bench + type: exitcode-stdio-1.0 + hs-source-dirs: src benchmarks + main-is: GenericsBench.hs + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + -- The benchmark already depended on 'generic-deriving' transitively. That's + -- what caused one of the problems, as both 'generic-deriving' and + -- 'GenericsBenchTypes' used to define 'instance Generic Version'. + generic-deriving >= 0.10, + directory, + filepath, + unordered-containers, + zlib, + criterion + + other-modules: + Cabal24 + GenericsBenchCache + GenericsBenchTypes + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -O2 -Wall + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim + +benchmark builder + type: exitcode-stdio-1.0 + hs-source-dirs: src benchmarks + main-is: Builder.hs + other-modules: + Data.Binary + Data.Binary.Builder + Data.Binary.Class + Data.Binary.FloatCast + Data.Binary.Generic + Data.Binary.Get + Data.Binary.Get.Internal + Data.Binary.Internal + Data.Binary.Put + build-depends: + base >= 4.5.0.0 && < 5, + bytestring >= 0.10.4, + criterion == 1.*, + deepseq, + mtl + -- build dependencies from using binary source rather than depending on the library + build-depends: array, containers + ghc-options: -O2 + if impl(ghc <= 7.6) + -- prior to ghc-7.4 generics lived in ghc-prim + build-depends: ghc-prim diff --git a/test/fixtures/Cabal/binary.cabal b/test/fixtures/Cabal/binary-0.8.9.0.cabal similarity index 100% rename from test/fixtures/Cabal/binary.cabal rename to test/fixtures/Cabal/binary-0.8.9.0.cabal