Skip to content

Commit 125cd2d

Browse files
authored
Merge pull request #9720 from mpickering/wip/multi-repl-closure
Fix multi-repl closure computation with invalid Custom setup
2 parents 517ddc6 + f1c6bb4 commit 125cd2d

File tree

19 files changed

+182
-58
lines changed

19 files changed

+182
-58
lines changed

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

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3223,9 +3223,6 @@ setRootTargets targetAction perPkgTargetsMap =
32233223
| isSubLibComponentTarget tgt = elab{elabHaddockInternal = True}
32243224
| otherwise = elab
32253225

3226-
minVersionReplFlagFile :: Version
3227-
minVersionReplFlagFile = mkVersion [3, 9]
3228-
32293226
-- | Assuming we have previously set the root build targets (i.e. the user
32303227
-- targets but not rev deps yet), the first pruning pass does two things:
32313228
--
@@ -3240,7 +3237,7 @@ pruneInstallPlanPass1
32403237
pruneInstallPlanPass1 pkgs
32413238
-- if there are repl targets, we need to do a bit more work
32423239
-- See Note [Pruning for Multi Repl]
3243-
| anyReplTarget = final_final_graph
3240+
| anyMultiReplTarget = graph_with_repl_targets
32443241
-- otherwise we'll do less
32453242
| otherwise = pruned_packages
32463243
where
@@ -3264,10 +3261,11 @@ pruneInstallPlanPass1 pkgs
32643261
closed_graph :: Graph.Graph ElaboratedPlanPackage
32653262
closed_graph = Graph.fromDistinctList pruned_packages
32663263

3267-
-- whether any package has repl targets enabled.
3268-
anyReplTarget :: Bool
3269-
anyReplTarget = any is_repl_gpp pkgs'
3264+
-- whether any package has repl targets enabled, and we need to use multi-repl.
3265+
anyMultiReplTarget :: Bool
3266+
anyMultiReplTarget = length repls > 1
32703267
where
3268+
repls = filter is_repl_gpp pkgs'
32713269
is_repl_gpp (InstallPlan.Configured pkg) = is_repl_pp pkg
32723270
is_repl_gpp _ = False
32733271

@@ -3290,52 +3288,9 @@ pruneInstallPlanPass1 pkgs
32903288

32913289
-- Add the repl target information to the ElaboratedPlanPackages
32923290
graph_with_repl_targets
3293-
| anyReplTarget = map (mapConfiguredPackage add_repl_target) (Graph.toList closed_graph)
3291+
| anyMultiReplTarget = map (mapConfiguredPackage add_repl_target) (Graph.toList closed_graph)
32943292
| otherwise = Graph.toList closed_graph
32953293

