-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNix.hs
79 lines (68 loc) · 2.76 KB
/
Nix.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
module Nix
( nixBuild
) where
import Route
import Conf
import Control.Monad
import Network.Wai
import System.Exit
import System.FilePath
import System.Log.Logger
import System.Process (readProcessWithExitCode)
import System.Directory
import qualified Data.Text as T
nixBuild :: Nixrbd -> Request -> String -> [String] -> Path -> IO (Either String String)
nixBuild conf req file nixpaths path = do
let buildArgs = nixBuildArgs conf file path nixpaths req
infoM "nixrbd" ("Executing nix-instantiate " ++ unwords buildArgs)
(r1,o1,e1) <- readProcessWithExitCode "nix-instantiate" buildArgs ""
let [o1',e1'] = map (T.unpack . T.strip . T.pack) [o1,e1]
if r1 /= ExitSuccess
then return $ Left $ "nix-instantiate failed: "++e1'
else do
infoM "nixrbd" ("Derivation: "++o1')
prevBuild <- lookupPreviousBuild conf o1'
case prevBuild of
Just p -> do
infoM "nixrbd" ("Existing build found: "++p)
return (Right p)
Nothing -> do
storeArgs <- nixStoreArgs conf o1'
infoM "nixrbd" ("Executing nix-store " ++ unwords storeArgs)
(r2,o2,e2) <- readProcessWithExitCode "nix-store" storeArgs ""
let [o2',e2'] = map (T.unpack . T.strip . T.pack) [o2,e2]
if r2 /= ExitSuccess
then return $ Left $ "nix-store failed: "++e2'
else do
exists <- doesFileExist o2'
return $ if not exists
then Left $ "nix-store output not a file: "++o2'
else Right o2'
-- Private interface --
listToNix :: Show a => [a] -> String
listToNix xs = "[" ++ unwords (map show xs) ++ "]"
reqToNix :: Path -> Request -> String
reqToNix path req = concat
[ "{"
, "fullPath = ", listToNix (pathInfo req), ";"
, "path = ", listToNix path, ";"
, "}"
]
nixBuildArgs :: Nixrbd -> FilePath -> Path -> [String] -> Request -> [String]
nixBuildArgs opts file path nixpaths req =
file : "--arg" : "request" : reqToNix path req : "--show-trace" :
"-Q" : concat [["-I",p] | p <- (nixrbdNixPath opts) ++ nixpaths]
nixStoreArgs :: Nixrbd -> FilePath -> IO [String]
nixStoreArgs conf drvPath = do
buildDirExists <- doesDirectoryExist (nixrbdBuildDir conf)
unless buildDirExists $ infoM "nixrbd" "No build dir. Not saving results"
let linkArgs = ["--indirect", "--add-root", buildLinkName conf drvPath]
return $ "--realise" : drvPath : if buildDirExists then linkArgs else []
buildLinkName :: Nixrbd -> FilePath -> FilePath
buildLinkName conf drvPath =
combine (nixrbdBuildDir conf) (takeFileName drvPath)
lookupPreviousBuild :: Nixrbd -> String -> IO (Maybe FilePath)
lookupPreviousBuild conf drvPath = do
let linkName = buildLinkName conf drvPath
exists <- doesFileExist linkName
return $ if not exists then Nothing else Just linkName