From 2e7dca9fc2cc0b679603105499ee826310996cae Mon Sep 17 00:00:00 2001 From: sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> Date: Thu, 10 Jun 2021 16:50:57 +0200 Subject: [PATCH] Support Cabal 3.4.0.0 finalizePD uses PackageVersionConstraint instead of dependency since 3.4.0.0 (see also https://github.com/haskell/cabal/issues/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). --- hackage2nix/Main.hs | 13 ++++----- .../Nixpkgs/Haskell/Constraint.hs | 10 ++++--- src/Distribution/Nixpkgs/Haskell/FromCabal.hs | 27 +++++++++++++++---- .../Haskell/FromCabal/Configuration.hs | 2 +- .../Nixpkgs/Haskell/FromCabal/PostProcess.hs | 5 ++-- .../Nixpkgs/Haskell/OrphanInstances.hs | 9 ++++--- 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/hackage2nix/Main.hs b/hackage2nix/Main.hs index 9817e6784..5c5b272e1 100644 --- a/hackage2nix/Main.hs +++ b/hackage2nix/Main.hs @@ -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 @@ -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 @@ -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 @@ -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 @@ -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) @@ -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) diff --git a/src/Distribution/Nixpkgs/Haskell/Constraint.hs b/src/Distribution/Nixpkgs/Haskell/Constraint.hs index 2ebb152b7..422bf52fa 100644 --- a/src/Distribution/Nixpkgs/Haskell/Constraint.hs +++ b/src/Distribution/Nixpkgs/Haskell/Constraint.hs @@ -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) diff --git a/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index da35d149a..47b2a0980 100644 --- a/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -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 @@ -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 @@ -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 @@ -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 ] @@ -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] diff --git a/src/Distribution/Nixpkgs/Haskell/FromCabal/Configuration.hs b/src/Distribution/Nixpkgs/Haskell/FromCabal/Configuration.hs index 449e599c8..fa0d4f454 100644 --- a/src/Distribution/Nixpkgs/Haskell/FromCabal/Configuration.hs +++ b/src/Distribution/Nixpkgs/Haskell/FromCabal/Configuration.hs @@ -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) diff --git a/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs index 5d452c3e6..df1916f49 100644 --- a/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs +++ b/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs @@ -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 @@ -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) diff --git a/src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs b/src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs index a6f8e4f8c..b16c4e6ca 100644 --- a/src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs +++ b/src/Distribution/Nixpkgs/Haskell/OrphanInstances.hs @@ -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 @@ -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" @@ -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)