Skip to content

Commit 5a2528d

Browse files
yvan-srakaerikd
andcommitted
Refactor cabal-install solver config log output
Includes: * Apply some of @grayjay and @mpickering comments * Fix #4251 Co-Authored-By: Erik de Castro Lopo <[email protected]>
1 parent e38a514 commit 5a2528d

File tree

6 files changed

+379
-161
lines changed

6 files changed

+379
-161
lines changed

cabal-install-solver/src/Distribution/Solver/Modular.hs

+57-34
Original file line numberDiff line numberDiff line change
@@ -18,43 +18,60 @@ import Distribution.Solver.Compat.Prelude
1818
import qualified Data.Map as M
1919
import Data.Set (isSubsetOf)
2020
import Distribution.Compat.Graph
21-
( IsNode(..) )
21+
( IsNode(..) )
2222
import Distribution.Compiler
23-
( CompilerInfo )
23+
( CompilerInfo )
2424
import Distribution.Solver.Modular.Assignment
25-
( Assignment, toCPs )
25+
( Assignment, toCPs )
2626
import Distribution.Solver.Modular.ConfiguredConversion
27-
( convCP )
27+
( convCP )
2828
import qualified Distribution.Solver.Modular.ConflictSet as CS
2929
import Distribution.Solver.Modular.Dependency
30-
import Distribution.Solver.Modular.Flag
31-
import Distribution.Solver.Modular.Index
30+
( Var(..),
31+
showVar,
32+
ConflictMap,
33+
ConflictSet,
34+
showConflictSet,
35+
RevDepMap )
36+
import Distribution.Solver.Modular.Flag ( SN(SN), FN(FN) )
37+
import Distribution.Solver.Modular.Index ( Index )
3238
import Distribution.Solver.Modular.IndexConversion
33-
( convPIs )
39+
( convPIs )
3440
import Distribution.Solver.Modular.Log
35-
( SolverFailure(..), displayLogMessages )
41+
( SolverFailure(..), displayLogMessages )
3642
import Distribution.Solver.Modular.Package
37-
( PN )
43+
( PN )
3844
import Distribution.Solver.Modular.RetryLog
45+
( RetryLog,
46+
toProgress,
47+
fromProgress,
48+
retry,
49+
failWith,
50+
continueWith )
3951
import Distribution.Solver.Modular.Solver
40-
( SolverConfig(..), PruneAfterFirstSuccess(..), solve )
52+
( SolverConfig(..), PruneAfterFirstSuccess(..), solve )
4153
import Distribution.Solver.Types.DependencyResolver
54+
( DependencyResolver )
4255
import Distribution.Solver.Types.LabeledPackageConstraint
56+
( LabeledPackageConstraint, unlabelPackageConstraint )
4357
import Distribution.Solver.Types.PackageConstraint
44-
import Distribution.Solver.Types.PackagePath
58+
( PackageConstraint(..), scopeToPackageName )
59+
import Distribution.Solver.Types.PackagePath ( QPN )
4560
import Distribution.Solver.Types.PackagePreferences
61+
( PackagePreferences )
4662
import Distribution.Solver.Types.PkgConfigDb
47-
( PkgConfigDb )
63+
( PkgConfigDb )
4864
import Distribution.Solver.Types.Progress
49-
import Distribution.Solver.Types.Variable
65+
( Progress(..), foldProgress, SummarizedMessage(ErrorMsg) )
66+
import Distribution.Solver.Types.Variable ( Variable(..) )
5067
import Distribution.System
51-
( Platform(..) )
68+
( Platform(..) )
5269
import Distribution.Simple.Setup
53-
( BooleanFlag(..) )
70+
( BooleanFlag(..) )
5471
import Distribution.Simple.Utils
55-
( ordNubBy )
56-
import Distribution.Verbosity
57-
72+
( ordNubBy )
73+
import Distribution.Verbosity ( normal, verbose )
74+
import Distribution.Solver.Modular.Message ( renderSummarizedMessage )
5875

