forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRepl.hs
More file actions
88 lines (84 loc) · 3.3 KB
/
Repl.hs
File metadata and controls
88 lines (84 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
-- | Run a REPL configured with the user's project(s).
module Stack.Repl where
import Control.Monad.Catch
import Control.Monad.IO.Class
import Control.Monad.Logger
import Control.Monad.Reader
import Control.Monad.Trans.Control (MonadBaseControl)
import Data.List
import qualified Data.Map.Strict as M
import Data.Maybe
import Data.Monoid
import qualified Data.Set as S
import Data.Text (Text)
import qualified Data.Text as T
import Path
import Path.IO
import Stack.Build.Source
import Stack.Exec
import Stack.Package
import Stack.Types
-- | Launch a GHCi REPL for the given local project targets with the
-- given options and configure it with the load paths and extensions
-- of those targets.
repl
:: (HasConfig r, HasBuildConfig r, HasEnvConfig r, MonadReader r m, MonadIO m, MonadThrow m, MonadLogger m, MonadCatch m, MonadBaseControl IO m)
=> [Text] -- ^ Targets.
-> [String] -- ^ GHC options.
-> FilePath
-> Bool
-> m ()
repl targets useropts ghciPath noload = do
econfig <- asks getEnvConfig
bconfig <- asks getBuildConfig
pwd <- getWorkingDir
locals <-
liftM catMaybes $
forM (M.toList (bcPackages bconfig)) $
\(dir,validWanted) ->
do cabalfp <- getCabalFileName dir
name <- parsePackageNameFromFilePath cabalfp
if validWanted && wanted pwd cabalfp name
then return (Just (name, cabalfp))
else return Nothing
pkgs <-
forM locals $
\(name,cabalfp) ->
do let config =
PackageConfig
{ packageConfigEnableTests = True
, packageConfigEnableBenchmarks = True
, packageConfigFlags = localFlags mempty bconfig name
, packageConfigGhcVersion = envConfigGhcVersion econfig
, packageConfigPlatform = configPlatform
(getConfig bconfig)
}
pkg <- readPackage config cabalfp
pkgOpts <- getPackageOpts (packageOpts pkg) (map fst locals) cabalfp
srcfiles <- getPackageFiles (packageFiles pkg) Modules cabalfp
return (packageName pkg, pkgOpts, S.toList srcfiles)
let pkgopts = filter (not . badForGhci) (concat (map _2 pkgs))
srcfiles
| noload = []
| otherwise = concatMap (map toFilePath . _3) pkgs
$logInfo
("Configuring GHCi with the following packages: " <>
T.intercalate ", " (map packageNameText (map _1 pkgs)))
exec
defaultEnvSettings
ghciPath
("--interactive" : pkgopts <> srcfiles <> useropts)
where
wanted pwd cabalfp name = isInWantedList || targetsEmptyAndInDir
where
isInWantedList = elem (packageNameText name) targets
targetsEmptyAndInDir = null targets || isParentOf (parent cabalfp) pwd
badForGhci x =
isPrefixOf "-O" x || elem x (words "-debug -threaded -ticky")
_1 (x,_,_) = x
_2 (_,x,_) = x
_3 (_,_,x) = x