forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScript.hs
More file actions
105 lines (82 loc) · 3 KB
/
Script.hs
File metadata and controls
105 lines (82 loc) · 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{-# LANGUAGE OverloadedStrings #-}
module Stack.Ghci.Script
( GhciScript
, ModuleName
, cmdAdd
, cmdAddFile
, cmdCdGhc
, cmdModule
, scriptToLazyByteString
, scriptToBuilder
, scriptToFile
) where
import Control.Applicative
import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Builder
import Data.Monoid
import Data.List
import Data.Set (Set)
import qualified Data.Set as S
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8Builder)
import Path
import Prelude -- Fix redundant imports warnings
import System.IO
import Distribution.ModuleName hiding (toFilePath)
newtype GhciScript = GhciScript { unGhciScript :: [GhciCommand] }
instance Monoid GhciScript where
mempty = GhciScript []
(GhciScript xs) `mappend` (GhciScript ys) = GhciScript (ys <> xs)
data GhciCommand
= Add (Set ModuleName)
| AddFile (Path Abs File)
| CdGhc (Path Abs Dir)
| Module (Set ModuleName)
deriving (Show)
cmdAdd :: Set ModuleName -> GhciScript
cmdAdd = GhciScript . (:[]) . Add
cmdAddFile :: Path Abs File -> GhciScript
cmdAddFile = GhciScript . (:[]) . AddFile
cmdCdGhc :: Path Abs Dir -> GhciScript
cmdCdGhc = GhciScript . (:[]) . CdGhc
cmdModule :: Set ModuleName -> GhciScript
cmdModule = GhciScript . (:[]) . Module
scriptToLazyByteString :: GhciScript -> ByteString
scriptToLazyByteString = toLazyByteString . scriptToBuilder
scriptToBuilder :: GhciScript -> Builder
scriptToBuilder backwardScript = mconcat $ fmap commandToBuilder script
where
script = reverse $ unGhciScript backwardScript
scriptToFile :: Path Abs File -> GhciScript -> IO ()
scriptToFile path script =
withFile filepath WriteMode
$ \hdl -> do hSetBuffering hdl (BlockBuffering Nothing)
hSetBinaryMode hdl True
hPutBuilder hdl (scriptToBuilder script)
where
filepath = toFilePath path
-- Command conversion
fromText :: Text -> Builder
fromText = encodeUtf8Builder
commandToBuilder :: GhciCommand -> Builder
commandToBuilder (Add modules)
| S.null modules = mempty
| otherwise =
fromText ":add "
<> mconcat (intersperse (fromText " ")
$ (stringUtf8 . quoteFileName . mconcat . intersperse "." . components) <$> S.toAscList modules)
<> fromText "\n"
commandToBuilder (AddFile path) =
fromText ":add " <> stringUtf8 (quoteFileName (toFilePath path)) <> fromText "\n"
commandToBuilder (CdGhc path) =
fromText ":cd-ghc " <> stringUtf8 (quoteFileName (toFilePath path)) <> fromText "\n"
commandToBuilder (Module modules)
| S.null modules = fromText ":module +\n"
| otherwise =
fromText ":module + "
<> mconcat (intersperse (fromText " ")
$ (stringUtf8 . quoteFileName . mconcat . intersperse "." . components) <$> S.toAscList modules)
<> fromText "\n"
-- | Make sure that a filename with spaces in it gets the proper quotes.
quoteFileName :: String -> String
quoteFileName x = if ' ' `elem` x then show x else x