@@ -74,12 +74,22 @@ data AddDepRes
7474 | ADRFound InstallLocation Version Installed
7575 deriving Show
7676
77+ data W = W
78+ { wFinals :: ! (Map PackageName (Either ConstructPlanException (Task , LocalPackageTB )))
79+ , wInstall :: ! (Map Text InstallLocation )
80+ -- ^ executable to be installed, and location where the binary is placed
81+ , wDirty :: ! (Map PackageName Text )
82+ -- ^ why a local package is considered dirty
83+ , wDeps :: ! (Set PackageName )
84+ -- ^ Packages which count as dependencies
85+ }
86+ instance Monoid W where
87+ mempty = W mempty mempty mempty mempty
88+ mappend (W a b c d) (W w x y z) = W (mappend a w) (mappend b x) (mappend c y) (mappend d z)
89+
7790type M = RWST
7891 Ctx
79- ( Map PackageName (Either ConstructPlanException Task ) -- finals
80- , Map Text InstallLocation -- executable to be installed, and location where the binary is placed
81- , Map PackageName Text -- why a local package is considered dirty
82- )
92+ W
8393 (Map PackageName (Either ConstructPlanException AddDepRes ))
8494 IO
8595
@@ -121,14 +131,25 @@ constructPlan mbp0 baseConfigOpts0 locals extraToBuild0 locallyRegistered loadPa
121131 let latest = Map. fromListWith max $ map toTuple $ Map. keys caches
122132
123133 econfig <- asks getEnvConfig
124- let onWanted =
125- case boptsFinalAction $ bcoBuildOpts baseConfigOpts0 of
126- DoNothing -> void . addDep . packageName . lpPackage
127- _ -> addFinal
134+ let onWanted lp = do
135+ {-
136+ - Arguably this is the right thing to do. However, forcing the
137+ - library to rebuild causes the cabal_macros.h file to change,
138+ - which makes GHC rebuild everything...
139+
140+ case lpExeComponents lp of
141+ Nothing -> return ()
142+ Just _ -> void $ addDep $ packageName $ lpPackage lp
143+ -}
144+
145+ case lpTestBench lp of
146+ Just tb -> addFinal lp tb
147+ -- See comment above
148+ Nothing -> void $ addDep False $ packageName $ lpPackage lp
128149 let inner = do
129150 mapM_ onWanted $ filter lpWanted locals
130- mapM_ addDep $ Set. toList extraToBuild0
131- (() , m, ( efinals, installExes, dirtyReason) ) <- liftIO $ runRWST inner (ctx econfig latest) M. empty
151+ mapM_ ( addDep False ) $ Set. toList extraToBuild0
152+ (() , m, W efinals installExes dirtyReason deps ) <- liftIO $ runRWST inner (ctx econfig latest) M. empty
132153 let toEither (_, Left e) = Left e
133154 toEither (k, Right v) = Right (k, v)
134155 (errlibs, adrs) = partitionEithers $ map toEither $ M. toList m
@@ -139,11 +160,12 @@ constructPlan mbp0 baseConfigOpts0 locals extraToBuild0 locallyRegistered loadPa
139160 let toTask (_, ADRFound _ _ _) = Nothing
140161 toTask (name, ADRToInstall task) = Just (name, task)
141162 tasks = M. fromList $ mapMaybe toTask adrs
142- maybeStripLocals
143- | boptsOnlySnapshot $ bcoBuildOpts baseConfigOpts0 =
144- stripLocals
145- | otherwise = id
146- return $ maybeStripLocals Plan
163+ takeSubset =
164+ case boptsBuildSubset $ bcoBuildOpts baseConfigOpts0 of
165+ BSAll -> id
166+ BSOnlySnapshot -> stripLocals
167+ BSOnlyDependencies -> stripNonDeps deps
168+ return $ takeSubset Plan
147169 { planTasks = tasks
148170 , planFinals = M. fromList finals
149171 , planUnregisterLocal = mkUnregisterLocal tasks dirtyReason locallyRegistered
@@ -192,14 +214,14 @@ mkUnregisterLocal tasks dirtyReason locallyRegistered =
192214 ident = ghcPkgIdPackageIdentifier gid
193215 name = packageIdentifierName ident
194216
195- addFinal :: LocalPackage -> M ()
196- addFinal lp = do
197- depsRes <- addPackageDeps package
217+ addFinal :: LocalPackage -> LocalPackageTB -> M ()
218+ addFinal lp lptb = do
219+ depsRes <- addPackageDeps False package
198220 res <- case depsRes of
199221 Left e -> return $ Left e
200222 Right (missing, present, _minLoc) -> do
201223 ctx <- ask
202- return $ Right Task
224+ return $ Right ( Task
203225 { taskProvides = PackageIdentifier
204226 (packageName package)
205227 (packageVersion package)
@@ -214,32 +236,38 @@ addFinal lp = do
214236 package
215237 , taskPresent = present
216238 , taskType = TTLocal lp
217- }
218- tell ( Map. singleton (packageName package) res, mempty , mempty )
239+ }, lptb)
240+ tell mempty { wFinals = Map. singleton (packageName package) res }
219241 where
220- package = lpPackageFinal lp
242+ package = lptbPackage lptb
221243
222- addDep :: PackageName -> M (Either ConstructPlanException AddDepRes )
223- addDep name = do
244+ addDep :: Bool -- ^ is this being used by a dependency?
245+ -> PackageName -> M (Either ConstructPlanException AddDepRes )
246+ addDep treatAsDep' name = do
247+ ctx <- ask
248+ let treatAsDep = treatAsDep' || name `Set.notMember` wanted ctx
249+ when treatAsDep $ markAsDep name
224250 m <- get
225251 case Map. lookup name m of
226252 Just res -> return res
227253 Nothing -> do
228- res <- addDep' name
254+ res <- addDep' treatAsDep name
229255 modify $ Map. insert name res
230256 return res
231257
232- addDep' :: PackageName -> M (Either ConstructPlanException AddDepRes )
233- addDep' name = do
258+ addDep' :: Bool -- ^ is this being used by a dependency?
259+ -> PackageName -> M (Either ConstructPlanException AddDepRes )
260+ addDep' treatAsDep name = do
234261 ctx <- ask
235262 if name `elem` callStack ctx
236263 then return $ Left $ DependencyCycleDetected $ name : callStack ctx
237264 else local
238265 (\ ctx' -> ctx' { callStack = name : callStack ctx' }) $ do
239- (addDep'' name)
266+ (addDep'' treatAsDep name)
240267
241- addDep'' :: PackageName -> M (Either ConstructPlanException AddDepRes )
242- addDep'' name = do
268+ addDep'' :: Bool -- ^ is this being used by a dependency?
269+ -> PackageName -> M (Either ConstructPlanException AddDepRes )
270+ addDep'' treatAsDep name = do
243271 ctx <- ask
244272 case Map. lookup name $ combinedMap ctx of
245273 -- TODO look up in the package index and see if there's a
@@ -250,12 +278,12 @@ addDep'' name = do
250278 return $ Right $ ADRFound loc version installed
251279 Just (PIOnlySource ps) -> do
252280 tellExecutables name ps
253- installPackage name ps
281+ installPackage treatAsDep name ps
254282 Just (PIBoth ps installed) -> do
255283 tellExecutables name ps
256- needInstall <- checkNeedInstall name ps installed (wanted ctx)
284+ needInstall <- checkNeedInstall treatAsDep name ps installed (wanted ctx)
257285 if needInstall
258- then installPackage name ps
286+ then installPackage treatAsDep name ps
259287 else return $ Right $ ADRFound (piiLocation ps) (piiVersion ps) installed
260288
261289tellExecutables :: PackageName -> PackageSource -> M () -- TODO merge this with addFinal above?
@@ -283,10 +311,10 @@ tellExecutablesPackage loc p = do
283311 Just (PIOnlySource ps) -> goSource ps
284312 Just (PIBoth ps _) -> goSource ps
285313
286- goSource (PSLocal lp) = lpComponents lp
314+ goSource (PSLocal lp) = fromMaybe Set. empty $ lpExeComponents lp
287315 goSource (PSUpstream _ _ _) = Set. empty
288316
289- tell ( Map. empty, m myComps, Map. empty)
317+ tell mempty { wInstall = m myComps }
290318 where
291319 m myComps = Map. fromList $ map (, loc) $ Set. toList
292320 $ filterComps myComps $ packageExes p
@@ -300,11 +328,12 @@ tellExecutablesPackage loc p = do
300328-- TODO There are a lot of duplicated computations below. I've kept that for
301329-- simplicity right now
302330
303- installPackage :: PackageName -> PackageSource -> M (Either ConstructPlanException AddDepRes )
304- installPackage name ps = do
331+ installPackage :: Bool -- ^ is this being used by a dependency?
332+ -> PackageName -> PackageSource -> M (Either ConstructPlanException AddDepRes )
333+ installPackage treatAsDep name ps = do
305334 ctx <- ask
306335 package <- psPackage name ps
307- depsRes <- addPackageDeps package
336+ depsRes <- addPackageDeps treatAsDep package
308337 case depsRes of
309338 Left e -> return $ Left e
310339 Right (missing, present, minLoc) -> do
@@ -331,29 +360,31 @@ installPackage name ps = do
331360 PSUpstream _ loc _ -> TTUpstream package $ loc <> minLoc
332361 }
333362
334- checkNeedInstall :: PackageName -> PackageSource -> Installed -> Set PackageName -> M Bool
335- checkNeedInstall name ps installed wanted = assert (piiLocation ps == Local ) $ do
363+ checkNeedInstall :: Bool
364+ -> PackageName -> PackageSource -> Installed -> Set PackageName -> M Bool
365+ checkNeedInstall treatAsDep name ps installed wanted = assert (piiLocation ps == Local ) $ do
336366 package <- psPackage name ps
337- depsRes <- addPackageDeps package
367+ depsRes <- addPackageDeps treatAsDep package
338368 case depsRes of
339369 Left _e -> return True -- installPackage will find the error again
340370 Right (missing, present, _loc)
341371 | Set. null missing -> checkDirtiness ps installed package present wanted
342372 | otherwise -> do
343- tell ( Map. empty, Map. empty, Map. singleton name $
373+ tell mempty { wDirty = Map. singleton name $
344374 let t = T. intercalate " , " $ map (T. pack . packageNameString . packageIdentifierName) (Set. toList missing)
345375 in T. append " missing dependencies: " $
346376 if T. length t < 100
347377 then t
348- else T. take 97 t <> " ..." )
378+ else T. take 97 t <> " ..." }
349379 return True
350380
351- addPackageDeps :: Package -> M (Either ConstructPlanException (Set PackageIdentifier , Set GhcPkgId , InstallLocation ))
352- addPackageDeps package = do
381+ addPackageDeps :: Bool -- ^ is this being used by a dependency?
382+ -> Package -> M (Either ConstructPlanException (Set PackageIdentifier , Set GhcPkgId , InstallLocation ))
383+ addPackageDeps treatAsDep package = do
353384 ctx <- ask
354385 deps' <- packageDepsWithTools package
355386 deps <- forM (Map. toList deps') $ \ (depname, range) -> do
356- eres <- addDep depname
387+ eres <- addDep treatAsDep depname
357388 let mlatest = Map. lookup depname $ latestVersions ctx
358389 case eres of
359390 Left e ->
@@ -403,7 +434,7 @@ checkDirtiness ps installed package present wanted = do
403434 , configCacheDeps = present
404435 , configCacheComponents =
405436 case ps of
406- PSLocal lp -> Set. map encodeUtf8 $ lpComponents lp
437+ PSLocal lp -> Set. map renderComponent $ lpComponents lp
407438 PSUpstream _ _ _ -> Set. empty
408439 , configCacheHaddock =
409440 shouldHaddockPackage buildOpts wanted (packageName package) ||
@@ -420,7 +451,7 @@ checkDirtiness ps installed package present wanted = do
420451 case mreason of
421452 Nothing -> return False
422453 Just reason -> do
423- tell ( Map. empty, Map. empty, Map. singleton (packageName package) reason)
454+ tell mempty { wDirty = Map. singleton (packageName package) reason }
424455 return True
425456
426457describeConfigDiff :: ConfigCache -> ConfigCache -> Text
@@ -493,3 +524,15 @@ stripLocals plan = plan
493524 TTLocal _ -> False
494525 TTUpstream _ Local -> False
495526 TTUpstream _ Snap -> True
527+
528+ stripNonDeps :: Set PackageName -> Plan -> Plan
529+ stripNonDeps deps plan = plan
530+ { planTasks = Map. filter checkTask $ planTasks plan
531+ , planFinals = Map. empty
532+ , planInstallExes = Map. empty -- TODO maybe don't disable this?
533+ }
534+ where
535+ checkTask task = packageIdentifierName (taskProvides task) `Set.member` deps
536+
537+ markAsDep :: PackageName -> M ()
538+ markAsDep name = tell mempty { wDeps = Set. singleton name }
0 commit comments