Skip to content

Commit 77df52d

Browse files
committed
Use batched ghc-pkg unregister implemented in GHC 8.0.1
1 parent 59efd85 commit 77df52d

3 files changed

Lines changed: 55 additions & 20 deletions

File tree

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ Other enhancements:
8787
[#4463](https://github.com/commercialhaskell/stack/issues/4463)
8888
* Add `--cabal-files` flag to `stack ide targets` command.
8989
* Add `--stdout` flag to all `stack ide` subcommands.
90+
* Use batches when unregistering packages with `ghc-pkg`.
91+
(See [#2662](https://github.com/commercialhaskell/stack/issues/2662))
9092

9193
Bug fixes:
9294

src/Stack/Build/Execute.hs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Data.Conduit.Process.Typed
4141
runProcess_, getStdout, getStderr, createSource)
4242
import qualified Data.Conduit.Text as CT
4343
import Data.List hiding (any)
44+
import Data.List.Split (chunksOf)
4445
import qualified Data.Map.Strict as M
4546
import qualified Data.Map.Strict as Map
4647
import qualified Data.Set as Set
@@ -584,14 +585,7 @@ executePlan' installedMap0 targets plan ee@ExecuteEnv {..} = do
584585
[] -> return ()
585586
ids -> do
586587
localDB <- packageDatabaseLocal
587-
forM_ ids $ \(id', (ident, reason)) -> do
588-
logInfo $
589-
fromString (packageIdentifierString ident) <>
590-
": unregistering" <>
591-
if T.null reason
592-
then ""
593-
else " (" <> RIO.display reason <> ")"
594-
unregisterGhcPkgId wc cv localDB id' ident
588+
unregisterPackages wc cv localDB ids
595589

596590
liftIO $ atomically $ modifyTVar' eeLocalDumpPkgs $ \initMap ->
597591
foldl' (flip Map.delete) initMap $ Map.keys (planUnregisterLocal plan)
@@ -661,6 +655,35 @@ executePlan' installedMap0 targets plan ee@ExecuteEnv {..} = do
661655
$ Map.elems
662656
$ planUnregisterLocal plan
663657

658+
unregisterPackages ::
659+
(HasProcessContext env, HasLogFunc env)
660+
=> WhichCompiler
661+
-> ActualCompiler
662+
-> Path Abs Dir
663+
-> [(GhcPkgId, (PackageIdentifier, Text))]
664+
-> RIO env ()
665+
unregisterPackages wc ac localDB ids = do
666+
let logReason ident reason =
667+
logInfo $
668+
fromString (packageIdentifierString ident) <> ": unregistering" <>
669+
if T.null reason
670+
then ""
671+
else " (" <> RIO.display reason <> ")"
672+
case ac of
673+
ACGhc v | v >= mkVersion [8, 0, 1] -> do
674+
let batchSize = 500
675+
for_ (chunksOf batchSize ids) $ \batch -> do
676+
for_ batch $ \(_, (ident, reason)) -> logReason ident reason
677+
unregisterGhcPkgIds wc localDB $ map fst batch
678+
ACGhc v | v >= mkVersion [7, 9] ->
679+
for_ ids $ \(gid, (ident, reason)) -> do
680+
logReason ident reason
681+
unregisterGhcPkgIds wc localDB [gid]
682+
_ -> do
683+
for_ ids $ \(_gid, (ident, reason)) -> do
684+
logReason ident reason
685+
unregisterSinglePackageId wc localDB ident
686+
664687
toActions :: HasEnvConfig env
665688
=> InstalledMap
666689
-> Maybe (MVar ())

src/Stack/GhcPkg.hs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ module Stack.GhcPkg
1010
(getGlobalDB
1111
,findGhcPkgField
1212
,createDatabase
13-
,unregisterGhcPkgId
13+
,unregisterSinglePackageId
14+
,unregisterGhcPkgIds
1415
,getCabalPkgVer
1516
,ghcPkgExeName
1617
,ghcPkgPathEnvVar
@@ -23,7 +24,6 @@ import qualified Data.ByteString.Lazy as BL
2324
import Data.List
2425
import qualified Data.Text as T
2526
import qualified Data.Text.Encoding as T
26-
import Distribution.Version (mkVersion)
2727
import Path (parent, (</>))
2828
import Path.Extra (toFilePathNoTrailingSep)
2929
import Path.IO
@@ -147,25 +147,35 @@ findGhcPkgVersion wc pkgDbs name = do
147147
Just !v -> return (parseVersion $ T.unpack v)
148148
_ -> return Nothing
149149

150-
unregisterGhcPkgId :: (HasProcessContext env, HasLogFunc env)
150+
unregisterSinglePackageId :: (HasProcessContext env, HasLogFunc env)
151+
=> WhichCompiler
152+
-> Path Abs Dir -- ^ package database
153+
-> PackageIdentifier
154+
-> RIO env ()
155+
unregisterSinglePackageId wc pkgDb ident = do
156+
eres <- ghcPkg wc [pkgDb] args
157+
case eres of
158+
Left e -> logWarn $ displayShow e
159+
Right _ -> return ()
160+
where
161+
args = "unregister" : "--user" : "--force" :
162+
[packageIdentifierString ident]
163+
164+
-- | unregister list of package ghcids, batching available from GHC 8.0.1,
165+
-- using GHC package id available from GHC 7.9(?)
166+
unregisterGhcPkgIds :: (HasProcessContext env, HasLogFunc env)
151167
=> WhichCompiler
152-
-> ActualCompiler
153168
-> Path Abs Dir -- ^ package database
154-
-> GhcPkgId
155-
-> PackageIdentifier
169+
-> [GhcPkgId]
156170
-> RIO env ()
157-
unregisterGhcPkgId wc cv pkgDb gid ident = do
171+
unregisterGhcPkgIds wc pkgDb gids = do
158172
eres <- ghcPkg wc [pkgDb] args
159173
case eres of
160174
Left e -> logWarn $ displayShow e
161175
Right _ -> return ()
162176
where
163-
-- TODO ideally we'd tell ghc-pkg a GhcPkgId instead
164177
args = "unregister" : "--user" : "--force" :
165-
(case cv of
166-
ACGhc v | v < mkVersion [7, 9] ->
167-
[packageIdentifierString ident]
168-
_ -> ["--ipid", ghcPkgIdString gid])
178+
concatMap (\gid -> ["--ipid", ghcPkgIdString gid]) gids
169179

170180
-- | Get the version of Cabal from the global package database.
171181
getCabalPkgVer :: (HasProcessContext env, HasLogFunc env)

0 commit comments

Comments
 (0)