hix-0.7.2: lib/Hix/Managed/Cabal/Mock/SourcePackage.hs
module Hix.Managed.Cabal.Mock.SourcePackage where
import qualified Data.Map.Strict as Map
import Distribution.Client.Types (PackageLocation (LocalTarballPackage), SourcePackageDb (..), UnresolvedSourcePackage)
import Distribution.PackageDescription (
BuildInfo (targetBuildDepends),
CondTree (..),
Library (libBuildInfo),
LibraryVisibility (LibraryVisibilityPublic),
PackageDescription (..),
emptyLibrary,
emptyPackageDescription,
)
import Distribution.Simple (Version)
import qualified Distribution.Solver.Types.PackageIndex as PackageIndex
import Distribution.Solver.Types.PackageIndex (PackageIndex)
import qualified Distribution.Solver.Types.SourcePackage as Cabal
import Distribution.Types.GenericPackageDescription (GenericPackageDescription (..), emptyGenericPackageDescription)
import Distribution.Types.Library (libVisibility)
import Exon (exon)
import Hix.Class.Map (nGet, nKeys, nMap, nTo1, nTransform, (!!))
import qualified Hix.Data.Dep as Dep
import Hix.Data.Dep (Dep)
import Hix.Data.Monad (M)
import qualified Hix.Data.PackageId as PackageId
import Hix.Data.PackageId (PackageId (PackageId))
import Hix.Data.PackageName (LocalPackage (LocalPackage), PackageName, localPackageName)
import Hix.Managed.Cabal.Data.SourcePackage (SourcePackage, SourcePackageId (..), SourcePackageVersions, SourcePackages)
import qualified Hix.Managed.Data.ManagedPackage as ManagedPackage
import Hix.Managed.Data.ManagedPackage (ManagedPackage)
import Hix.Managed.Data.Packages (Packages)
import Hix.Monad (noteClient)
allDeps :: [Dep] -> SourcePackage -> SourcePackage
allDeps deps =
nMap \ p -> p {deps = deps ++ p.deps}
where
allDep :: Dep -> SourcePackage -> SourcePackage
allDep = allDeps . pure
sourcePackageVersions :: SourcePackages -> SourcePackageVersions
sourcePackageVersions = nMap (sort . nKeys)
queryVersions :: SourcePackageVersions -> PackageName -> M [Version]
queryVersions packages query = noteClient [exon|No such package in the source db: ##{query}|] (packages !! query)
queryPackages :: SourcePackages -> PackageName -> M [Version]
queryPackages packages =
queryVersions (sourcePackageVersions packages)
queryVersionsLatest :: SourcePackageVersions -> PackageName -> M (Maybe Version)
queryVersionsLatest packages query = last <$> queryVersions packages query
queryPackagesLatest :: SourcePackages -> PackageName -> M (Maybe Version)
queryPackagesLatest packages =
queryVersionsLatest versions
where
versions = sourcePackageVersions packages
-- | This _must_ have the dependencies in both 'targetBuildDepends' and 'condTreeConstraints', otherwise they will be
-- ignored or deleted depending on what resolver params are used.
-- This is also evidenced by looking at a parsed Cabal file, see @CabalTest@.
mockSourcePackage :: PackageName -> Version -> SourcePackageId -> UnresolvedSourcePackage
mockSourcePackage name version SourcePackageId {description, deps} =
Cabal.SourcePackage {
srcpkgPackageId = cabalId,
srcpkgDescription = emptyGenericPackageDescription {
packageDescription = (fromMaybe emptyPackageDescription description) {
package = cabalId
},
condLibrary = Just library
},
srcpkgSource = LocalTarballPackage "/invalid",
srcpkgDescrOverride = Nothing
}
where
library =
mempty {
condTreeData = emptyLibrary {
libVisibility = LibraryVisibilityPublic,
libBuildInfo = mempty {targetBuildDepends = cabalDeps}
},
condTreeConstraints = cabalDeps
}
cabalId = PackageId.toCabal PackageId {..}
cabalDeps = Dep.toCabal <$> deps
mockSourcePackageDb :: SourcePackages -> SourcePackageDb
mockSourcePackageDb packages =
SourcePackageDb {
packageIndex = PackageIndex.fromList (nTo1 packages mockSourcePackage),
packagePreferences = []
}
managedSourcePackageVersions :: Packages ManagedPackage -> SourcePackageVersions
managedSourcePackageVersions =
nTransform \ (LocalPackage name) package -> (name, [package.version])
managedSourcePackage :: ManagedPackage -> UnresolvedSourcePackage
managedSourcePackage package =
mockSourcePackage (localPackageName package.package) package.version pid
where
pid = SourcePackageId {deps = ManagedPackage.deps package, description = Nothing}
managedPackageIndex :: Packages ManagedPackage -> PackageIndex UnresolvedSourcePackage
managedPackageIndex packages =
PackageIndex.fromList (managedSourcePackage <$> Map.elems (nGet packages))
dbWithManaged :: Packages ManagedPackage -> SourcePackageDb -> SourcePackageDb
dbWithManaged packages SourcePackageDb {packageIndex, packagePreferences} =
SourcePackageDb {
packageIndex = PackageIndex.merge packageIndex (managedPackageIndex packages),
packagePreferences
}