3296-
-- But check that all the InMemory targets have a new enough version of Cabal,
3297-
-- otherwise we will confuse Setup.hs by passing new arguments which it doesn't understand
3298-
-- later down the line. We try to remove just these edges, if it doesn't break the overall structure
3299-
-- then we just report to the user that their target will not be loaded for this reason.
3300-
--
3301-
-- 'bad' are the nodes with a too old version of Cabal
3302-
-- 'good' are the nodes with a new-enough version of Cabal
3303-
(bad, _good) = partitionEithers (map go graph_with_repl_targets)
3304-
where
3305-
go :: ElaboratedPlanPackage -> Either UnitId ElaboratedPlanPackage
3306-
go (InstallPlan.Configured cp)
3307-
| BuildInplaceOnly InMemory <- elabBuildStyle cp
3308-
, elabSetupScriptCliVersion cp < minVersionReplFlagFile =
3309-
Left (elabUnitId cp)
3310-
go (InstallPlan.Configured c) = Right (InstallPlan.Configured c)
3311-
go c = Right c
3312-
3313-
-- Now take the upwards closure from the bad nodes, and find the other `BuildInplaceOnly InMemory` packages that clobbers,
3314-
-- disables those and issue a warning to the user. Because we aren't going to be able to load those into memory as well
3315-
-- because the thing it depends on is not going to be in memory.
3316-
disabled_repl_targets =
3317-
[ c | InstallPlan.Configured c <- fromMaybe [] $ Graph.revClosure (Graph.fromDistinctList graph_with_repl_targets) bad, BuildInplaceOnly InMemory <- [elabBuildStyle c]
3318-
]
3319-
3320-
remove_repl_target :: ElaboratedConfiguredPackage -> ElaboratedConfiguredPackage
3321-
remove_repl_target ecp
3322-
| ecp `elem` disabled_repl_targets =
3323-
ecp
3324-
{ elabReplTarget = []
3325-
, elabBuildStyle = BuildInplaceOnly OnDisk
3326-
}
3327-
| otherwise = ecp
3328-
3329-
final_graph_with_repl_targets = map (mapConfiguredPackage remove_repl_target) graph_with_repl_targets
3330-
3331-
-- Now find what the new roots are after we have disabled things which we can't build (and the things above that)
3332-
new_roots :: [UnitId]
3333-
new_roots = mapMaybe find_root (map (mapConfiguredPackage prune) final_graph_with_repl_targets)
3334-
3335-
-- Then take the final closure from these new roots to remove these things
3336-
-- TODO: Can probably just remove them directly in remove_repl_target.
3337-
final_final_graph = fromMaybe [] $ Graph.closure (Graph.fromDistinctList final_graph_with_repl_targets) new_roots
3338-
33393294
is_root :: PrunedPackage -> Maybe UnitId
33403295
is_root (PrunedPackage elab _) =
33413296
if not $
@@ -3462,13 +3417,6 @@ our roots (graph closure), and then from this closed graph, we calculate
34623417
the reverse closure, which gives us all components that depend on
34633418
'roots'. Thus, the result is a list of components that we need to load
34643419
into the repl to uphold the closure property.
3465-
3466-
Further to this, we then check that all the enabled components are using a new enough
3467-
version of Cabal which understands the repl option to write the arguments to a file.
3468-
3469-
If there is a package using a custom Setup.hs which is linked against a too old version
3470-
of Cabal then we need to disable that as otherwise we will end up passing unknown
3471-
arguments to `./Setup`.
34723420
-}
34733421

34743422
-- | Given a set of already installed packages @availablePkgs@,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# cabal v2-repl
2+
Resolving dependencies...
3+
Error: [Cabal-7107]
4+
Could not resolve dependencies:
5+
[__0] trying: pkg-b-0 (user goal)
6+
[__1] next goal: pkg-b:setup.Cabal (dependency of pkg-b)
7+
[__1] rejecting: pkg-b:setup.Cabal-<VERSION>/installed-<HASH> (constraint from --enable-multi-repl requires >=3.11)
8+
[__1] fail (backjumping, conflict set: pkg-b, pkg-b:setup.Cabal)
9+
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: pkg-b (2), pkg-b:setup.Cabal (2)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
packages: pkg-a/*.cabal
2+
packages: pkg-b/*.cabal
3+
packages: pkg-c/*.cabal
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Test.Cabal.Prelude
2+
3+
main = do
4+
cabalTest $ do
5+
-- MP: TODO: This should query Cabal library version
6+
skipIfGhcVersion ">= 9.10"
7+
-- Note: only the last package is interactive.
8+
-- this test should load pkg-b too.
9+
res <- fails $ cabalWithStdin "v2-repl" ["--enable-multi-repl","pkg-c", "pkg-a"] "Quu.quu"
10+
11+
assertOutputContains "constraint from --enable-multi-repl requires >=3.11" res
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Foo where
2+
3+
foo :: Int
4+
foo = 42
5+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cabal-version: 2.2
2+
name: pkg-a
3+
version: 0
4+
5+
library
6+
default-language: Haskell2010
7+
build-depends: base
8+
exposed-modules: Foo
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Bar where
2+
3+
import Foo
4+
5+
bar :: Int
6+
bar = foo + foo
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Setup where
2+
3+
import Distribution.Simple
4+
5+
main = defaultMain
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
cabal-version: 2.2
2+
name: pkg-b
3+
version: 0
4+
build-type: Custom
5+
6+
custom-setup
7+
setup-depends: Cabal <= 3.11
8+
9+
library
10+
default-language: Haskell2010
11+
build-depends: base, pkg-a
12+
exposed-modules: Bar
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Quu where
2+
3+
import Bar
4+
5+
quu :: Int
6+
quu = bar + bar

0 commit comments

Comments
 (0)