5976
-- | Ties the two worlds together: classic cabal-install vs. the modular
6077
-- solver. Performs the necessary translations before and after.
@@ -120,25 +137,25 @@ solve' :: SolverConfig
120137
-> (PN -> PackagePreferences)
121138
-> Map PN [LabeledPackageConstraint]
122139
-> Set PN
123-
-> Progress String String (Assignment, RevDepMap)
140+
-> Progress SummarizedMessage String (Assignment, RevDepMap)
124141
solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
125142
toProgress $ retry (runSolver printFullLog sc) createErrorMsg
126143
where
127144
runSolver :: Bool -> SolverConfig
128-
-> RetryLog String SolverFailure (Assignment, RevDepMap)
145+
-> RetryLog SummarizedMessage SolverFailure (Assignment, RevDepMap)
129146
runSolver keepLog sc' =
130147
displayLogMessages keepLog $
131148
solve sc' cinfo idx pkgConfigDB pprefs gcs pns
132149

133150
createErrorMsg :: SolverFailure
134-
-> RetryLog String String (Assignment, RevDepMap)
135-
createErrorMsg failure@(ExhaustiveSearch cs cm) =
151+
-> RetryLog SummarizedMessage String (Assignment, RevDepMap)
152+
createErrorMsg failure@(ExhaustiveSearch cs _cm) =
136153
if asBool $ minimizeConflictSet sc
137-
then continueWith ("Found no solution after exhaustively searching the "
154+
then continueWith (mkErrorMsg ("Found no solution after exhaustively searching the "
138155
++ "dependency tree. Rerunning the dependency solver "
139156
++ "to minimize the conflict set ({"
140-
++ showConflictSet cs ++ "}).") $
141-
retry (tryToMinimizeConflictSet (runSolver printFullLog) sc cs cm) $
157+
++ showConflictSet cs ++ "}).")) $
158+
retry (tryToMinimizeConflictSet (runSolver printFullLog) sc cs _cm) $
142159
\case
143160
ExhaustiveSearch cs' cm' ->
144161
fromProgress $ Fail $
@@ -151,13 +168,13 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
151168
++ "Original error message:\n"
152169
++ rerunSolverForErrorMsg cs
153170
++ finalErrorMsg sc failure
154-
else fromProgress $ Fail $
155-
rerunSolverForErrorMsg cs ++ finalErrorMsg sc failure
171+
else
172+
fromProgress $ Fail $ rerunSolverForErrorMsg cs ++ finalErrorMsg sc failure
156173
createErrorMsg failure@BackjumpLimitReached =
157174
continueWith
158-
("Backjump limit reached. Rerunning dependency solver to generate "
175+
(mkErrorMsg ("Backjump limit reached. Rerunning dependency solver to generate "
159176
++ "a final conflict set for the search tree containing the "
160-
++ "first backjump.") $
177+
++ "first backjump.")) $
161178
retry (runSolver printFullLog sc { pruneAfterFirstSuccess = PruneAfterFirstSuccess True }) $
162179
\case
163180
ExhaustiveSearch cs _ ->
@@ -181,13 +198,16 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
181198
-- original goal order.
182199
goalOrder' = preferGoalsFromConflictSet cs <> fromMaybe mempty (goalOrder sc)
183200

