Skip to content

Commit bcbfb1e

Browse files
authored
Merge pull request #4138 from commercialhaskell/ghci-ask-target-before-build
'stack ghci' now asks which main module to load before building
2 parents 93de6a9 + e18043e commit bcbfb1e

File tree

2 files changed

+83
-33
lines changed

2 files changed

+83
-33
lines changed

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ Other enhancements:
7272
* [#3685](https://github.com/commercialhaskell/stack/issues/3685)
7373
Suggestion to add `'allow-newer': true` now shows path to user config
7474
file where this flag should be put into
75+
* `stack ghci` now asks which main target to load before doing the build,
76+
rather than after
7577

7678
Bug fixes:
7779

src/Stack/Ghci.hs

Lines changed: 81 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ data GhciPkgInfo = GhciPkgInfo
8787
, ghciPkgPackage :: !Package
8888
} deriving Show
8989

90+
-- | Loaded package description and related info.
91+
data GhciPkgDesc = GhciPkgDesc
92+
{ ghciDescPkg :: !Package
93+
, ghciDescCabalFp :: !(Path Abs File)
94+
, ghciDescTarget :: !Target
95+
}
96+
9097
-- Mapping from a module name to a map with all of the paths that use
9198
-- that name. Each of those paths is associated with a set of components
9299
-- that contain it. Purpose of this complex structure is for use in
@@ -154,15 +161,31 @@ ghci opts@GhciOpts{..} = do
154161
nonLocalTargets <- getAllNonLocalTargets inputTargets
155162
-- Check if additional package arguments are sensible.
156163
addPkgs <- checkAdditionalPackages ghciAdditionalPackages
164+
-- Load package descriptions.
165+
pkgDescs <- loadGhciPkgDescs buildOptsCLI localTargets
166+
-- If necessary, ask user about which main module to load.
167+
bopts <- view buildOptsL
168+
mainFile <-
169+
if ghciNoLoadModules
170+
then return Nothing
171+
else do
172+
-- Figure out package files, in order to ask the user
173+
-- about which main module to load. See the note below for
174+
-- why this is done again after the build. This could
175+
-- potentially be done more efficiently, because all we
176+
-- need is the location of main modules, not the rest.
177+
pkgs0 <- getGhciPkgInfos sourceMap addPkgs (fmap fst mfileTargets) pkgDescs
178+
figureOutMainFile bopts mainIsTargets localTargets pkgs0
157179
-- Build required dependencies and setup local packages.
158180
stackYaml <- view stackYamlL
159181
buildDepsAndInitialSteps opts (map (packageNameText . fst) localTargets)
160182
targetWarnings stackYaml localTargets nonLocalTargets mfileTargets
161-
-- Load the list of modules _after_ building, to catch changes in unlisted dependencies (#1180)
162-
pkgs <- getGhciPkgInfos buildOptsCLI sourceMap addPkgs (fmap fst mfileTargets) localTargets
183+
-- Load the list of modules _after_ building, to catch changes in
184+
-- unlisted dependencies (#1180)
185+
pkgs <- getGhciPkgInfos sourceMap addPkgs (fmap fst mfileTargets) pkgDescs
163186
checkForIssues pkgs
164187
-- Finally, do the invocation of ghci
165-
runGhci opts localTargets mainIsTargets pkgs (maybe [] snd mfileTargets) (nonLocalTargets ++ addPkgs)
188+
runGhci opts localTargets mainFile pkgs (maybe [] snd mfileTargets) (nonLocalTargets ++ addPkgs)
166189

167190
preprocessTargets :: HasEnvConfig env => BuildOptsCLI -> [Text] -> RIO env (Either [Path Abs File] (Map PackageName Target))
168191
preprocessTargets buildOptsCLI rawTargets = do
@@ -321,12 +344,12 @@ runGhci
321344
:: HasEnvConfig env
322345
=> GhciOpts
323346
-> [(PackageName, (Path Abs File, Target))]
324-
-> Maybe (Map PackageName Target)
347+
-> Maybe (Path Abs File)
325348
-> [GhciPkgInfo]
326349
-> [Path Abs File]
327350
-> [PackageName]
328351
-> RIO env ()
329-
runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles exposePackages = do
352+
runGhci GhciOpts{..} targets mainFile pkgs extraFiles exposePackages = do
330353
config <- view configL
331354
wc <- view $ actualCompilerVersionL.whichCompilerL
332355
let pkgopts = hidePkgOpts ++ genOpts ++ ghcOpts
@@ -407,8 +430,6 @@ runGhci GhciOpts{..} targets mainIsTargets pkgs extraFiles exposePackages = do
407430
else do
408431
checkForDuplicateModules pkgs
409432
isIntero <- checkIsIntero
410-
bopts <- view buildOptsL
411-
mainFile <- figureOutMainFile bopts mainIsTargets targets pkgs
412433
scriptOptions <- writeGhciScript tmpDirectory (renderScript isIntero pkgs mainFile ghciOnlyMain extraFiles)
413434
execGhci (macrosOptions ++ scriptOptions)
414435

@@ -561,41 +582,24 @@ figureOutMainFile bopts mainIsTargets targets0 packages = do
561582
sampleMainIsArg (pkg,comp,_) =
562583
"--main-is " <> packageNameText pkg <> ":" <> renderComp comp
563584

564-
getGhciPkgInfos
585+
loadGhciPkgDescs
565586
:: HasEnvConfig env
566587
=> BuildOptsCLI
567-
-> SourceMap
568-
-> [PackageName]
569-
-> Maybe (Map PackageName (Set (Path Abs File)))
570588
-> [(PackageName, (Path Abs File, Target))]
571-
-> RIO env [GhciPkgInfo]
572-
getGhciPkgInfos buildOptsCLI sourceMap addPkgs mfileTargets localTargets = do
573-
(installedMap, _, _, _) <- getInstalled
574-
GetInstalledOpts
575-
{ getInstalledProfiling = False
576-
, getInstalledHaddock = False
577-
, getInstalledSymbols = False
578-
}
579-
sourceMap
580-
let localLibs = [name | (name, (_, target)) <- localTargets, hasLocalComp isCLib target]
589+
-> RIO env [GhciPkgDesc]
590+
loadGhciPkgDescs buildOptsCLI localTargets =
581591
forM localTargets $ \(name, (cabalfp, target)) ->
582-
makeGhciPkgInfo buildOptsCLI sourceMap installedMap localLibs addPkgs mfileTargets name cabalfp target
592+
loadGhciPkgDesc buildOptsCLI name cabalfp target
583593

584-
-- | Make information necessary to load the given package in GHCi.
585-
makeGhciPkgInfo
594+
-- | Load package description information for a ghci target.
595+
loadGhciPkgDesc
586596
:: HasEnvConfig env
587597
=> BuildOptsCLI
588-
-> SourceMap
589-
-> InstalledMap
590-
-> [PackageName]
591-
-> [PackageName]
592-
-> Maybe (Map PackageName (Set (Path Abs File)))
593598
-> PackageName
594599
-> Path Abs File
595600
-> Target
596-
-> RIO env GhciPkgInfo
597-
makeGhciPkgInfo buildOptsCLI sourceMap installedMap locals addPkgs mfileTargets name cabalfp target = do
598-
bopts <- view buildOptsL
601+
-> RIO env GhciPkgDesc
602+
loadGhciPkgDesc buildOptsCLI name cabalfp target = do
599603
econfig <- view envConfigL
600604
bconfig <- view buildConfigL
601605
compilerVersion <- view actualCompilerVersionL
@@ -633,15 +637,59 @@ makeGhciPkgInfo buildOptsCLI sourceMap installedMap locals addPkgs mfileTargets
633637
(C.updatePackageDescription bi x)
634638
(C.updatePackageDescription bi y))
635639
mbuildinfo
640+
return GhciPkgDesc
641+
{ ghciDescPkg = pkg
642+
, ghciDescCabalFp = cabalfp
643+
, ghciDescTarget = target
644+
}
636645

646+
getGhciPkgInfos
647+
:: HasEnvConfig env
648+
=> SourceMap
649+
-> [PackageName]
650+
-> Maybe (Map PackageName (Set (Path Abs File)))
651+
-> [GhciPkgDesc]
652+
-> RIO env [GhciPkgInfo]
653+
getGhciPkgInfos sourceMap addPkgs mfileTargets localTargets = do
654+
(installedMap, _, _, _) <- getInstalled
655+
GetInstalledOpts
656+
{ getInstalledProfiling = False
657+
, getInstalledHaddock = False
658+
, getInstalledSymbols = False
659+
}
660+
sourceMap
661+
let localLibs =
662+
[ packageName (ghciDescPkg desc)
663+
| desc <- localTargets
664+
, hasLocalComp isCLib (ghciDescTarget desc)
665+
]
666+
forM localTargets $ \pkgDesc ->
667+
makeGhciPkgInfo sourceMap installedMap localLibs addPkgs mfileTargets pkgDesc
668+
669+
-- | Make information necessary to load the given package in GHCi.
670+
makeGhciPkgInfo
671+
:: HasEnvConfig env
672+
=> SourceMap
673+
-> InstalledMap
674+
-> [PackageName]
675+
-> [PackageName]
676+
-> Maybe (Map PackageName (Set (Path Abs File)))
677+
-> GhciPkgDesc
678+
-> RIO env GhciPkgInfo
679+
makeGhciPkgInfo sourceMap installedMap locals addPkgs mfileTargets pkgDesc = do
680+
bopts <- view buildOptsL
681+
let pkg = ghciDescPkg pkgDesc
682+
cabalfp = ghciDescCabalFp pkgDesc
683+
target = ghciDescTarget pkgDesc
684+
name = packageName pkg
637685
(mods,files,opts) <- getPackageOpts (packageOpts pkg) sourceMap installedMap locals addPkgs cabalfp
638686
let filteredOpts = filterWanted opts
639687
filterWanted = M.filterWithKey (\k _ -> k `S.member` allWanted)
640688
allWanted = wantedPackageComponents bopts target pkg
641689
setMapMaybe f = S.fromList . mapMaybe f . S.toList
642690
return
643691
GhciPkgInfo
644-
{ ghciPkgName = packageName pkg
692+
{ ghciPkgName = name
645693
, ghciPkgOpts = M.toList filteredOpts
646694
, ghciPkgDir = parent cabalfp
647695
, ghciPkgModules = unionModuleMaps $

0 commit comments

Comments
 (0)