forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIde.hs
More file actions
105 lines (100 loc) · 3.92 KB
/
Ide.hs
File metadata and controls
105 lines (100 loc) · 3.92 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
-- | Run a IDE configured with the user's project(s).
module Stack.Ide
(ide, getPackageOptsAndTargetFiles)
where
import Control.Concurrent
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.Aeson
import qualified Data.ByteString as S
import qualified Data.ByteString.Char8 as S8
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as L
import Data.List
import Data.Maybe
import Data.Monoid
import qualified Data.Set as S
import Data.Text (Text)
import qualified Data.Text as T
import Distribution.System
import Network.HTTP.Client.Conduit
import Path
import Path.IO
import Stack.Constants
import Stack.Exec (defaultEnvSettings)
import Stack.Ghci (GhciPkgInfo(..), ghciSetup)
import Stack.Package
import Stack.Types
import Stack.Types.Internal
import System.Directory (doesFileExist)
import System.Environment (lookupEnv)
import System.Exit
import System.IO
import qualified System.Process as P
import System.Process.Read
import System.Process.Run
-- | Launch a GHCi IDE for the given local project targets with the
-- given options and configure it with the load paths and extensions
-- of those targets.
ide
:: (HasConfig r, HasBuildConfig r, HasTerminal r, HasLogLevel r, MonadMask m, HasEnvConfig r, MonadReader r m, MonadIO m, MonadThrow m, MonadLogger m, MonadCatch m, MonadBaseControl IO m, HasHttpManager r)
=> [Text] -- ^ Targets.
-> [String] -- ^ GHC options.
-> m ()
ide targets useropts = do
(_realTargets,_,pkgs) <- ghciSetup Nothing targets
pwd <- getWorkingDir
(pkgopts,srcfiles) <-
liftM mconcat $ forM pkgs $ getPackageOptsAndTargetFiles pwd
localdb <- packageDatabaseLocal
depsdb <- packageDatabaseDeps
mpath <- liftIO $ lookupEnv "PATH"
bindirs <- extraBinDirs `ap` return True {- include local bin -}
let pkgdbs =
["--package-db=" <> toFilePath depsdb <> ":" <> toFilePath localdb]
paths =
[ "--ide-backend-tools-path=" <>
intercalate ":" (map toFilePath bindirs) <>
(maybe "" (':' :) mpath)]
args =
["--verbose"] <> ["--local-work-dir=" ++ toFilePath pwd] <>
map ("--ghc-option=" ++) useropts <>
paths <>
pkgopts <>
pkgdbs
menv <- getMinimalEnvOverride
Platform _ os <- asks getPlatform
when (os == OSX)
(callProcess (Just pwd) menv "stty" ["cbreak","-imaxbel"])
callProcess (Just pwd) menv "stack-ide" args
-- | Get options and target files for the given package info.
getPackageOptsAndTargetFiles
:: (MonadThrow m, MonadIO m, MonadReader env m, HasEnvConfig env)
=> Path Abs Dir -> GhciPkgInfo -> m ([FilePath], [FilePath])
getPackageOptsAndTargetFiles pwd pkg = do
dist <- distDirFromDir (ghciPkgDir pkg)
autogen <- return (autogenDir dist)
paths_foo <-
liftM
(autogen </>)
(parseRelFile
("Paths_" ++ packageNameString (ghciPkgName pkg) ++ ".hs"))
paths_foo_exists <- fileExists paths_foo
return
( ["--dist-dir=" <> toFilePath dist] ++
map ("--ghc-option=" ++) (ghciPkgOpts pkg)
, mapMaybe
(fmap toFilePath . stripDir pwd)
(S.toList (ghciPkgCFiles pkg) <> S.toList (ghciPkgModFiles pkg) <>
if paths_foo_exists
then [paths_foo]
else []))