Commit 512d74ad authored by Mikhail Glushenkov's avatar Mikhail Glushenkov Committed by GitHub
Browse files

Merge pull request #4481 from grayjay/enable-independent-goals

Uncomment --independent-goals flag.
parents 3e17abec c0e43bc8
......@@ -211,7 +211,7 @@ resolveSolverSettings ProjectConfig{
solverSettingStrongFlags = fromFlag projectConfigStrongFlags
solverSettingAllowBootLibInstalls = fromFlag projectConfigAllowBootLibInstalls
solverSettingIndexState = flagToMaybe projectConfigIndexState
--solverSettingIndependentGoals = fromFlag projectConfigIndependentGoals
solverSettingIndependentGoals = fromFlag projectConfigIndependentGoals
--solverSettingShadowPkgs = fromFlag projectConfigShadowPkgs
--solverSettingReinstall = fromFlag projectConfigReinstall
--solverSettingAvoidReinstalls = fromFlag projectConfigAvoidReinstalls
......@@ -228,8 +228,8 @@ resolveSolverSettings ProjectConfig{
projectConfigReorderGoals = Flag (ReorderGoals False),
projectConfigCountConflicts = Flag (CountConflicts True),
projectConfigStrongFlags = Flag (StrongFlags False),
projectConfigAllowBootLibInstalls = Flag (AllowBootLibInstalls False)
--projectConfigIndependentGoals = Flag (IndependentGoals False),
projectConfigAllowBootLibInstalls = Flag (AllowBootLibInstalls False),
projectConfigIndependentGoals = Flag (IndependentGoals False)
--projectConfigShadowPkgs = Flag False,
--projectConfigReinstall = Flag False,
--projectConfigAvoidReinstalls = Flag False,
......
......@@ -305,7 +305,7 @@ convertLegacyAllPackageFlags globalFlags configFlags
installReorderGoals = projectConfigReorderGoals,
installCountConflicts = projectConfigCountConflicts,
installPerComponent = projectConfigPerComponent,
--installIndependentGoals = projectConfigIndependentGoals,
installIndependentGoals = projectConfigIndependentGoals,
--installShadowPkgs = projectConfigShadowPkgs,
installStrongFlags = projectConfigStrongFlags,
installAllowBootLibInstalls = projectConfigAllowBootLibInstalls
......@@ -503,7 +503,7 @@ convertToLegacySharedConfig
installUpgradeDeps = mempty, --projectConfigUpgradeDeps,
installReorderGoals = projectConfigReorderGoals,
installCountConflicts = projectConfigCountConflicts,
installIndependentGoals = mempty, --projectConfigIndependentGoals,
installIndependentGoals = projectConfigIndependentGoals,
installShadowPkgs = mempty, --projectConfigShadowPkgs,
installStrongFlags = projectConfigStrongFlags,
installAllowBootLibInstalls = projectConfigAllowBootLibInstalls,
......@@ -859,8 +859,8 @@ legacySharedConfigFieldDescrs =
, "remote-build-reporting", "report-planning-failure"
, "one-shot", "jobs", "keep-going", "offline", "per-component"
-- solver flags:
, "max-backjumps", "reorder-goals", "count-conflicts", "strong-flags"
, "allow-boot-library-installs", "index-state"
, "max-backjumps", "reorder-goals", "count-conflicts", "independent-goals"
, "strong-flags" , "allow-boot-library-installs", "index-state"
]
. commandOptionsToFields
) (installOptions ParseArgs)
......
......@@ -185,11 +185,11 @@ data ProjectConfigShared
projectConfigCountConflicts :: Flag CountConflicts,
projectConfigStrongFlags :: Flag StrongFlags,
projectConfigAllowBootLibInstalls :: Flag AllowBootLibInstalls,
projectConfigPerComponent :: Flag Bool
projectConfigPerComponent :: Flag Bool,
projectConfigIndependentGoals :: Flag IndependentGoals
-- More things that only make sense for manual mode, not --local mode
-- too much control!
--projectConfigIndependentGoals :: Flag IndependentGoals,
--projectConfigShadowPkgs :: Flag Bool,
--projectConfigReinstall :: Flag Bool,
--projectConfigAvoidReinstalls :: Flag Bool,
......@@ -360,10 +360,10 @@ data SolverSettings
solverSettingCountConflicts :: CountConflicts,
solverSettingStrongFlags :: StrongFlags,
solverSettingAllowBootLibInstalls :: AllowBootLibInstalls,
solverSettingIndexState :: Maybe IndexState
solverSettingIndexState :: Maybe IndexState,
solverSettingIndependentGoals :: IndependentGoals
-- Things that only make sense for manual mode, not --local mode
-- too much control!
--solverSettingIndependentGoals :: IndependentGoals,
--solverSettingShadowPkgs :: Bool,
--solverSettingReinstall :: Bool,
--solverSettingAvoidReinstalls :: Bool,
......
......@@ -898,8 +898,7 @@ planPackages verbosity comp platform solver SolverSettings{..}
setMaxBackjumps solverSettingMaxBackjumps
--TODO: [required eventually] should only be configurable for custom installs
-- . setIndependentGoals solverSettingIndependentGoals
. setIndependentGoals solverSettingIndependentGoals
. setReorderGoals solverSettingReorderGoals
......
......@@ -2415,7 +2415,7 @@ optionSolverFlags :: ShowOrParseArgs
-> (flags -> Flag StrongFlags) -> (Flag StrongFlags -> flags -> flags)
-> (flags -> Flag AllowBootLibInstalls) -> (Flag AllowBootLibInstalls -> flags -> flags)
-> [OptionField flags]
optionSolverFlags showOrParseArgs getmbj setmbj getrg setrg getcc setcc _getig _setig
optionSolverFlags showOrParseArgs getmbj setmbj getrg setrg getcc setcc getig setig
getsip setsip getstrfl setstrfl getib setib =
[ option [] ["max-backjumps"]
("Maximum number of backjumps allowed while solving (default: " ++ show defaultMaxBackjumps ++ "). Use a negative number to enable unlimited backtracking. Use 0 to disable backtracking completely.")
......@@ -2432,14 +2432,11 @@ optionSolverFlags showOrParseArgs getmbj setmbj getrg setrg getcc setcc _getig _
(fmap asBool . getcc)
(setcc . fmap CountConflicts)
(yesNoOpt showOrParseArgs)
-- TODO: Disabled for now because it may not be necessary
{-
, option [] ["independent-goals"]
"Treat several goals on the command line as independent. If several goals depend on the same package, different versions can be chosen."
(fmap asBool . getig)
(setig . fmap IndependentGoals)
(yesNoOpt showOrParseArgs)
-}
, option [] ["shadow-installed-packages"]
"If multiple package instances of the same version are installed, treat all but one as shadowed."
(fmap asBool . getsip)
......
......@@ -215,7 +215,7 @@ pkgSpecifierConstraints (SpecificSourcePackage pkg) =
[LabeledPackageConstraint pc ConstraintSourceUserTarget]
where
pc = PackageConstraint
(scopeToplevel $ packageName pkg)
(ScopeTarget $ packageName pkg)
(PackagePropertyVersion $ thisVersion (packageVersion pkg))
-- ------------------------------------------------------------
......
......@@ -260,7 +260,7 @@ buildTree idx (IndependentGoals ind) igs =
where
topLevelGoal qpn = PkgGoal qpn UserGoal
qpns | ind = makeIndependent igs
qpns | ind = L.map makeIndependent igs
| otherwise = L.map (Q (PackagePath DefaultNamespace QualToplevel)) igs
{-------------------------------------------------------------------------------
......
......@@ -101,9 +101,7 @@ setupPP :: PackagePath -> Bool
setupPP (PackagePath _ns (QualSetup _)) = True
setupPP (PackagePath _ns _) = False
-- | Create artificial parents for each of the package names, making
-- them all independent.
makeIndependent :: [PN] -> [QPN]
makeIndependent ps = [ Q pp pn | (pn, i) <- zip ps [0::Int ..]
, let pp = PackagePath (Independent i) QualToplevel
]
-- | Qualify a target package with its own name so that its dependencies are not
-- required to be consistent with other targets.
makeIndependent :: PN -> QPN
makeIndependent pn = Q (PackagePath (Independent pn) QualToplevel) pn
......@@ -37,8 +37,18 @@ import qualified Text.PrettyPrint as Disp
-- | Determines to what packages and in what contexts a
-- constraint applies.
data ConstraintScope
-- | A scope that applies when the given package is used as a build target.
-- In other words, the scope applies iff a goal has a top-level qualifier
-- and its namespace matches the given package name. A namespace is
-- considered to match a package name when it is either the default
-- namespace (for --no-independent-goals) or it is an independent namespace
-- with the given package name (for --independent-goals).
-- TODO: Try to generalize the ConstraintScopes once component-based
-- solving is implemented, and remove this special case for targets.
= ScopeTarget PackageName
-- | The package with the specified name and qualifier.
= ScopeQualified Qualifier PackageName
| ScopeQualified Qualifier PackageName
-- | The package with the specified name when it has a
-- setup qualifier.
| ScopeAnySetupQualifier PackageName
......@@ -55,11 +65,16 @@ scopeToplevel = ScopeQualified QualToplevel
-- | Returns the package name associated with a constraint scope.
scopeToPackageName :: ConstraintScope -> PackageName
scopeToPackageName (ScopeTarget pn) = pn
scopeToPackageName (ScopeQualified _ pn) = pn
scopeToPackageName (ScopeAnySetupQualifier pn) = pn
scopeToPackageName (ScopeAnyQualifier pn) = pn
constraintScopeMatches :: ConstraintScope -> QPN -> Bool
constraintScopeMatches (ScopeTarget pn) (Q (PackagePath ns q) pn') =
let namespaceMatches DefaultNamespace = True
namespaceMatches (Independent namespacePn) = pn == namespacePn
in namespaceMatches ns && q == QualToplevel && pn == pn'
constraintScopeMatches (ScopeQualified q pn) (Q (PackagePath _ q') pn') =
q == q' && pn == pn'
constraintScopeMatches (ScopeAnySetupQualifier pn) (Q pp pn') =
......@@ -70,6 +85,7 @@ constraintScopeMatches (ScopeAnyQualifier pn) (Q _ pn') = pn == pn'
-- | Pretty-prints a constraint scope.
dispConstraintScope :: ConstraintScope -> Disp.Doc
dispConstraintScope (ScopeTarget pn) = disp pn <<>> Disp.text "." <<>> disp pn
dispConstraintScope (ScopeQualified q pn) = dispQualifier q <<>> disp pn
dispConstraintScope (ScopeAnySetupQualifier pn) = Disp.text "setup." <<>> disp pn
dispConstraintScope (ScopeAnyQualifier pn) = Disp.text "any." <<>> disp pn
......
......@@ -27,17 +27,15 @@ data Namespace =
-- | The default namespace
DefaultNamespace
-- | Independent namespace
--
-- For now we just number these (rather than giving them more structure).
| Independent Int
-- | A namespace for a specific build target
| Independent PackageName
deriving (Eq, Ord, Show)
-- | Pretty-prints a namespace. The result is either empty or
-- ends in a period, so it can be prepended onto a qualifier.
dispNamespace :: Namespace -> Disp.Doc
dispNamespace DefaultNamespace = Disp.empty
dispNamespace (Independent i) = Disp.int i <<>> Disp.text "."
dispNamespace (Independent i) = disp i <<>> Disp.text "."
-- | Qualifier of a package within a namespace (see 'PackagePath')
data Qualifier =
......
......@@ -357,6 +357,7 @@ instance Arbitrary ProjectConfigShared where
<*> arbitrary <*> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
where
arbitraryConstraints :: Gen [(UserConstraint, ConstraintSource)]
arbitraryConstraints =
......@@ -367,22 +368,22 @@ instance Arbitrary ProjectConfigShared where
x05 x06 x07 x08 x09
x10 x11 x12 x13 x14
x15 x16 x17 x18 x19
x20) =
x20 x21) =
[ ProjectConfigShared
x00' x01' x02' (fmap getNonEmpty x03') (fmap getNonEmpty x04')
x05' x06' x07' x08' (postShrink_Constraints x09')
x10' x11' x12' x13' x14' x15' x16' x17' x18' x19' x20'
x10' x11' x12' x13' x14' x15' x16' x17' x18' x19' x20' x21'
| ((x00', x01', x02', x03', x04'),
(x05', x06', x07', x08', x09'),
(x10', x11', x12', x13', x14'),
(x15', x16', x17', x18', x19'),
x20')
x20', x21')
<- shrink
((x00, x01, x02, fmap NonEmpty x03, fmap NonEmpty x04),
(x05, x06, x07, x08, preShrink_Constraints x09),
(x10, x11, x12, x13, x14),
(x15, x16, x17, x18, x19),
x20)
x20, x21)
]
where
preShrink_Constraints = map fst
......@@ -615,6 +616,9 @@ instance Arbitrary ReorderGoals where
instance Arbitrary CountConflicts where
arbitrary = CountConflicts <$> arbitrary
instance Arbitrary IndependentGoals where
arbitrary = IndependentGoals <$> arbitrary
instance Arbitrary StrongFlags where
arbitrary = StrongFlags <$> arbitrary
......
......@@ -209,9 +209,12 @@ data ExampleVar =
data ExampleQualifier =
None
| Indep Int
| Indep ExamplePkgName
| Setup ExamplePkgName
| IndepSetup Int ExamplePkgName
-- The two package names are the build target and the package containing the
-- setup script.
| IndepSetup ExamplePkgName ExamplePkgName
-- | Whether to enable tests in all packages in a test case.
newtype EnableAllTests = EnableAllTests Bool
......@@ -658,9 +661,12 @@ exResolve db exts langs pkgConfigDb targets solver mbj indepGoals reorder
where
pp = case q of
None -> P.PackagePath P.DefaultNamespace P.QualToplevel
Indep x -> P.PackagePath (P.Independent x) P.QualToplevel
Setup p -> P.PackagePath P.DefaultNamespace (P.QualSetup (C.mkPackageName p))
IndepSetup x p -> P.PackagePath (P.Independent x) (P.QualSetup (C.mkPackageName p))
Indep p -> P.PackagePath (P.Independent $ C.mkPackageName p)
P.QualToplevel
Setup s -> P.PackagePath P.DefaultNamespace
(P.QualSetup (C.mkPackageName s))
IndepSetup p s -> P.PackagePath (P.Independent $ C.mkPackageName p)
(P.QualSetup (C.mkPackageName s))
extractInstallPlan :: CI.SolverInstallPlan.SolverInstallPlan
-> [(ExamplePkgName, ExamplePkgVersion)]
......
......@@ -752,14 +752,14 @@ testIndepGoals2 name =
goals :: [ExampleVar]
goals = [
P (Indep 0) "A"
, P (Indep 0) "C"
, P (Indep 0) "D"
, P (Indep 1) "B"
, P (Indep 1) "C"
, P (Indep 1) "D"
, S (Indep 1) "B" TestStanzas
, S (Indep 0) "A" TestStanzas
P (Indep "A") "A"
, P (Indep "A") "C"
, P (Indep "A") "D"
, P (Indep "B") "B"
, P (Indep "B") "C"
, P (Indep "B") "D"
, S (Indep "B") "B" TestStanzas
, S (Indep "A") "A" TestStanzas
]
-- | Issue #2834
......@@ -836,16 +836,16 @@ testIndepGoals3 name =
goals :: [ExampleVar]
goals = [
P (Indep 0) "D"
, P (Indep 0) "C"
, P (Indep 0) "A"
, P (Indep 1) "E"
, P (Indep 1) "C"
, P (Indep 1) "B"
, P (Indep 2) "F"
, P (Indep 2) "B"
, P (Indep 2) "C"
, P (Indep 2) "A"
P (Indep "D") "D"
, P (Indep "D") "C"
, P (Indep "D") "A"
, P (Indep "E") "E"
, P (Indep "E") "C"
, P (Indep "E") "B"
, P (Indep "F") "F"
, P (Indep "F") "B"
, P (Indep "F") "C"
, P (Indep "F") "A"
]
-- | This test checks that the solver correctly backjumps when dependencies
......@@ -878,15 +878,15 @@ testIndepGoals4 name =
goals :: [ExampleVar]
goals = [
P (Indep 0) "A"
, P (Indep 0) "E"
, P (Indep 1) "B"
, P (Indep 1) "D"
, P (Indep 1) "E"
, P (Indep 2) "C"
, P (Indep 2) "D"
, P (Indep 2) "E"
, S (Indep 2) "C" TestStanzas
P (Indep "A") "A"
, P (Indep "A") "E"
, P (Indep "B") "B"
, P (Indep "B") "D"
, P (Indep "B") "E"
, P (Indep "C") "C"
, P (Indep "C") "D"
, P (Indep "C") "E"
, S (Indep "C") "C" TestStanzas
]
-- | Test the trace messages that we get when a package refers to an unknown pkg
......@@ -955,14 +955,14 @@ testIndepGoals5 name fixGoalOrder =
goals :: [ExampleVar]
goals = [
P (Indep 0) "X"
, P (Indep 0) "A"
, P (Indep 0) "B"
, P (Indep 0) "C"
, P (Indep 1) "Y"
, P (Indep 1) "A"
, P (Indep 1) "B"
, P (Indep 1) "C"
P (Indep "X") "X"
, P (Indep "X") "A"
, P (Indep "X") "B"
, P (Indep "X") "C"
, P (Indep "Y") "Y"
, P (Indep "Y") "A"
, P (Indep "Y") "B"
, P (Indep "Y") "C"
]
-- | A simplified version of 'testIndepGoals5'.
......@@ -989,12 +989,12 @@ testIndepGoals6 name fixGoalOrder =
goals :: [ExampleVar]
goals = [
P (Indep 0) "X"
, P (Indep 0) "A"
, P (Indep 0) "B"
, P (Indep 1) "Y"
, P (Indep 1) "A"
, P (Indep 1) "B"
P (Indep "X") "X"
, P (Indep "X") "A"
, P (Indep "X") "B"
, P (Indep "Y") "Y"
, P (Indep "Y") "A"
, P (Indep "Y") "B"
]
dbExts1 :: ExampleDb
......
name: pkg
version: 1.0
build-type: Custom
cabal-version: >= 1.24
custom-setup
setup-depends: setup-dep == 2.*
library
build-depends: setup-dep == 1.*
name: setup-dep
version: 1.0
build-type: Simple
cabal-version: >= 1.2
library
name: setup-dep
version: 2.0
build-type: Simple
cabal-version: >= 1.2
library
# cabal update
Downloading the latest package list from test-local-repo
# cabal new-build
Resolving dependencies...
cabal: Could not resolve dependencies:
trying: pkg-1.0 (user goal)
next goal: setup-dep (user goal)
rejecting: setup-dep-2.0 (conflict: pkg => setup-dep==1.*)
rejecting: setup-dep-1.0 (constraint from user target requires ==2.0)
fail (backjumping, conflict set: pkg, setup-dep)
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: setup-dep (3), pkg (2)
# cabal new-build
Resolving dependencies...
In order, the following would be built:
- setup-dep-1.0 (lib:setup-dep) (requires download & build)
- setup-dep-2.0 (first run)
- pkg-1.0 (lib:pkg) (first run)
import Test.Cabal.Prelude
-- This test case is a simplified version of #4295. There is a local package,
-- pkg-1.0, which has a setup dependency on setup-dep==2.*. The repo contains
-- setup-dep-1.0, and the project contains the newer version, setup-dep-2.0.
-- pkg-1.0 also has a non-setup dependency on setup-dep==1.*.
--
-- The solution to the dependency problem must use the local setup-dep only as a
-- setup dependency for pkg. This means that setup-dep cannot use the same
-- qualifier as pkg, even though they are both build targets of the project.
-- The solution must use --independent-goals to give pkg and setup-dep different
-- qualifiers.
main = cabalTest $ withRepo "repo" $ do
fails $ cabal "new-build" ["pkg", "--dry-run"]
cabal "new-build" ["pkg", "--dry-run", "--independent-goals"]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment