Skip to content

Commit c0c546f

Browse files
yvan-srakaerikd
andcommitted
Refactor cabal-install solver config log output
The main goal is to add an intermediate log message type to the processing of the solver log. Changes to the cabal solver's output are very minor. Includes: * Apply some of @grayjay and @mpickering comments * Fix #4251 Co-Authored-By: Erik de Castro Lopo <[email protected]>
1 parent 4ca7aeb commit c0c546f

File tree

10 files changed

+245
-130
lines changed

10 files changed

+245
-130
lines changed

cabal-install-solver/cabal-install-solver.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ library
9595
Distribution.Solver.Types.SolverId
9696
Distribution.Solver.Types.SolverPackage
9797
Distribution.Solver.Types.SourcePackage
98+
Distribution.Solver.Types.SummarizedMessage
9899
Distribution.Solver.Types.Variable
99100

100101
build-depends:

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

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,51 @@ import Distribution.Solver.Modular.ConfiguredConversion
2727
( 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
3339
( convPIs )
3440
import Distribution.Solver.Modular.Log
3541
( SolverFailure(..), displayLogMessages )
3642
import Distribution.Solver.Modular.Package
3743
( 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
4052
( 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
4763
( 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
5168
( Platform(..) )
5269
import Distribution.Simple.Setup
5370
( 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,21 +137,21 @@ 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)
151+
-> RetryLog SummarizedMessage String (Assignment, RevDepMap)
135152
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 ({"
140157
++ showConflictSet cs ++ "}).") $
@@ -155,7 +172,7 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
155172
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 "
160177
++ "first backjump.") $
161178
retry (runSolver printFullLog sc { pruneAfterFirstSuccess = PruneAfterFirstSuccess True }) $
@@ -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,11 +239,11 @@ 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 =
228248
foldl (\r v -> retryNoSolution r $ tryToRemoveOneVar v)
229249
(fromProgress $ Fail $ ExhaustiveSearch cs cm)
@@ -249,14 +269,14 @@ tryToMinimizeConflictSet runSolver sc cs cm =
249269
tryToRemoveOneVar :: Var QPN
250270
-> ConflictSet
251271
-> ConflictMap
252-
-> RetryLog String SolverFailure a
272+
-> RetryLog SummarizedMessage SolverFailure a
253273
tryToRemoveOneVar v smallestKnownCS smallestKnownCM
254274
-- Check whether v is still present, because it may have already been
255275
-- removed in a previous solver rerun.
256276
| not (v `CS.member` smallestKnownCS) =
257277
fromProgress $ Fail $ ExhaustiveSearch smallestKnownCS smallestKnownCM
258278
| otherwise =
259-
continueWith ("Trying to remove variable " ++ varStr ++ " from the "
279+
continueWith (mkErrorMsg $ "Trying to remove variable " ++ varStr ++ " from the "
260280
++ "conflict set.") $
261281
retry (runSolver sc') $ \case
262282
err@(ExhaustiveSearch cs' _)
@@ -268,14 +288,14 @@ tryToMinimizeConflictSet runSolver sc cs cm =
268288
++ "conflict set."
269289
in -- Use the new conflict set, even if v wasn't removed,
270290
-- because other variables may have been removed.
271-
failWith (msg ++ " Continuing with " ++ showCS cs' ++ ".") err
291+
failWith (mkErrorMsg $ msg ++ " Continuing with " ++ showCS cs' ++ ".") err
272292
| otherwise ->
273-
failWith ("Failed to find a smaller conflict set. The new "
293+
failWith (mkErrorMsg $ "Failed to find a smaller conflict set. The new "
274294
++ "conflict set is not a subset of the previous "
275295
++ "conflict set: " ++ showCS cs') $
276296
ExhaustiveSearch smallestKnownCS smallestKnownCM
277297
BackjumpLimitReached ->
278-
failWith "Reached backjump limit while minimizing conflict set."
298+
failWith (mkErrorMsg "Reached backjump limit while minimizing conflict set.")
279299
BackjumpLimitReached
280300
where
281301
varStr = "\"" ++ showVar v ++ "\""
@@ -290,9 +310,9 @@ tryToMinimizeConflictSet runSolver sc cs cm =
290310

291311
-- Like 'retry', except that it only applies the input function when the
292312
-- backjump limit has not been reached.
293-
retryNoSolution :: RetryLog step SolverFailure done
294-
-> (ConflictSet -> ConflictMap -> RetryLog step SolverFailure done)
295-
-> RetryLog step SolverFailure done
313+
retryNoSolution :: RetryLog SummarizedMessage SolverFailure done
314+
-> (ConflictSet -> ConflictMap -> RetryLog SummarizedMessage SolverFailure done)
315+
-> RetryLog SummarizedMessage SolverFailure done
296316
retryNoSolution lg f = retry lg $ \case
297317
ExhaustiveSearch cs' cm' -> f cs' cm'
298318
BackjumpLimitReached -> fromProgress (Fail BackjumpLimitReached)

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

Lines changed: 7 additions & 5 deletions
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 )
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 (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)