-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathDirectories.hs
130 lines (104 loc) · 2.98 KB
/
Directories.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
{-# OPTIONS_GHC -Wall #-}
module Directories
( details,
interfaces,
objects,
greni,
greno,
findRoot,
withRootLock,
withRegistryLock,
PackageCache,
getPackageCache,
package,
getReplCache,
getGrenHome,
)
where
import Gren.ModuleName qualified as ModuleName
import Gren.Package qualified as Pkg
import Gren.Version qualified as V
import System.Directory qualified as Dir
import System.Environment qualified as Env
import System.FileLock qualified as Lock
import System.FilePath ((<.>), (</>))
import System.FilePath qualified as FP
-- PATHS
projectCache :: FilePath -> FilePath
projectCache root =
root </> ".gren" </> compilerVersion
details :: FilePath -> FilePath
details root =
projectCache root </> "d.dat"
interfaces :: FilePath -> FilePath
interfaces root =
projectCache root </> "i.dat"
objects :: FilePath -> FilePath
objects root =
projectCache root </> "o.dat"
compilerVersion :: FilePath
compilerVersion =
V.toChars V.compiler
-- GRENI and GRENO
greni :: FilePath -> ModuleName.Raw -> FilePath
greni root name =
toArtifactPath root name "greni"
greno :: FilePath -> ModuleName.Raw -> FilePath
greno root name =
toArtifactPath root name "greno"
toArtifactPath :: FilePath -> ModuleName.Raw -> String -> FilePath
toArtifactPath root name ext =
projectCache root </> ModuleName.toHyphenPath name <.> 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 </> "gren.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 = projectCache 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"
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 <- getGrenHome
let root = home </> compilerVersion </> projectName
Dir.createDirectoryIfMissing True root
return root
getGrenHome :: IO FilePath
getGrenHome =
do
maybeCustomHome <- Env.lookupEnv "GREN_HOME"
case maybeCustomHome of
Just customHome -> return customHome
Nothing -> Dir.getXdgDirectory Dir.XdgCache "gren"