Skip to content

Commit

Permalink
Support Cabal 3.4.0.0
Browse files Browse the repository at this point in the history
finalizePD uses PackageVersionConstraint instead of dependency since
3.4.0.0 (see also haskell/cabal#5570).
This is a bit annoying since we need to do some CPP-stuff to support
both 3.2.* and 3.4.0.0, but it is a good opportunity to clean up our use
of Dependency: Since we always ignore the `LibraryName`s in `Dependency`
and it is required to be a `NonEmptySet` since 3.4.0.0, we switch to
using the simpler `PackageVersionConstraint` which doesn't care about
`LibraryName` at all (just like us).
  • Loading branch information
sternenseemann committed Jun 10, 2021
1 parent 938b26d commit 2e7dca9
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 21 deletions.
13 changes: 7 additions & 6 deletions hackage2nix/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import Distribution.Nixpkgs.PackageMap
import Distribution.Package
import Distribution.PackageDescription hiding ( options, extraLibs, buildTools, homepage )
import Distribution.System
import Distribution.Types.PackageVersionConstraint
import Distribution.Text
import Distribution.Version
import Language.Nix
Expand Down Expand Up @@ -97,7 +98,7 @@ main = do
latestVersionSet = Map.map Set.findMax (Map.filter (not . Set.null) (Map.mapWithKey (enforcePreferredVersions preferredVersions) hackage))

defaultPackageOverridesSet :: PackageSet
defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(Dependency name _ _) <- defaultPackageOverrides config ]
defaultPackageOverridesSet = Map.fromList [ (name, resolveConstraint c hackage) | c@(PackageVersionConstraint name _) <- defaultPackageOverrides config ]

generatedDefaultPackageSet :: PackageSet
generatedDefaultPackageSet = (defaultPackageOverridesSet `Map.union` latestVersionSet) `Map.difference` corePackageSet
Expand All @@ -110,7 +111,7 @@ main = do

extraPackageSet :: PackageMultiSet
extraPackageSet = Map.unionsWith Set.union
[ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(Dependency name _ _) <- extraPackages config ]
[ Map.singleton name (Set.singleton (resolveConstraint c hackage)) | c@(PackageVersionConstraint name _) <- extraPackages config ]

db :: PackageMultiSet
db = Map.unionsWith Set.union [ Map.map Set.singleton generatedDefaultPackageSet
Expand All @@ -119,8 +120,8 @@ main = do
, extraPackageSet
]

haskellResolver :: Dependency -> Bool
haskellResolver (Dependency name vrange _)
haskellResolver :: HaskellResolver
haskellResolver (PackageVersionConstraint name vrange)
| Just v <- Map.lookup name corePackageSet = v `withinRange` vrange
| Just v <- Map.lookup name generatedDefaultPackageSet = v `withinRange` vrange
| otherwise = False
Expand All @@ -142,7 +143,7 @@ main = do
let isInDefaultPackageSet, isHydraEnabled, isBroken :: Bool
isInDefaultPackageSet = (== Just v) (Map.lookup name generatedDefaultPackageSet)
isHydraEnabled = isInDefaultPackageSet && not (isBroken || name `Set.member` dontDistributePackages config)
isBroken = any (withinRange v) [ vr | Dependency pn vr _ <- brokenPackages config, pn == name ]
isBroken = any (withinRange v) [ vr | PackageVersionConstraint pn vr <- brokenPackages config, pn == name ]

droppedPlatforms :: Set Platform
droppedPlatforms = Map.findWithDefault mempty name (unsupportedPlatforms config)
Expand Down Expand Up @@ -209,7 +210,7 @@ resolveConstraint c = fromMaybe (error msg) . resolveConstraint' c
]

