diff --git a/cabal-install/Distribution/Client/Dependency.hs b/cabal-install/Distribution/Client/Dependency.hs index e3eff395779..40c60c274c6 100644 --- a/cabal-install/Distribution/Client/Dependency.hs +++ b/cabal-install/Distribution/Client/Dependency.hs @@ -61,6 +61,7 @@ module Distribution.Client.Dependency ( removeUpperBounds, addDefaultSetupDependencies, addSetupCabalMinVersionConstraint, + addSetupCabalMaxVersionConstraint, ) where import Distribution.Solver.Modular @@ -555,6 +556,21 @@ addSetupCabalMinVersionConstraint minVersion = where cabalPkgname = mkPackageName "Cabal" +-- | Variant of 'addSetupCabalMinVersionConstraint' which sets an +-- upper bound on @setup.Cabal@ labeled with 'ConstraintSetupCabalMaxVersion'. +-- +addSetupCabalMaxVersionConstraint :: Version + -> DepResolverParams -> DepResolverParams +addSetupCabalMaxVersionConstraint maxVersion = + addConstraints + [ LabeledPackageConstraint + (PackageConstraint (ScopeAnySetupQualifier cabalPkgname) + (PackagePropertyVersion $ earlierVersion maxVersion)) + ConstraintSetupCabalMaxVersion + ] + where + cabalPkgname = mkPackageName "Cabal" + upgradeDependencies :: DepResolverParams -> DepResolverParams upgradeDependencies = setPreferenceDefault PreferAllLatest diff --git a/cabal-install/Distribution/Client/ProjectPlanning.hs b/cabal-install/Distribution/Client/ProjectPlanning.hs index 8fa2d9ec8e8..1a51276dd8c 100644 --- a/cabal-install/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/Distribution/Client/ProjectPlanning.hs @@ -80,6 +80,7 @@ import qualified Distribution.Client.SolverInstallPlan as SolverInstallPlan import Distribution.Client.Dependency import Distribution.Client.Dependency.Types import qualified Distribution.Client.IndexUtils as IndexUtils +import Distribution.Client.Init (incVersion) import Distribution.Client.Targets (userToPackageConstraint) import Distribution.Client.DistDirLayout import Distribution.Client.SetupWrapper @@ -950,6 +951,7 @@ planPackages verbosity comp platform solver SolverSettings{..} . packageDescription) . addSetupCabalMinVersionConstraint setupMinCabalVersionConstraint + . addSetupCabalMaxVersionConstraint setupMaxCabalVersionConstraint . addPreferences -- preferences from the config file or command line @@ -1039,7 +1041,7 @@ planPackages verbosity comp platform solver SolverSettings{..} -- respective major Cabal version bundled with the respective GHC -- release). -- - -- GHC 8.4 needs Cabal >= 2.1 (GHC 8.4.1-rc1 has Cabal-2.1) + -- GHC 8.4 needs Cabal >= 2.2 -- GHC 8.2 needs Cabal >= 2.0 -- GHC 8.0 needs Cabal >= 1.24 -- GHC 7.10 needs Cabal >= 1.22 @@ -1050,6 +1052,10 @@ planPackages verbosity comp platform solver SolverSettings{..} -- TODO: long-term, this compatibility matrix should be -- stored as a field inside 'Distribution.Compiler.Compiler' setupMinCabalVersionConstraint + | isGHC, compVer >= mkVersion [8,4,1] = mkVersion [2,2] + -- GHC 8.4.1-rc1 (GHC 8.4.0.20180224) still shipped with an + -- devel snapshot of Cabal-2.1.0.0; the rule below can be + -- dropped at some point | isGHC, compVer >= mkVersion [8,4] = mkVersion [2,1] | isGHC, compVer >= mkVersion [8,2] = mkVersion [2,0] | isGHC, compVer >= mkVersion [8,0] = mkVersion [1,24] @@ -1060,6 +1066,25 @@ planPackages verbosity comp platform solver SolverSettings{..} compFlav = compilerFlavor comp compVer = compilerVersion comp + -- As we can't predict the future, we also place a global upper + -- bound on the lib:Cabal version we know how to interact with: + -- + -- The upper bound is computed by incrementing the current major + -- version twice in order to allow for the current version, as + -- well as the next adjacent major version (one of which will not + -- be released, as only "even major" versions of Cabal are + -- released to Hackage or bundled with proper GHC releases). + -- + -- For instance, if the current version of cabal-install is an odd + -- development version, e.g. Cabal-2.1.0.0, then we impose an + -- upper bound `setup.Cabal < 2.3`; if `cabal-install` is on a + -- stable/release even version, e.g. Cabal-2.2.1.0, the upper + -- bound is `setup.Cabal < 2.4`. This gives us enough flexibility + -- when dealing with development snapshots of Cabal and cabal-install. + -- + setupMaxCabalVersionConstraint = + alterVersion (take 2) $ incVersion 1 $ incVersion 1 cabalVersion + ------------------------------------------------------------------------------ -- * Install plan post-processing ------------------------------------------------------------------------------ diff --git a/cabal-install/Distribution/Solver/Types/ConstraintSource.hs b/cabal-install/Distribution/Solver/Types/ConstraintSource.hs index 7697bbec6b6..16afd2e0d80 100644 --- a/cabal-install/Distribution/Solver/Types/ConstraintSource.hs +++ b/cabal-install/Distribution/Solver/Types/ConstraintSource.hs @@ -49,6 +49,10 @@ data ConstraintSource = -- | An internal constraint due to compatibility issues with the Setup.hs -- command line interface requires a minimum lower bound on Cabal | ConstraintSetupCabalMinVersion + + -- | An internal constraint due to compatibility issues with the Setup.hs + -- command line interface requires a maximum upper bound on Cabal + | ConstraintSetupCabalMaxVersion deriving (Eq, Show, Generic) instance Binary ConstraintSource @@ -74,3 +78,5 @@ showConstraintSource ConstraintSourceConfigFlagOrTarget = showConstraintSource ConstraintSourceUnknown = "unknown source" showConstraintSource ConstraintSetupCabalMinVersion = "minimum version of Cabal used by Setup.hs" +showConstraintSource ConstraintSetupCabalMaxVersion = + "maximum version of Cabal used by Setup.hs" diff --git a/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.out b/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.out index 1f5437704ea..de5fbf4bddc 100644 --- a/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.out +++ b/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.out @@ -4,5 +4,4 @@ Downloading the latest package list from test-local-repo Resolving dependencies... Build profile: -w ghc- -O1 In order, the following would be built: - - Cabal-99999 (lib) (requires download & build) - time-99999 (lib:time) (first run) diff --git a/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.test.hs b/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.test.hs index 54c56fe2ce0..59aad8b34ef 100644 --- a/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.test.hs +++ b/cabal-testsuite/PackageTests/Regression/T4154/install-time-with-constraint.test.hs @@ -9,7 +9,9 @@ main = cabalTest $ withRepo "repo" $ do -- Temporarily disabled recording here because output is not stable recordMode DoNotRecord $ do - -- Constraining all uses of 'time' results in a cyclic dependency - -- between 'Cabal' and the new 'time'. - r <- fails $ cabal' "new-build" ["time", "--constraint=any.time==99999", "--dry-run"] - assertOutputContains "cyclic dependencies; conflict set: time:setup.Cabal, time:setup.time" r + r <- fails $ cabal' "new-build" ["time", "--constraint=any.time==99999", "--constraint=setup.Cabal installed", "--dry-run"] + -- Constraining all uses of 'time' originally resulted in a cyclic dependency + -- between 'Cabal' and the new 'time': + -- assertOutputContains "cyclic dependencies; conflict set: time:setup.Cabal, time:setup.time" r + -- However, this doesn't work anymore, so instead we more directly look for: + assertOutputContains "time:setup.time~>time-99999 (conflict: time:setup.Cabal" r diff --git a/cabal-testsuite/PackageTests/Regression/T4154/time.cabal b/cabal-testsuite/PackageTests/Regression/T4154/time.cabal index ad72efcdae9..ac9899b035f 100644 --- a/cabal-testsuite/PackageTests/Regression/T4154/time.cabal +++ b/cabal-testsuite/PackageTests/Regression/T4154/time.cabal @@ -4,7 +4,7 @@ cabal-version: >=1.8 build-type: Custom custom-setup - setup-depends: base, Cabal == 99999 + setup-depends: base, Cabal library build-depends: base