Skip to content

Commit 8896dc1

Browse files
committed
refactor(cabal-install, cabal-install-solver): avoid using "error" in validateSolverResult
- Add a `step` helper and a `MonadFail` instance to `Progress` - Refactor `validateSolverResult` to integrate into the `Progress` monad chain using `fail` instead of `error`, giving structured failure instead of an uncatchable exception
1 parent ec8052b commit 8896dc1

4 files changed

Lines changed: 57 additions & 52 deletions

File tree

.local/bin/cabal-validate

5.54 MB
Binary file not shown.

cabal-install-solver/src/Distribution/Solver/Types/Progress.hs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
{-# LANGUAGE FlexibleInstances #-}
12
module Distribution.Solver.Types.Progress
23
( Progress(..)
34
, foldProgress
5+
, step
46
) where
57

68
import Prelude ()
7-
import Distribution.Solver.Compat.Prelude hiding (fail)
9+
import Distribution.Solver.Compat.Prelude
810

911
-- | A type to represent the unfolding of an expensive long running
1012
-- calculation that may fail. We may get intermediate steps before the final
@@ -22,6 +24,9 @@ instance Functor (Progress step fail) where
2224
fmap _ (Fail x) = Fail x
2325
fmap f (Done r) = Done (f r)
2426

27+
step :: step -> Progress step fail ()
28+
step s = Step s (Done ())
29+
2530
-- | Consume a 'Progress' calculation. Much like 'foldr' for lists but with two
2631
-- base cases, one for a final result and one for failure.
2732
--
@@ -31,15 +36,18 @@ instance Functor (Progress step fail) where
3136
--
3237
foldProgress :: (step -> a -> a) -> (fail -> a) -> (done -> a)
3338
-> Progress step fail done -> a
34-
foldProgress step fail done = fold
35-
where fold (Step s p) = step s (fold p)
36-
fold (Fail f) = fail f
37-
fold (Done r) = done r
39+
foldProgress step' fail' done' = fold
40+
where fold (Step s p) = step' s (fold p)
41+
fold (Fail f) = fail' f
42+
fold (Done r) = done' r
3843

3944
instance Monad (Progress step fail) where
4045
return = pure
4146
p >>= f = foldProgress Step Fail f p
4247

48+
instance MonadFail (Progress step String) where
49+
fail = Fail
50+
4351
instance Applicative (Progress step fail) where
4452
pure a = Done a
4553
p <*> x = foldProgress Step Fail (`fmap` x) p

cabal-install/src/Distribution/Client/Dependency.hs

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
-----------------------------------------------------------------------------
2-
3-
-----------------------------------------------------------------------------
4-
51
-- |
62
-- Module : Distribution.Client.Dependency
73
-- Copyright : (c) David Himmelstrup 2005,
@@ -805,36 +801,37 @@ resolveDependencies
805801
-> Maybe PkgConfigDb
806802
-> DepResolverParams
807803
-> Progress String String SolverInstallPlan
808-
resolveDependencies platform comp pkgConfigDB params =
809-
Step (showDepResolverParams finalparams) $
810-
fmap (validateSolverResult platform comp indGoals) $
811-
formatProgress $
812-
runSolver
813-
( SolverConfig
814-
reordGoals
815-
cntConflicts
816-
fineGrained
817-
minimize
818-
indGoals
819-
noReinstalls
820-
shadowing
821-
strFlags
822-
onlyConstrained_
823-
maxBkjumps
824-
enableBj
825-
solveExes
826-
order
827-
verbosity
828-
(PruneAfterFirstSuccess False)
829-
)
830-
platform
831-
comp
832-
installedPkgIndex
833-
sourcePkgIndex
834-
pkgConfigDB
835-
preferences
836-
constraints
837-
targets
804+
resolveDependencies platform comp pkgConfigDB params = do
805+
step (showDepResolverParams finalparams)
806+
pkgs <-
807+
formatProgress $
808+
runSolver
809+
( SolverConfig
810+
reordGoals
811+
cntConflicts
812+
fineGrained
813+
minimize
814+
indGoals
815+
noReinstalls
816+
shadowing
817+
strFlags
818+
onlyConstrained_
819+
maxBkjumps
820+
enableBj
821+
solveExes
822+
order
823+
verbosity
824+
(PruneAfterFirstSuccess False)
825+
)
826+
platform
827+
comp
828+
installedPkgIndex
829+
sourcePkgIndex
830+
pkgConfigDB
831+
preferences
832+
constraints
833+
targets
834+
validateSolverResult platform comp indGoals pkgs
838835
where
839836
finalparams@( DepResolverParams
840837
targets
@@ -935,13 +932,13 @@ validateSolverResult
935932
-> CompilerInfo
936933
-> IndependentGoals
937934
-> [ResolverPackage UnresolvedPkgLoc]
938-
-> SolverInstallPlan
935+
-> Progress String String SolverInstallPlan
939936
validateSolverResult platform comp indepGoals pkgs =
940937
case planPackagesProblems platform comp pkgs of
941938
[] -> case SolverInstallPlan.new indepGoals graph of
942-
Right plan -> plan
943-
Left problems -> error (formatPlanProblems problems)
944-
problems -> error (formatPkgProblems problems)
939+
Right plan -> return plan
940+
Left problems -> fail (formatPlanProblems problems)
941+
problems -> fail (formatPkgProblems problems)
945942
where
946943
graph :: Graph.Graph (ResolverPackage UnresolvedPkgLoc)
947944
graph = Graph.fromDistinctList pkgs

cabal-install/tests/UnitTests/Distribution/Solver/Modular/RetryLog.hs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ tests =
3535
\p (Blind f) ->
3636
toProgress (retry (fromProgress p) (fromProgress . f))
3737
=== (foldProgress Step f Done (p :: Log Int) :: Log Int)
38-
, testProperty "failWith" $ \step failure ->
39-
toProgress (failWith step failure)
40-
=== (Step step (Fail failure) :: Log Int)
41-
, testProperty "succeedWith" $ \step success ->
42-
toProgress (succeedWith step success)
43-
=== (Step step (Done success) :: Log Int)
44-
, testProperty "continueWith" $ \step p ->
45-
toProgress (continueWith step (fromProgress p))
46-
=== (Step step p :: Log Int)
38+
, testProperty "failWith" $ \step' failure ->
39+
toProgress (failWith step' failure)
40+
=== (Step step' (Fail failure) :: Log Int)
41+
, testProperty "succeedWith" $ \step' success ->
42+
toProgress (succeedWith step' success)
43+
=== (Step step' (Done success) :: Log Int)
44+
, testProperty "continueWith" $ \step' p ->
45+
toProgress (continueWith step' (fromProgress p))
46+
=== (Step step' p :: Log Int)
4747
, testCase "tryWith with failure" $
4848
let failure = Fail "Error"
4949
s = Step Success

0 commit comments

Comments
 (0)