resolveConstraint' :: Constraint -> Hackage -> Maybe Version
resolveConstraint' (Dependency name vrange _) hackage
resolveConstraint' (PackageVersionConstraint name vrange) hackage
| Just vset' <- Map.lookup name hackage
, vset <- Set.filter (`withinRange` vrange) vset'
, not (Set.null vset) = Just (Set.findMax vset)
Expand Down
10 changes: 7 additions & 3 deletions src/Distribution/Nixpkgs/Haskell/Constraint.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
module Distribution.Nixpkgs.Haskell.Constraint
( Constraint, satisfiesConstraint, satisfiesConstraints
( Constraint, constraintPkgName, satisfiesConstraint, satisfiesConstraints
) where

import Distribution.Package
import Distribution.Version
import Distribution.Types.PackageVersionConstraint
import Distribution.Nixpkgs.Haskell.OrphanInstances ( )

type Constraint = Dependency
type Constraint = PackageVersionConstraint

constraintPkgName :: Constraint -> PackageName
constraintPkgName (PackageVersionConstraint n _) = n

satisfiesConstraint :: PackageIdentifier -> Constraint -> Bool
satisfiesConstraint (PackageIdentifier pn v) (Dependency cn vr _) = (pn /= cn) || (v `withinRange` vr)
satisfiesConstraint (PackageIdentifier pn v) (PackageVersionConstraint cn vr) = (pn /= cn) || (v `withinRange` vr)

satisfiesConstraints :: PackageIdentifier -> [Constraint] -> Bool
satisfiesConstraints p = all (satisfiesConstraint p)
27 changes: 22 additions & 5 deletions src/Distribution/Nixpkgs/Haskell/FromCabal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Distribution.PackageDescription
import qualified Distribution.PackageDescription as Cabal
import Distribution.PackageDescription.Configuration as Cabal
import Distribution.System
import Distribution.Types.PackageVersionConstraint
import Distribution.Text ( display )
import Distribution.Types.ComponentRequestedSpec as Cabal
import Distribution.Types.ExeDependency as Cabal
Expand All @@ -36,7 +37,7 @@ import Distribution.Utils.ShortText ( fromShortText )
import Distribution.Version
import Language.Nix

type HaskellResolver = Dependency -> Bool
type HaskellResolver = PackageVersionConstraint -> Bool
type NixpkgsResolver = Identifier -> Maybe Binding

fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> Derivation
Expand All @@ -48,10 +49,26 @@ fromGenericPackageDescription haskellResolver nixpkgsResolver arch compiler flag
finalizeGenericPackageDescription :: HaskellResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> (PackageDescription, [Dependency])
finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc =
let
-- finalizePD incooperates the 'LibraryName' of a dependency
-- which we always ignore, so the Cabal-compatible resolver
-- is a simple wrapper around our 'HaskellResolver'
makeCabalResolver :: HaskellResolver -> Dependency -> Bool
makeCabalResolver r (Dependency n v _) = r (PackageVersionConstraint n v)

-- the finalizePD API changed in Cabal 3.4.0.0, so we need to do some plumbing.
-- See https://github.com/haskell/cabal/issues/5570
#if MIN_VERSION_Cabal(3,4,0)
makeCabalConstraints :: [Constraint] -> [PackageVersionConstraint]
makeCabalConstraints = id
#else
makeCabalConstraints :: [Constraint] -> [Dependency]
makeCabalConstraints = map $ \(PackageVersionConstraint n v) -> Dependency n v mempty
#endif

-- We have to call the Cabal finalizer several times with different resolver
-- functions, and this convenience function makes our code shorter.
finalize :: HaskellResolver -> Either [Dependency] (PackageDescription,FlagAssignment)
finalize resolver = finalizePD flags requestedComponents resolver arch compiler constraints genDesc
finalize resolver = finalizePD flags requestedComponents (makeCabalResolver resolver) arch compiler (makeCabalConstraints constraints) genDesc

requestedComponents :: ComponentRequestedSpec
requestedComponents = ComponentRequestedSpec
Expand All @@ -60,10 +77,10 @@ finalizeGenericPackageDescription haskellResolver arch compiler flags constraint
}

jailbroken :: HaskellResolver -> HaskellResolver
jailbroken resolver (Dependency pkg _ _) = resolver (Dependency pkg anyVersion mempty)
jailbroken resolver (PackageVersionConstraint pkg _) = resolver (PackageVersionConstraint pkg anyVersion)

