-
Notifications
You must be signed in to change notification settings - Fork 710
Refactor cabal-install solver config log output #10854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,34 +27,51 @@ import Distribution.Solver.Modular.ConfiguredConversion | |
( convCP ) | ||
import qualified Distribution.Solver.Modular.ConflictSet as CS | ||
import Distribution.Solver.Modular.Dependency | ||
import Distribution.Solver.Modular.Flag | ||
import Distribution.Solver.Modular.Index | ||
( Var(..), | ||
showVar, | ||
ConflictMap, | ||
ConflictSet, | ||
showConflictSet, | ||
RevDepMap ) | ||
import Distribution.Solver.Modular.Flag ( SN(SN), FN(FN) ) | ||
import Distribution.Solver.Modular.Index ( Index ) | ||
import Distribution.Solver.Modular.IndexConversion | ||
( convPIs ) | ||
import Distribution.Solver.Modular.Log | ||
( SolverFailure(..), displayLogMessages ) | ||
import Distribution.Solver.Modular.Package | ||
( PN ) | ||
import Distribution.Solver.Modular.RetryLog | ||
( RetryLog, | ||
toProgress, | ||
fromProgress, | ||
retry, | ||
failWith, | ||
continueWith ) | ||
import Distribution.Solver.Modular.Solver | ||
( SolverConfig(..), PruneAfterFirstSuccess(..), solve ) | ||
import Distribution.Solver.Types.DependencyResolver | ||
( DependencyResolver ) | ||
import Distribution.Solver.Types.LabeledPackageConstraint | ||
( LabeledPackageConstraint, unlabelPackageConstraint ) | ||
import Distribution.Solver.Types.PackageConstraint | ||
import Distribution.Solver.Types.PackagePath | ||
( PackageConstraint(..), scopeToPackageName ) | ||
import Distribution.Solver.Types.PackagePath ( QPN ) | ||
import Distribution.Solver.Types.PackagePreferences | ||
( PackagePreferences ) | ||
import Distribution.Solver.Types.PkgConfigDb | ||
( PkgConfigDb ) | ||
import Distribution.Solver.Types.Progress | ||
import Distribution.Solver.Types.Variable | ||
( Progress(..), foldProgress, SummarizedMessage(ErrorMsg) ) | ||
import Distribution.Solver.Types.Variable ( Variable(..) ) | ||
import Distribution.System | ||
( Platform(..) ) | ||
import Distribution.Simple.Setup | ||
( BooleanFlag(..) ) | ||
import Distribution.Simple.Utils | ||
( ordNubBy ) | ||
import Distribution.Verbosity | ||
|
||
( ordNubBy ) | ||
import Distribution.Verbosity ( normal, verbose ) | ||
import Distribution.Solver.Modular.Message ( renderSummarizedMessage ) | ||
|
||
-- | Ties the two worlds together: classic cabal-install vs. the modular | ||
-- solver. Performs the necessary translations before and after. | ||
|
@@ -120,25 +137,25 @@ solve' :: SolverConfig | |
-> (PN -> PackagePreferences) | ||
-> Map PN [LabeledPackageConstraint] | ||
-> Set PN | ||
-> Progress String String (Assignment, RevDepMap) | ||
-> Progress SummarizedMessage String (Assignment, RevDepMap) | ||
solve' sc cinfo idx pkgConfigDB pprefs gcs pns = | ||
toProgress $ retry (runSolver printFullLog sc) createErrorMsg | ||
where | ||
runSolver :: Bool -> SolverConfig | ||
-> RetryLog String SolverFailure (Assignment, RevDepMap) | ||
-> RetryLog SummarizedMessage SolverFailure (Assignment, RevDepMap) | ||
runSolver keepLog sc' = | ||
displayLogMessages keepLog $ | ||
solve sc' cinfo idx pkgConfigDB pprefs gcs pns | ||
|
||
createErrorMsg :: SolverFailure | ||
-> RetryLog String String (Assignment, RevDepMap) | ||
createErrorMsg failure@(ExhaustiveSearch cs cm) = | ||
-> RetryLog SummarizedMessage String (Assignment, RevDepMap) | ||
createErrorMsg failure@(ExhaustiveSearch cs _cm) = | ||
if asBool $ minimizeConflictSet sc | ||
then continueWith ("Found no solution after exhaustively searching the " | ||
then continueWith (mkErrorMsg ("Found no solution after exhaustively searching the " | ||
++ "dependency tree. Rerunning the dependency solver " | ||
++ "to minimize the conflict set ({" | ||
++ showConflictSet cs ++ "}).") $ | ||
retry (tryToMinimizeConflictSet (runSolver printFullLog) sc cs cm) $ | ||
++ showConflictSet cs ++ "}).")) $ | ||
retry (tryToMinimizeConflictSet (runSolver printFullLog) sc cs _cm) $ | ||
\case | ||
ExhaustiveSearch cs' cm' -> | ||
fromProgress $ Fail $ | ||
|
@@ -151,13 +168,13 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns = | |
++ "Original error message:\n" | ||
++ rerunSolverForErrorMsg cs | ||
++ finalErrorMsg sc failure | ||
else fromProgress $ Fail $ | ||
rerunSolverForErrorMsg cs ++ finalErrorMsg sc failure | ||
else | ||
fromProgress $ Fail $ rerunSolverForErrorMsg cs ++ finalErrorMsg sc failure | ||
createErrorMsg failure@BackjumpLimitReached = | ||
continueWith | ||
("Backjump limit reached. Rerunning dependency solver to generate " | ||
(mkErrorMsg ("Backjump limit reached. Rerunning dependency solver to generate " | ||
++ "a final conflict set for the search tree containing the " | ||
++ "first backjump.") $ | ||
++ "first backjump.")) $ | ||
retry (runSolver printFullLog sc { pruneAfterFirstSuccess = PruneAfterFirstSuccess True }) $ | ||
\case | ||
ExhaustiveSearch cs _ -> | ||
|
@@ -181,13 +198,16 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns = | |
-- original goal order. | ||
goalOrder' = preferGoalsFromConflictSet cs <> fromMaybe mempty (goalOrder sc) | ||
|
||
in unlines ("Could not resolve dependencies:" : messages (toProgress (runSolver True sc'))) | ||
in unlines ("Could not resolve dependencies:" : map renderSummarizedMessage (messages (toProgress (runSolver True sc')))) | ||
|
||
printFullLog = solverVerbosity sc >= verbose | ||
|
||
messages :: Progress step fail done -> [step] | ||
messages = foldProgress (:) (const []) (const []) | ||
|
||
mkErrorMsg :: String -> SummarizedMessage | ||
mkErrorMsg msg = ErrorMsg msg | ||
|
||
-- | Try to remove variables from the given conflict set to create a minimal | ||
-- conflict set. | ||
-- | ||
|
@@ -219,13 +239,13 @@ solve' sc cinfo idx pkgConfigDB pprefs gcs pns = | |
-- solver to add new unnecessary variables to the conflict set. This function | ||
-- discards the result from any run that adds new variables to the conflict | ||
-- set, but the end result may not be completely minimized. | ||
tryToMinimizeConflictSet :: forall a . (SolverConfig -> RetryLog String SolverFailure a) | ||
tryToMinimizeConflictSet :: forall a . (SolverConfig -> RetryLog SummarizedMessage SolverFailure a) | ||
-> SolverConfig | ||
-> ConflictSet | ||
-> ConflictMap | ||
-> RetryLog String SolverFailure a | ||
-> RetryLog SummarizedMessage SolverFailure a | ||
tryToMinimizeConflictSet runSolver sc cs cm = | ||
foldl (\r v -> retryNoSolution r $ tryToRemoveOneVar v) | ||
foldl (\r v -> retryMap mkErrorMsg $ retryNoSolution (retryMap renderSummarizedMessage r) $ tryToRemoveOneVar v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From #9159: Why does this line convert the |
||
(fromProgress $ Fail $ ExhaustiveSearch cs cm) | ||
(CS.toList cs) | ||
where | ||
|
@@ -258,7 +278,7 @@ tryToMinimizeConflictSet runSolver sc cs cm = | |
| otherwise = | ||
continueWith ("Trying to remove variable " ++ varStr ++ " from the " | ||
++ "conflict set.") $ | ||
retry (runSolver sc') $ \case | ||
retry (retryMap renderSummarizedMessage $ runSolver sc') $ \case | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From #9159: Why does this line call |
||
err@(ExhaustiveSearch cs' _) | ||
| CS.toSet cs' `isSubsetOf` CS.toSet smallestKnownCS -> | ||
let msg = if not $ CS.member v cs' | ||
|
@@ -297,6 +317,9 @@ tryToMinimizeConflictSet runSolver sc cs cm = | |
ExhaustiveSearch cs' cm' -> f cs' cm' | ||
BackjumpLimitReached -> fromProgress (Fail BackjumpLimitReached) | ||
|
||
retryMap :: (t -> step) -> RetryLog t fail done -> RetryLog step fail done | ||
retryMap f l = fromProgress $ (\p -> foldProgress (\x xs -> Step (f x) xs) Fail Done p) $ toProgress l | ||
Comment on lines
+320
to
+321
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From #9159: I think that it would be better to avoid creating a helper function that hides calls to |
||
|
||
-- | Goal ordering that chooses goals contained in the conflict set before | ||
-- other goals. | ||
preferGoalsFromConflictSet :: ConflictSet | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #9159: Why was
cm
renamed?