From e66106c7b77d6ee6df4948bbe144e4d520f8b311 Mon Sep 17 00:00:00 2001
From: Herbert Valerio Riedel <hvr@gnu.org>
Date: Sat, 3 Mar 2018 11:15:02 +0100
Subject: [PATCH] Set upper bound on setup.Cabal relative to current version

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.

This addresses #415
---
 .../Distribution/Client/Dependency.hs         | 16 ++++++++++++++
 .../Distribution/Client/ProjectPlanning.hs    | 21 +++++++++++++++++++
 .../Solver/Types/ConstraintSource.hs          |  6 ++++++
 3 files changed, 43 insertions(+)

diff --git a/cabal-install/Distribution/Client/Dependency.hs b/cabal-install/Distribution/Client/Dependency.hs
index e3eff39577..40c60c274c 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 50ae2ee221..1a51276dd8 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
@@ -1064,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 7697bbec6b..16afd2e0d8 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"
-- 
GitLab