184-
in unlines ("Could not resolve dependencies:" : messages (toProgress (runSolver True sc')))
201+
in unlines ("Could not resolve dependencies:" : map renderSummarizedMessage (messages (toProgress (runSolver True sc'))))
185202

186203
printFullLog = solverVerbosity sc >= verbose
187204

188205
messages :: Progress step fail done -> [step]
189206
messages = foldProgress (:) (const []) (const [])
190207

208+
mkErrorMsg :: String -> SummarizedMessage
209+
mkErrorMsg msg = ErrorMsg msg
210+
191211
-- | Try to remove variables from the given conflict set to create a minimal
192212
-- conflict set.
193213
--
@@ -219,13 +239,13 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
219239
-- solver to add new unnecessary variables to the conflict set. This function
220240
-- discards the result from any run that adds new variables to the conflict
221241
-- set, but the end result may not be completely minimized.
222-
tryToMinimizeConflictSet :: forall a . (SolverConfig -> RetryLog String SolverFailure a)
242+
tryToMinimizeConflictSet :: forall a . (SolverConfig -> RetryLog SummarizedMessage SolverFailure a)
223243
-> SolverConfig
224244
-> ConflictSet
225245
-> ConflictMap
226-
-> RetryLog String SolverFailure a
246+
-> RetryLog SummarizedMessage SolverFailure a
227247
tryToMinimizeConflictSet runSolver sc cs cm =
228-
foldl (\r v -> retryNoSolution r $ tryToRemoveOneVar v)
248+
foldl (\r v -> retryMap mkErrorMsg $ retryNoSolution (retryMap renderSummarizedMessage r) $ tryToRemoveOneVar v)
229249
(fromProgress $ Fail $ ExhaustiveSearch cs cm)
230250
(CS.toList cs)
231251
where
@@ -258,7 +278,7 @@ tryToMinimizeConflictSet runSolver sc cs cm =
258278
| otherwise =
259279
continueWith ("Trying to remove variable " ++ varStr ++ " from the "
260280
++ "conflict set.") $
261-
retry (runSolver sc') $ \case
281+
retry (retryMap renderSummarizedMessage $ runSolver sc') $ \case
262282
err@(ExhaustiveSearch cs' _)
263283
| CS.toSet cs' `isSubsetOf` CS.toSet smallestKnownCS ->
264284
let msg = if not $ CS.member v cs'
@@ -297,6 +317,9 @@ tryToMinimizeConflictSet runSolver sc cs cm =
297317
ExhaustiveSearch cs' cm' -> f cs' cm'
298318
BackjumpLimitReached -> fromProgress (Fail BackjumpLimitReached)
299319

320+
retryMap :: (t -> step) -> RetryLog t fail done -> RetryLog step fail done
321+
retryMap f l = fromProgress $ (\p -> foldProgress (\x xs -> Step (f x) xs) Fail Done p) $ toProgress l
322+
300323
-- | Goal ordering that chooses goals contained in the conflict set before
301324
-- other goals.
302325
preferGoalsFromConflictSet :: ConflictSet

cabal-install-solver/src/Distribution/Solver/Modular/Log.hs

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import Prelude ()
77
import Distribution.Solver.Compat.Prelude
88

99
import Distribution.Solver.Types.Progress
10-
11-
import Distribution.Solver.Modular.Dependency
12-
import Distribution.Solver.Modular.Message
10+
( Progress(Done, Fail), foldProgress, SummarizedMessage, Message )
11+
import Distribution.Solver.Modular.ConflictSet
12+
( ConflictMap, ConflictSet )
1313
import Distribution.Solver.Modular.RetryLog
14+
( RetryLog, toProgress, fromProgress )
15+
import Distribution.Solver.Modular.Message (summarizeMessages)
1416

1517
-- | Information about a dependency solver failure.
1618
data SolverFailure =
@@ -22,10 +24,10 @@ data SolverFailure =
2224
-- 'keepLog'), for efficiency.
2325
displayLogMessages :: Bool
2426
-> RetryLog Message SolverFailure a
25-
-> RetryLog String SolverFailure a
27+
-> RetryLog SummarizedMessage SolverFailure a
2628
displayLogMessages keepLog lg = fromProgress $
2729
if keepLog
28-
then showMessages progress
30+
then summarizeMessages progress
2931
else foldProgress (const id) Fail Done progress
3032
where
3133
progress = toProgress lg

0 commit comments

Comments
 (0)