withInternalLibs :: HaskellResolver -> HaskellResolver
withInternalLibs resolver d = depPkgName d `elem` internalNames || resolver d
withInternalLibs resolver c = constraintPkgName c `elem` internalNames || resolver c

internalNames :: [PackageName]
internalNames = [ unqualComponentNameToPackageName n | (n,_) <- condSubLibraries genDesc ]
Expand Down Expand Up @@ -152,7 +169,7 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package
| otherwise = bindNull i

resolveInHackageThenNixpkgs :: Identifier -> Binding
resolveInHackageThenNixpkgs i | haskellResolver (Dependency (mkPackageName (i^.ident)) anyVersion mempty) = resolveInHackage i
resolveInHackageThenNixpkgs i | haskellResolver (PackageVersionConstraint (mkPackageName (i^.ident)) anyVersion) = resolveInHackage i
| otherwise = resolveInNixpkgs i

internalLibNames :: [PackageName]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ assertConsistency :: MonadFail m => Configuration -> m Configuration
assertConsistency cfg@Configuration {..} = do
let report msg = fail ("*** configuration error: " ++ msg)
maintainedPackages = Set.unions (Map.elems packageMaintainers)
disabledPackages = dontDistributePackages `Set.union` Set.fromList (depPkgName <$> brokenPackages)
disabledPackages = dontDistributePackages `Set.union` Set.fromList (constraintPkgName <$> brokenPackages)
disabledMaintainedPackages = maintainedPackages `Set.intersection` disabledPackages
unless (Set.null disabledMaintainedPackages) $
report ("disabled packages that have a maintainer: " ++ show disabledMaintainedPackages)
Expand Down
5 changes: 3 additions & 2 deletions src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import Distribution.Nixpkgs.Meta
import Distribution.Nixpkgs.License
import Distribution.Package
import Distribution.System
import Distribution.Types.PackageVersionConstraint
import Distribution.Text
import Distribution.Version
import Language.Nix

postProcess :: Derivation -> Derivation
postProcess deriv =
foldr (.) id [ f | (Dependency n vr _, f) <- hooks, packageName deriv == n, packageVersion deriv `withinRange` vr ]
foldr (.) id [ f | (PackageVersionConstraint n vr, f) <- hooks, packageName deriv == n, packageVersion deriv `withinRange` vr ]
. fixGtkBuilds
. fixBuildDependsForTools
$ deriv
Expand Down Expand Up @@ -70,7 +71,7 @@ fixBuildDependsForTools = foldr (.) id
]
]

hooks :: [(Dependency, Derivation -> Derivation)]
hooks :: [(PackageVersionConstraint, Derivation -> Derivation)]
hooks =
[ ("Agda < 2.5", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agdaPostInstall)
, ("Agda >= 2.5 && < 2.6", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agda25PostInstall)
Expand Down
9 changes: 5 additions & 4 deletions src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Distribution.Compiler
import Distribution.Package
import Distribution.Parsec
import Distribution.System
import Distribution.Types.PackageVersionConstraint
import Distribution.Pretty as Cabal
import qualified Data.Version as Base
import Distribution.Version
Expand All @@ -28,8 +29,8 @@ instance IsString VersionRange where
instance IsString PackageIdentifier where
fromString = text2isString "PackageIdentifier"

instance IsString Dependency where
fromString = text2isString "Dependency"
instance IsString PackageVersionConstraint where
fromString = text2isString "PackageVersionConstraint"

instance IsString CompilerId where
fromString = text2isString "CompilerId"
Expand Down Expand Up @@ -58,9 +59,9 @@ instance FromJSON VersionRange where
parseJSON (String s) = return (fromString (T.unpack s))
parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Cabal VersionRange")

instance FromJSON Dependency where
instance FromJSON PackageVersionConstraint where
parseJSON (String s) = return (fromString (T.unpack s))
parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell Dependency")
parseJSON s = fail ("parseJSON: " ++ show s ++ " is not a valid Haskell PackageVersionConstraint")

instance FromJSON CompilerInfo where
parseJSON (String s) = return (unknownCompilerInfo (fromString (T.unpack s)) NoAbiTag)
Expand Down

0 comments on commit 2e7dca9

Please sign in to comment.