-
Notifications
You must be signed in to change notification settings - Fork 664
/
Stuff.hs
179 lines (112 loc) · 3.24 KB
/
Stuff.hs
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
{-# OPTIONS_GHC -Wall #-}
module Stuff
( details
, interfaces
, objects
, prepublishDir
, elmi
, elmo
, temp
, findRoot
, withRootLock
, withRegistryLock
, PackageCache
, getPackageCache
, registry
, package
, getReplCache
, getElmHome
)
where
import qualified System.Directory as Dir
import qualified System.Environment as Env
import qualified System.FileLock as Lock
import qualified System.FilePath as FP
import System.FilePath ((</>), (<.>))
import qualified Elm.ModuleName as ModuleName
import qualified Elm.Package as Pkg
import qualified Elm.Version as V
-- PATHS
stuff :: FilePath -> FilePath
stuff root =
root </> "elm-stuff" </> compilerVersion
details :: FilePath -> FilePath
details root =
stuff root </> "d.dat"
interfaces :: FilePath -> FilePath
interfaces root =
stuff root </> "i.dat"
objects :: FilePath -> FilePath
objects root =
stuff root </> "o.dat"
prepublishDir :: FilePath -> FilePath
prepublishDir root =
stuff root </> "prepublish"
compilerVersion :: FilePath
compilerVersion =
V.toChars V.compiler
-- ELMI and ELMO
elmi :: FilePath -> ModuleName.Raw -> FilePath
elmi root name =
toArtifactPath root name "elmi"
elmo :: FilePath -> ModuleName.Raw -> FilePath
elmo root name =
toArtifactPath root name "elmo"
toArtifactPath :: FilePath -> ModuleName.Raw -> String -> FilePath
toArtifactPath root name ext =
stuff root </> ModuleName.toHyphenPath name <.> ext
-- TEMP
temp :: FilePath -> String -> FilePath
temp root ext =
stuff root </> "temp" <.> ext
-- ROOT
findRoot :: IO (Maybe FilePath)
findRoot =
do dir <- Dir.getCurrentDirectory
findRootHelp (FP.splitDirectories dir)
findRootHelp :: [String] -> IO (Maybe FilePath)
findRootHelp dirs =
case dirs of
[] ->
return Nothing
_:_ ->
do exists <- Dir.doesFileExist (FP.joinPath dirs </> "elm.json")
if exists
then return (Just (FP.joinPath dirs))
else findRootHelp (init dirs)
-- LOCKS
withRootLock :: FilePath -> IO a -> IO a
withRootLock root work =
do let dir = stuff root
Dir.createDirectoryIfMissing True dir
Lock.withFileLock (dir </> "lock") Lock.Exclusive (\_ -> work)
withRegistryLock :: PackageCache -> IO a -> IO a
withRegistryLock (PackageCache dir) work =
Lock.withFileLock (dir </> "lock") Lock.Exclusive (\_ -> work)
-- PACKAGE CACHES
newtype PackageCache = PackageCache FilePath
getPackageCache :: IO PackageCache
getPackageCache =
PackageCache <$> getCacheDir "packages"
registry :: PackageCache -> FilePath
registry (PackageCache dir) =
dir </> "registry.dat"
package :: PackageCache -> Pkg.Name -> V.Version -> FilePath
package (PackageCache dir) name version =
dir </> Pkg.toFilePath name </> V.toChars version
-- CACHE
getReplCache :: IO FilePath
getReplCache =
getCacheDir "repl"
getCacheDir :: FilePath -> IO FilePath
getCacheDir projectName =
do home <- getElmHome
let root = home </> compilerVersion </> projectName
Dir.createDirectoryIfMissing True root
return root
getElmHome :: IO FilePath
getElmHome =
do maybeCustomHome <- Env.lookupEnv "ELM_HOME"
case maybeCustomHome of
Just customHome -> return customHome
Nothing -> Dir.getAppUserDataDirectory "elm"