-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmock-runtime.mjs
142 lines (131 loc) · 4.65 KB
/
mock-runtime.mjs
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
import fs from 'node:fs/promises';
import { constants as fsconsts } from 'node:fs';
import path from 'node:path';
import { translate_inline_srcmap } from 'nix2js-wasm';
import * as nixBlti from 'nix-builtins';
function fmtTdif(tdif) {
let [secs, nanos] = tdif;
let millis = nanos / 1000000;
return secs.toString() + "s " + millis.toFixed(3).toString() + "ms";
}
let setImmediatePromise = () => new Promise(resolve => {
setImmediate(resolve);
});
export const import_cache = new Map();
let nix_path_parsed = (() => {
let nixpath = process.env.NIX_PATH;
if (!nixpath) {
return undefined;
}
let parsed = {
lookup: {},
rest: [],
};
for (const i of nixpath.split(':')) {
let parts = i.split('=', 2);
switch(parts.length) {
case 1:
parsed.rest.push(i);
break;
case 2:
parsed.lookup[parts[0]] = parts[1];
break;
}
}
return parsed;
})();
async function importTail(real_path) {
const tstart = process.hrtime();
let fdat = null;
try {
fdat = await fs.readFile(real_path, 'utf8');
} catch(e) {
if (e.message.includes('illegal operation on a directory')) {
real_path = path.resolve(real_path, 'default.nix');
fdat = await fs.readFile(real_path, 'utf8');
} else {
console.log(real_path, e);
throw NixEvalError(e.stack);
}
}
try {
console.log(real_path + ' ' + fmtTdif(process.hrtime(tstart)) + '\tloaded');
let trld = translate_inline_srcmap(fdat, real_path);
console.log(real_path + ' ' + fmtTdif(process.hrtime(tstart)) + '\ttranslated');
let stru;
stru = (new Function('nixRt', 'nixBlti', trld));
// call the yield here to allow any hanging events to proceed
//await setImmediatePromise();
stru = stru(buildRT(real_path), nixBlti);
console.log(real_path + ' ' + fmtTdif(process.hrtime(tstart)) + '\tevaluated');
import_cache.set(real_path, stru);
console.debug(real_path + ' -res-> ');
console.debug(stru);
return stru;
} catch (e) {
console.log(real_path, e);
throw NixEvalError(e.stack);
}
}
export function import_(xpath) {
if (xpath instanceof Promise)
return xpath.then(import_);
if (xpath instanceof Error)
throw xpath;
if (!import_cache.has(xpath)) {
import_cache.set(xpath, importTail(xpath));
}
return import_cache.get(xpath);
}
function buildRT(opath) {
// get opath directory absolute.
opath = path.resolve(opath);
const dirnam = path.dirname(opath);
return {
'export': (anchor, xpath) => {
console.log(opath + ': called RT.export with anchor=' + anchor + ' path=' + xpath);
//throw Error('loading prohibited');
if (!xpath) {
throw Error(opath + ': null path');
}
switch (anchor) {
case "Relative":
return path.resolve(dirnam, xpath);
case "Absolute":
return path.resolve(xpath);
case "Home":
return path.resolve(process.env.HOME, xpath);
// weirdly named anchor...
case "Store":
if (!nix_path_parsed) {
throw new nixBlti.NixEvalError(opath + ": export not supported: " + anchor + "|" + xpath);
}
let parts = xpath.split(path.sep);
if (nix_path_parsed.lookup.hasOwnProperty(parts[0])) {
return path.resolve(nix_path_parsed.lookup[parts[0]], ... parts.slice(1));
}
return (async () => {
for (const i of nix_path_parsed.rest) {
let tmp = path.resolve(i, xpath);
try {
await fs.access(tmp, fsconsts.R_OK);
return tmp;
} catch(e) { }
}
throw new nixBlti.NixEvalError(opath + ": export did not resolve: " + anchor + "|" + xpath)
})();
default:
throw Error(opath + ": export not supported: " + anchor + "|" + xpath);
}
},
'import': import_,
'pathExists': async xpath => {
try {
await fs.access(await xpath, fsconsts.R_OK);
return true;
} catch(e) {
return false;
}
},
};
}