diff --git a/Cabal-syntax/src/Distribution/Version.hs b/Cabal-syntax/src/Distribution/Version.hs index 2abf88100a8..a53a85b80fb 100644 --- a/Cabal-syntax/src/Distribution/Version.hs +++ b/Cabal-syntax/src/Distribution/Version.hs @@ -108,9 +108,13 @@ import Distribution.Types.VersionRange -- | This is the converse of 'isAnyVersion'. It check if the version range is -- empty, if there is no possible version that satisfies the version range. -- --- For example this is @True@ (for all @v@): +-- For example, @\v@ is no version for all @v@. -- --- > isNoVersion (EarlierVersion v `IntersectVersionRanges` LaterVersion v) +-- >>> ordNub [isNoVersion (earlierVersion v `intersectVersionRanges` laterVersion v) | v <- mkVersion <$> [[0],[1]]] +-- [True] +-- +-- >>> isNoVersion <$> [noVersion, anyVersion] +-- [True,False] isNoVersion :: VersionRange -> Bool isNoVersion vr = case asVersionIntervals vr of [] -> True @@ -118,8 +122,11 @@ isNoVersion vr = case asVersionIntervals vr of -- | Is this version range in fact just a specific version? -- --- For example the version range @\">= 3 && <= 3\"@ contains only the version +-- For example the version range @\>= 3 && <= 3@ contains only the version -- @3@. +-- +-- >>> isSpecificVersion (orLaterVersion (mkVersion [3]) `intersectVersionRanges` orEarlierVersion (mkVersion [3])) +-- Just (mkVersion [3]) isSpecificVersion :: VersionRange -> Maybe Version isSpecificVersion vr = case asVersionIntervals vr of [VersionInterval (LowerBound v InclusiveBound) (UpperBound v' InclusiveBound)] @@ -222,5 +229,6 @@ transformCaretLower = hyloVersionRange embed projectVersionRange -- >>> :set -XScopedTypeVariables -- >>> import Distribution.Parsec -- >>> import Distribution.Pretty +-- >>> import Distribution.Utils.Generic (ordNub) -- >>> -- >>> mapVR f xs = [pretty $ f v| Just v <- simpleParsec <$> xs] diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs index 1b6fa0b3af5..16a1b1ff13b 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Message.hs @@ -309,7 +309,7 @@ showFR _ (PackageRequiresMissingComponent qpn comp) = " (requires " ++ showExpos showFR _ (PackageRequiresPrivateComponent qpn comp) = " (requires " ++ showExposedComponent comp ++ " from " ++ showQPN qpn ++ ", but the component is private)" showFR _ (PackageRequiresUnbuildableComponent qpn comp) = " (requires " ++ showExposedComponent comp ++ " from " ++ showQPN qpn ++ ", but the component is not buildable in the current environment)" showFR _ CannotReinstall = " (avoiding to reinstall a package with same version but new dependencies)" -showFR _ NotExplicit = " (not a user-provided goal nor mentioned as a constraint, but reject-unconstrained-dependencies was set)" +showFR _ NotExplicit = " (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)" showFR _ Shadowed = " (shadowed by another installed package with same version)" showFR _ (Broken u) = " (package is broken, missing dependency " ++ prettyShow u ++ ")" showFR _ UnknownPackage = " (unknown package)" diff --git a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs index cb9b204b5cb..f2197379076 100644 --- a/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE ViewPatterns #-} #ifdef DEBUG_TRACETREE {-# OPTIONS_GHC -Wno-orphans #-} #endif @@ -18,6 +19,7 @@ import Distribution.Verbosity import Distribution.Compiler (CompilerInfo) +import Distribution.Version import Distribution.Solver.Types.PackagePath import Distribution.Solver.Types.PackagePreferences import Distribution.Solver.Types.PkgConfigDb (PkgConfigDb) @@ -41,6 +43,7 @@ import Distribution.Solver.Modular.PSQ (PSQ) import Distribution.Solver.Modular.RetryLog import Distribution.Solver.Modular.Tree import qualified Distribution.Solver.Modular.PSQ as PSQ +import Distribution.Solver.Types.PackageConstraint import Distribution.Simple.Setup (BooleanFlag(..)) @@ -140,15 +143,13 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = prunePhase = (if asBool (avoidReinstalls sc) then P.avoidReinstalls (const True) else id) . (case onlyConstrained sc of OnlyConstrainedAll -> - P.onlyConstrained pkgIsExplicit + P.onlyConstrained (`S.member` versionConstrainedOrGoals) OnlyConstrainedNone -> id) buildPhase = buildTree idx (independentGoals sc) (S.toList userGoals) - allExplicit = M.keysSet userConstraints `S.union` userGoals - - pkgIsExplicit :: PN -> Bool - pkgIsExplicit pn = S.member pn allExplicit + versionConstrained = filterVersion isVersionConstrained userConstraints + versionConstrainedOrGoals = versionConstrained `S.union` userGoals -- When --reorder-goals is set, we use preferReallyEasyGoalChoices, which -- prefers (keeps) goals only if the have 0 or 1 enabled choice. @@ -166,6 +167,25 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals = | asBool (reorderGoals sc) = P.preferReallyEasyGoalChoices | otherwise = id {- P.firstGoal -} +-- | Keep package names of constraints that satisfy the predicate. +filterVersion :: (LabeledPackageConstraint -> Bool) -> M.Map PN [LabeledPackageConstraint] -> Set PN +filterVersion versionFilter = M.keysSet . M.filter (not . null) . M.map (filter versionFilter) + +normalise :: VersionRange -> VersionRange +normalise = fromVersionIntervals . toVersionIntervals + +-- | Unconstrained with a version range @>=0@ or @<0@ or their flag equivalents +-- and constrained by other versions ranges. +-- +-- Both the @-any@ and @-none@ flags are considered unconstrained, because they +-- don't actually constrain the version of the package. The @-any@ flag allows +-- any version, and the @-none@ flag effectively excludes a package. +isVersionConstrained :: LabeledPackageConstraint -> Bool +isVersionConstrained (LabeledPackageConstraint (PackageConstraint _ c) _) = case c of + PackagePropertyVersion (normalise -> vr) -> not (isAnyVersion vr || isNoVersion vr) + -- `PackagePropertyFlags` @-any@ and @-none@ are covered below. + _ -> False + -- | Dump solver tree to a file (in debugging mode) -- -- This only does something if the @debug-tracetree@ configure argument was diff --git a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs index b3780e2a345..d76928e982f 100644 --- a/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs +++ b/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs @@ -242,33 +242,117 @@ tests = mkTest dbBaseOld "Refuse to install very old base" ["base"] $ solverFailure (isInfixOf "rejecting: base-1 (constraint from non-reinstallable package requires >=4.22)") ] - , testGroup + , -- reject-unconstrained-dependencies=all requires all non-goals to be + -- version constrained. Goals don't need constraints and flag constraints + -- are not enough. + testGroup "reject-unconstrained" - [ runTest $ - onlyConstrained $ - mkTest db12 "missing syb" ["E"] $ - solverFailure (isInfixOf "not a user-provided goal") - , runTest $ - onlyConstrained $ - mkTest db12 "all goals" ["E", "syb"] $ - solverSuccess [("E", 1), ("syb", 2)] - , runTest $ - onlyConstrained $ - mkTest db17 "backtracking" ["A", "B"] $ - solverSuccess [("A", 2), ("B", 1)] - , runTest $ - onlyConstrained $ - mkTest db17 "failure message" ["A"] $ - solverFailure $ - isInfixOf $ - "Could not resolve dependencies:\n" - ++ "[__0] trying: A-3 (user goal)\n" - ++ "[__1] next goal: C (dependency of A)\n" - ++ "[__1] fail (not a user-provided goal nor mentioned as a constraint, " - ++ "but reject-unconstrained-dependencies was set)\n" - ++ "[__1] fail (backjumping, conflict set: A, C)\n" - ++ "After searching the rest of the dependency tree exhaustively, " - ++ "these were the goals I've had most trouble fulfilling: A, C, B" + [ testGroup + "[A, B]" + [ runTest $ + onlyConstrained $ + mkTest db17 "accept backtracking finds all goals closed set" ["A", "B"] $ + solverSuccess [("A", 2), ("B", 1)] + , runTest $ + constraints [ExVersionConstraint (ScopeAnyQualifier "B") (V.thisVersion (V.mkVersion [1]))] $ + onlyConstrained $ + mkTest db17 "accept non-goal 'B' version-constrained" ["A"] $ + solverSuccess [("A", 2), ("B", 1)] + , runTest $ + constraints [ExFlagConstraint (ScopeAnyQualifier "B") "flag" False] $ + onlyConstrained $ + mkTest db17 "reject non-goal 'B' flag-constrained" ["A", "C"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: C-1 (user goal)\n\ + \[__1] next goal: B (dependency of C)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: B, C)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: C, B" + , runTest $ + onlyConstrained $ + mkTest db17 "reject non-goal 'C' unconstrained" ["A"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: A-3 (user goal)\n\ + \[__1] next goal: C (dependency of A)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: A, C)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: A, C, B" + ] + , testGroup + "[base, syb, E]" + [ runTest $ + onlyConstrained $ + mkTest db12 "accept all goals, no other dependencies" ["base", "E", "syb"] $ + solverSuccess [("E", 1), ("syb", 2)] + , runTest $ + constraints [ExVersionConstraint (ScopeAnyQualifier "base") (V.thisVersion (V.mkVersion [4]))] $ + onlyConstrained $ + mkTest db12 "accept non-goal 'base' version-constrained" ["E", "syb"] $ + solverSuccess [("E", 1), ("syb", 2)] + , runTest $ + constraints [ExVersionConstraint (ScopeAnyQualifier "syb") (V.thisVersion (V.mkVersion [2]))] $ + onlyConstrained $ + mkTest db12 "accept non-goal 'syb' version-constrained" ["base", "E"] $ + solverSuccess [("E", 1), ("syb", 2)] + , runTest + $ constraints + [ ExVersionConstraint (ScopeAnyQualifier "base") (V.thisVersion (V.mkVersion [4])) + , ExVersionConstraint (ScopeAnyQualifier "syb") (V.thisVersion (V.mkVersion [2])) + ] + $ onlyConstrained + $ mkTest db12 "accept non-goals 'base' and 'syb' version-unconstrained" ["E"] + $ solverSuccess [("E", 1), ("syb", 2)] + , runTest $ + onlyConstrained $ + mkTest db12 "reject non-goal 'base' unconstrained" ["E", "syb"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: E-1 (user goal)\n\ + \[__1] next goal: E.base (dependency of E)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: E, E.base)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: E, E.base" + , runTest $ + onlyConstrained $ + mkTest db12 "reject non-goal 'syb' unconstrained" ["base", "E"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: E-1 (user goal)\n\ + \[__1] next goal: syb (dependency of E)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: E, syb)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: E, syb" + , runTest $ + constraints [ExFlagConstraint (ScopeAnyQualifier "base") "flag" True] $ + onlyConstrained $ + mkTest db12 "reject non-goal 'base' only flag-constrained" ["E", "syb"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: E-1 (user goal)\n\ + \[__1] next goal: E.base (dependency of E)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: E, E.base)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: E, E.base" + , runTest $ + constraints [ExStanzaConstraint (ScopeAnyQualifier "base") [TestStanzas]] $ + onlyConstrained $ + mkTest db12 "reject non-goal 'base' only stanza-constrained" ["E", "syb"] $ + solverFailure $ + isInfixOf + "Could not resolve dependencies:\n\ + \[__0] trying: E-1 (user goal)\n\ + \[__1] next goal: E.base (dependency of E)\n\ + \[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all)\n\ + \[__1] fail (backjumping, conflict set: E, E.base)\n\ + \After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: E, E.base" + ] ] , testGroup "Cycles" diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/a.cabal b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/a.cabal new file mode 100644 index 00000000000..5d9797ccf7d --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/a.cabal @@ -0,0 +1,7 @@ +cabal-version: 2.2 +name: a +version: 0 + +library + build-depends: + some-lib diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-flag.out b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-flag.out new file mode 100644 index 00000000000..49872a08df4 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-flag.out @@ -0,0 +1,14 @@ +# tar +# tar +# tar +# cabal v2-update +Downloading the latest package list from test-local-repo +# cabal v2-build +Resolving dependencies... +Error: [Cabal-7107] +Could not resolve dependencies: +[__0] trying: a-0 (user goal) +[__1] next goal: some-lib (dependency of a) +[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all) +[__1] fail (backjumping, conflict set: a, some-lib) +After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: a (2), some-lib (1) diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-version.out b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-version.out new file mode 100644 index 00000000000..49872a08df4 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.any-version.out @@ -0,0 +1,14 @@ +# tar +# tar +# tar +# cabal v2-update +Downloading the latest package list from test-local-repo +# cabal v2-build +Resolving dependencies... +Error: [Cabal-7107] +Could not resolve dependencies: +[__0] trying: a-0 (user goal) +[__1] next goal: some-lib (dependency of a) +[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all) +[__1] fail (backjumping, conflict set: a, some-lib) +After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: a (2), some-lib (1) diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-flag.out b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-flag.out new file mode 100644 index 00000000000..49872a08df4 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-flag.out @@ -0,0 +1,14 @@ +# tar +# tar +# tar +# cabal v2-update +Downloading the latest package list from test-local-repo +# cabal v2-build +Resolving dependencies... +Error: [Cabal-7107] +Could not resolve dependencies: +[__0] trying: a-0 (user goal) +[__1] next goal: some-lib (dependency of a) +[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all) +[__1] fail (backjumping, conflict set: a, some-lib) +After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: a (2), some-lib (1) diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-version.out b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-version.out new file mode 100644 index 00000000000..49872a08df4 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.none-version.out @@ -0,0 +1,14 @@ +# tar +# tar +# tar +# cabal v2-update +Downloading the latest package list from test-local-repo +# cabal v2-build +Resolving dependencies... +Error: [Cabal-7107] +Could not resolve dependencies: +[__0] trying: a-0 (user goal) +[__1] next goal: some-lib (dependency of a) +[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all) +[__1] fail (backjumping, conflict set: a, some-lib) +After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: a (2), some-lib (1) diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.out b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.out new file mode 100644 index 00000000000..49872a08df4 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.out @@ -0,0 +1,14 @@ +# tar +# tar +# tar +# cabal v2-update +Downloading the latest package list from test-local-repo +# cabal v2-build +Resolving dependencies... +Error: [Cabal-7107] +Could not resolve dependencies: +[__0] trying: a-0 (user goal) +[__1] next goal: some-lib (dependency of a) +[__1] fail (not a user-provided goal nor mentioned as a constraint when reject-unconstrained-dependencies=all) +[__1] fail (backjumping, conflict set: a, some-lib) +After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: a (2), some-lib (1) diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.project b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.project new file mode 100644 index 00000000000..167c82a6219 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.project @@ -0,0 +1,3 @@ +packages: . +constraints: some-lib +some-flag +reject-unconstrained-dependencies: all diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.test.hs b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.test.hs new file mode 100644 index 00000000000..044f5d36759 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/cabal.test.hs @@ -0,0 +1,24 @@ +import Test.Cabal.Prelude +main = do + cabalTest . recordMode RecordMarked $ withRepo "repo" $ do + res <- fails $ cabal' "v2-build" ["all", "--dry-run"] + assertOutputContains "not a user-provided goal" res + + -- The following all check version ranges that don't have a version + -- constrained dependency one way or another. + + cabalTest' "any-flag" . recordMode RecordMarked $ withRepo "repo" $ do + res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--constraint", "some-lib -any"] + assertOutputContains "not a user-provided goal" res + + cabalTest' "any-version" . recordMode RecordMarked $ withRepo "repo" $ do + res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--constraint", "some-lib >=0"] + assertOutputContains "not a user-provided goal" res + + cabalTest' "none-flag" . recordMode RecordMarked $ withRepo "repo" $ do + res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--constraint", "some-lib -none"] + assertOutputContains "not a user-provided goal" res + + cabalTest' "none-version" . recordMode RecordMarked $ withRepo "repo" $ do + res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--constraint", "some-lib <0"] + assertOutputContains "not a user-provided goal" res diff --git a/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/repo b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/repo new file mode 120000 index 00000000000..2dd2305a132 --- /dev/null +++ b/cabal-testsuite/PackageTests/RequireExplicit/FlagNotVersion/repo @@ -0,0 +1 @@ +../repo/ \ No newline at end of file diff --git a/cabal-testsuite/PackageTests/RequireExplicit/MultiPkg/cabal.test.hs b/cabal-testsuite/PackageTests/RequireExplicit/MultiPkg/cabal.test.hs index 271bddebf0b..11dd7c8e341 100644 --- a/cabal-testsuite/PackageTests/RequireExplicit/MultiPkg/cabal.test.hs +++ b/cabal-testsuite/PackageTests/RequireExplicit/MultiPkg/cabal.test.hs @@ -9,8 +9,18 @@ main = cabalTest . recordMode DoNotRecord $ withRepo "repo" $ do res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "other-lib -any"] assertOutputContains "not a user-provided goal" res - -- everything's listed, good to go - cabal "v2-build" ["all", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "other-lib -any", "--constraint", "some-exe -any"] + -- everything's listed, but -any is not a version constraint accepted by reject-unconstrained-dependencies=all + res <- fails $ cabal' "v2-build" ["all", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "other-lib -any", "--constraint", "some-exe -any"] + assertOutputContains "not a user-provided goal" res + + -- everything's listed, good to go if we give proper version constraints + res <- cabal' "v2-build" ["all", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "some-lib ==1.0", "--constraint", "other-lib ==1.0", "--constraint", "some-exe ==1.0"] + assertOutputDoesNotContain "not a user-provided goal" res + + -- a depends on b, but b is a local dependency, so it gets a pass, but we still need to provide version constraints for the other dependencies + res <- fails $ cabal' "v2-build" ["a", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "other-lib -any", "--constraint", "some-exe -any"] + assertOutputContains "not a user-provided goal" res - -- a depends on b, but b is a local dependency, so it gets a pass - cabal "v2-build" ["a", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "other-lib -any", "--constraint", "some-exe -any"] + -- a depends on b, but b is a local dependency, so it gets a pass and we're good to go if we give proper version constraints + res <- cabal' "v2-build" ["a", "--dry-run", "--reject-unconstrained-dependencies", "all", "--constraint", "some-lib ==1.0", "--constraint", "other-lib ==1.0", "--constraint", "some-exe ==1.0"] + assertOutputDoesNotContain "not a user-provided goal" res diff --git a/changelog.d/12191.md b/changelog.d/12191.md new file mode 100644 index 00000000000..c5b2555b20a --- /dev/null +++ b/changelog.d/12191.md @@ -0,0 +1,11 @@ +--- +synopsis: Reject dependencies with unconstrained versions +packages: [cabal-install] +prs: 12191 +issues: 12190 +--- + +Change the behaviour of `--reject-unconstrained-dependencies=all` so that it is +not satisfied by flag constraints. Only version constraints should satisfy this +check and even then these need to reject at least some versions so `>=0` or +`-any` and `<0` or `-none` as version constraint will also fail the check.