@agoric/xsnap 0.14.3-u19.1 → 0.14.3-u20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.js +1 -1
- package/package.json +16 -15
- package/src/build.js +182 -191
package/api.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/xsnap",
|
|
3
|
-
"version": "0.14.3-
|
|
3
|
+
"version": "0.14.3-u20.0",
|
|
4
4
|
"description": "Snapshotting VM worker based on Moddable's XS Javascript engine",
|
|
5
5
|
"author": "Agoric",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,25 +28,26 @@
|
|
|
28
28
|
"test:xs": "exit 0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@agoric/internal": "^0.4.0-
|
|
32
|
-
"@agoric/xsnap-lockdown": "^0.14.1-
|
|
33
|
-
"@endo/bundle-source": "^
|
|
34
|
-
"@endo/errors": "^1.2.
|
|
35
|
-
"@endo/eventual-send": "^1.3.
|
|
36
|
-
"@endo/init": "^1.1.
|
|
37
|
-
"@endo/netstring": "^1.0.
|
|
38
|
-
"@endo/promise-kit": "^1.1.
|
|
39
|
-
"@endo/stream": "^1.2.
|
|
40
|
-
"@endo/stream-node": "^1.1.
|
|
31
|
+
"@agoric/internal": "^0.4.0-u20.0",
|
|
32
|
+
"@agoric/xsnap-lockdown": "^0.14.1-u20.0",
|
|
33
|
+
"@endo/bundle-source": "^4.0.0",
|
|
34
|
+
"@endo/errors": "^1.2.10",
|
|
35
|
+
"@endo/eventual-send": "^1.3.1",
|
|
36
|
+
"@endo/init": "^1.1.9",
|
|
37
|
+
"@endo/netstring": "^1.0.15",
|
|
38
|
+
"@endo/promise-kit": "^1.1.10",
|
|
39
|
+
"@endo/stream": "^1.2.10",
|
|
40
|
+
"@endo/stream-node": "^1.1.10",
|
|
41
41
|
"glob": "^7.1.6",
|
|
42
42
|
"tmp": "^0.2.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@endo/base64": "^1.0.9",
|
|
46
|
-
"@endo/nat": "^5.0
|
|
46
|
+
"@endo/nat": "^5.1.0",
|
|
47
47
|
"@types/glob": "^8.1.0",
|
|
48
48
|
"ava": "^5.3.0",
|
|
49
|
-
"c8": "^10.1.2"
|
|
49
|
+
"c8": "^10.1.2",
|
|
50
|
+
"execa": "^7.2.0"
|
|
50
51
|
},
|
|
51
52
|
"files": [
|
|
52
53
|
"LICENSE*",
|
|
@@ -76,7 +77,7 @@
|
|
|
76
77
|
"workerThreads": false
|
|
77
78
|
},
|
|
78
79
|
"typeCoverage": {
|
|
79
|
-
"atLeast": 93.
|
|
80
|
+
"atLeast": 93.56
|
|
80
81
|
},
|
|
81
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "8e4207fa19dabf76c1f91f8779b5b5b93570ecea"
|
|
82
83
|
}
|
package/src/build.js
CHANGED
|
@@ -10,9 +10,18 @@ const { freeze } = Object;
|
|
|
10
10
|
/** @param {string} path */
|
|
11
11
|
const asset = path => fileURLToPath(new URL(path, import.meta.url));
|
|
12
12
|
|
|
13
|
+
/** @param {Promise<unknown>} p */
|
|
14
|
+
const isRejected = p =>
|
|
15
|
+
p.then(
|
|
16
|
+
() => false,
|
|
17
|
+
() => true,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
/** @typedef {{ path: string, make?: string }} ModdablePlatform */
|
|
21
|
+
|
|
13
22
|
const ModdableSDK = {
|
|
14
23
|
MODDABLE: asset('../moddable'),
|
|
15
|
-
/** @type { Record<string,
|
|
24
|
+
/** @type { Record<string, ModdablePlatform>} */
|
|
16
25
|
platforms: {
|
|
17
26
|
Linux: { path: 'lin' },
|
|
18
27
|
Darwin: { path: 'mac' },
|
|
@@ -22,7 +31,8 @@ const ModdableSDK = {
|
|
|
22
31
|
};
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
|
-
*
|
|
34
|
+
* Create promise-returning functions for asynchronous execution of no-input
|
|
35
|
+
* commands.
|
|
26
36
|
*
|
|
27
37
|
* @param {string} command
|
|
28
38
|
* @param {{
|
|
@@ -48,6 +58,8 @@ function makeCLI(command, { spawn }) {
|
|
|
48
58
|
|
|
49
59
|
return freeze({
|
|
50
60
|
/**
|
|
61
|
+
* Run the command, writing directly to stdout and stderr.
|
|
62
|
+
*
|
|
51
63
|
* @param {string[]} args
|
|
52
64
|
* @param {{ cwd?: string }} [opts]
|
|
53
65
|
*/
|
|
@@ -55,26 +67,30 @@ function makeCLI(command, { spawn }) {
|
|
|
55
67
|
const { cwd = '.' } = opts || {};
|
|
56
68
|
const child = spawn(command, args, {
|
|
57
69
|
cwd,
|
|
58
|
-
stdio: ['
|
|
70
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
59
71
|
});
|
|
60
72
|
return wait(child);
|
|
61
73
|
},
|
|
62
74
|
/**
|
|
75
|
+
* Run the command, writing directly to stderr but capturing and returning
|
|
76
|
+
* stdout.
|
|
77
|
+
*
|
|
63
78
|
* @param {string[]} args
|
|
64
|
-
* @param {{ cwd?: string }} [opts]
|
|
79
|
+
* @param {{ cwd?: string, fullOutput?: boolean }} [opts]
|
|
80
|
+
* @returns {Promise<string>} command output, stripped of trailing
|
|
81
|
+
* whitespace unless option "fullOutput" is true
|
|
65
82
|
*/
|
|
66
|
-
pipe: (args, opts) => {
|
|
67
|
-
const { cwd = '.' } = opts || {};
|
|
83
|
+
pipe: async (args, opts) => {
|
|
84
|
+
const { cwd = '.', fullOutput = false } = opts || {};
|
|
68
85
|
const child = spawn(command, args, {
|
|
69
86
|
cwd,
|
|
70
|
-
stdio: ['
|
|
71
|
-
});
|
|
72
|
-
let output = '';
|
|
73
|
-
child.stdout.setEncoding('utf8');
|
|
74
|
-
child.stdout.on('data', data => {
|
|
75
|
-
output += data.toString();
|
|
87
|
+
stdio: ['ignore', 'pipe', 'inherit'],
|
|
76
88
|
});
|
|
77
|
-
|
|
89
|
+
const chunks = [];
|
|
90
|
+
child.stdout.on('data', chunk => chunks.push(chunk));
|
|
91
|
+
await wait(child);
|
|
92
|
+
const output = Buffer.concat(chunks).toString('utf8');
|
|
93
|
+
return fullOutput ? output : output.trimEnd();
|
|
78
94
|
},
|
|
79
95
|
});
|
|
80
96
|
}
|
|
@@ -85,28 +101,6 @@ function makeCLI(command, { spawn }) {
|
|
|
85
101
|
* @param {{ git: ReturnType<typeof makeCLI> }} io
|
|
86
102
|
*/
|
|
87
103
|
const makeSubmodule = (path, repoUrl, { git }) => {
|
|
88
|
-
/** @param {string} text */
|
|
89
|
-
const parseStatus = text =>
|
|
90
|
-
text
|
|
91
|
-
.split('\n')
|
|
92
|
-
// From `git submodule --help`:
|
|
93
|
-
// Show the status of the submodules. This will print the SHA-1 of the
|
|
94
|
-
// currently checked out commit for each submodule, along with the
|
|
95
|
-
// submodule path and the output of git describe for the SHA-1. Each
|
|
96
|
-
// SHA-1 will possibly be prefixed with - if the submodule is not
|
|
97
|
-
// initialized, + if the currently checked out submodule commit does
|
|
98
|
-
// not match the SHA-1 found in the index of the containing repository
|
|
99
|
-
// and U if the submodule has merge conflicts.
|
|
100
|
-
//
|
|
101
|
-
// We discovered that in other cases, the prefix is a single space.
|
|
102
|
-
.map(line => [line[0], ...line.slice(1).split(' ', 3)])
|
|
103
|
-
.map(([prefix, hash, statusPath, describe]) => ({
|
|
104
|
-
prefix,
|
|
105
|
-
hash,
|
|
106
|
-
path: statusPath,
|
|
107
|
-
describe,
|
|
108
|
-
}));
|
|
109
|
-
|
|
110
104
|
return freeze({
|
|
111
105
|
path,
|
|
112
106
|
clone: async () => git.run(['clone', repoUrl, path]),
|
|
@@ -114,90 +108,107 @@ const makeSubmodule = (path, repoUrl, { git }) => {
|
|
|
114
108
|
checkout: async commitHash =>
|
|
115
109
|
git.run(['checkout', commitHash], { cwd: path }),
|
|
116
110
|
init: async () => git.run(['submodule', 'update', '--init', '--checkout']),
|
|
117
|
-
status: async () =>
|
|
118
|
-
git.pipe(['submodule', 'status', path])
|
|
119
|
-
|
|
111
|
+
status: async () => {
|
|
112
|
+
const line = await git.pipe(['submodule', 'status', path]);
|
|
113
|
+
// From `git submodule --help`:
|
|
114
|
+
// status [--cached] [--recursive] [--] [<path>...]
|
|
115
|
+
// Show the status of the submodules. This will print the SHA-1 of the
|
|
116
|
+
// currently checked out commit for each submodule, along with the
|
|
117
|
+
// submodule path and the output of git describe for the SHA-1. Each
|
|
118
|
+
// SHA-1 will possibly be prefixed with - if the submodule is not
|
|
119
|
+
// initialized, + if the currently checked out submodule commit does
|
|
120
|
+
// not match the SHA-1 found in the index of the containing repository
|
|
121
|
+
// and U if the submodule has merge conflicts.
|
|
122
|
+
//
|
|
123
|
+
// We discovered that in other cases, the prefix is a single space.
|
|
124
|
+
const prefix = line[0];
|
|
125
|
+
const [hash, statusPath, ...describe] = line.slice(1).split(' ');
|
|
126
|
+
return {
|
|
127
|
+
prefix,
|
|
128
|
+
hash,
|
|
129
|
+
path: statusPath,
|
|
130
|
+
describe: describe.join(' '),
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
/**
|
|
134
|
+
* Read a specific configuration value for this submodule (e.g., "path" or
|
|
135
|
+
* "url") from the top-level .gitmodules.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} leaf
|
|
138
|
+
*/
|
|
120
139
|
config: async leaf => {
|
|
121
140
|
// git rev-parse --show-toplevel
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
const repoRoot = await git.pipe(['rev-parse', '--show-toplevel']);
|
|
142
|
+
if (!path.startsWith(`${repoRoot}/`)) {
|
|
143
|
+
throw Error(
|
|
144
|
+
`Expected submodule path ${path} to be a subdirectory of repository ${repoRoot}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
const relativePath = path.slice(repoRoot.length + 1);
|
|
148
|
+
// git config -f ../../.gitmodules --get submodule.${relativePath}.${leaf}
|
|
149
|
+
const value = await git.pipe([
|
|
150
|
+
'config',
|
|
151
|
+
'-f',
|
|
152
|
+
`${repoRoot}/.gitmodules`,
|
|
153
|
+
'--get',
|
|
154
|
+
`submodule.${relativePath}.${leaf}`,
|
|
155
|
+
]);
|
|
137
156
|
return value;
|
|
138
157
|
},
|
|
139
158
|
});
|
|
140
159
|
};
|
|
141
160
|
|
|
142
161
|
/**
|
|
143
|
-
* @
|
|
162
|
+
* @typedef {{
|
|
163
|
+
* url: string,
|
|
164
|
+
* path: string,
|
|
165
|
+
* commitHash?: string,
|
|
166
|
+
* envPrefix: string,
|
|
167
|
+
* }} SubmoduleDescriptor
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {SubmoduleDescriptor[]} submodules
|
|
144
172
|
* @param {{
|
|
145
|
-
*
|
|
173
|
+
* git: ReturnType<typeof makeCLI>,
|
|
146
174
|
* stdout: typeof process.stdout,
|
|
147
|
-
* spawn: typeof import('child_process').spawn,
|
|
148
|
-
* fs: {
|
|
149
|
-
* existsSync: typeof import('fs').existsSync,
|
|
150
|
-
* rmdirSync: typeof import('fs').rmdirSync,
|
|
151
|
-
* readFile: typeof import('fs').promises.readFile,
|
|
152
|
-
* },
|
|
153
175
|
* }} io
|
|
154
176
|
*/
|
|
155
|
-
const
|
|
156
|
-
const git = makeCLI('git', { spawn });
|
|
157
|
-
|
|
158
|
-
// When changing/adding entries here, make sure to search the whole project
|
|
159
|
-
// for `@@AGORIC_DOCKER_SUBMODULES@@`
|
|
160
|
-
const submodules = [
|
|
161
|
-
{
|
|
162
|
-
url: env.MODDABLE_URL || 'https://github.com/agoric-labs/moddable.git',
|
|
163
|
-
path: ModdableSDK.MODDABLE,
|
|
164
|
-
commitHash: env.MODDABLE_COMMIT_HASH,
|
|
165
|
-
envPrefix: 'MODDABLE_',
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
url:
|
|
169
|
-
env.XSNAP_NATIVE_URL || 'https://github.com/agoric-labs/xsnap-pub.git',
|
|
170
|
-
path: asset('../xsnap-native'),
|
|
171
|
-
commitHash: env.XSNAP_NATIVE_COMMIT_HASH,
|
|
172
|
-
envPrefix: 'XSNAP_NATIVE_',
|
|
173
|
-
},
|
|
174
|
-
];
|
|
175
|
-
|
|
177
|
+
const showEnv = async (submodules, { git, stdout }) => {
|
|
176
178
|
await null;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
stdout.write(`${envPrefix}URL=${submodule.url}\n`);
|
|
191
|
-
stdout.write(`${envPrefix}COMMIT_HASH=${submodule.commitHash}\n`);
|
|
179
|
+
for (const desc of submodules) {
|
|
180
|
+
const { path, envPrefix } = desc;
|
|
181
|
+
let { url, commitHash } = desc;
|
|
182
|
+
if (!commitHash) {
|
|
183
|
+
// We need to glean the commitHash and url from Git.
|
|
184
|
+
const submodule = makeSubmodule(path, '?', { git });
|
|
185
|
+
const [{ hash }, gitUrl] = await Promise.all([
|
|
186
|
+
submodule.status(),
|
|
187
|
+
submodule.config('url'),
|
|
188
|
+
]);
|
|
189
|
+
commitHash = hash;
|
|
190
|
+
url = gitUrl;
|
|
192
191
|
}
|
|
193
|
-
|
|
192
|
+
stdout.write(`${envPrefix}URL=${url}\n`);
|
|
193
|
+
stdout.write(`${envPrefix}COMMIT_HASH=${commitHash}\n`);
|
|
194
194
|
}
|
|
195
|
+
};
|
|
195
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @param {SubmoduleDescriptor[]} submodules
|
|
199
|
+
* @param {{
|
|
200
|
+
* fs: Pick<typeof import('fs'), 'existsSync' | 'rmdirSync'>,
|
|
201
|
+
* git: ReturnType<typeof makeCLI>,
|
|
202
|
+
* }} io
|
|
203
|
+
*/
|
|
204
|
+
const updateSubmodules = async (submodules, { fs, git }) => {
|
|
205
|
+
await null;
|
|
196
206
|
for (const { url, path, commitHash } of submodules) {
|
|
197
207
|
const submodule = makeSubmodule(path, url, { git });
|
|
198
208
|
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
if (!commitHash) {
|
|
210
|
+
await submodule.init();
|
|
211
|
+
} else {
|
|
201
212
|
// Do the moral equivalent of submodule update when explicitly overriding.
|
|
202
213
|
try {
|
|
203
214
|
fs.rmdirSync(submodule.path);
|
|
@@ -208,29 +219,20 @@ const updateSubmodules = async (showEnv, { env, stdout, spawn, fs }) => {
|
|
|
208
219
|
await submodule.clone();
|
|
209
220
|
}
|
|
210
221
|
await submodule.checkout(commitHash);
|
|
211
|
-
} else {
|
|
212
|
-
await submodule.init();
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
224
|
};
|
|
216
225
|
|
|
217
226
|
/**
|
|
227
|
+
* @param {ModdablePlatform} platform
|
|
228
|
+
* @param {boolean} force
|
|
218
229
|
* @param {{
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
* rmdirSync: typeof import('fs').rmdirSync,
|
|
223
|
-
* readFile: typeof import('fs').promises.readFile,
|
|
224
|
-
* writeFile: typeof import('fs').promises.writeFile,
|
|
225
|
-
* },
|
|
226
|
-
* os: {
|
|
227
|
-
* type: typeof import('os').type,
|
|
228
|
-
* }
|
|
230
|
+
* fs: Pick<typeof import('fs'), 'existsSync'> &
|
|
231
|
+
* Pick<typeof import('fs').promises, 'readFile' | 'writeFile'>,
|
|
232
|
+
* make: ReturnType<typeof makeCLI>,
|
|
229
233
|
* }} io
|
|
230
|
-
* @param {object} [options]
|
|
231
|
-
* @param {boolean} [options.forceBuild]
|
|
232
234
|
*/
|
|
233
|
-
const
|
|
235
|
+
const buildXsnap = async (platform, force, { fs, make }) => {
|
|
234
236
|
const pjson = await fs.readFile(asset('../package.json'), 'utf-8');
|
|
235
237
|
const pkg = JSON.parse(pjson);
|
|
236
238
|
|
|
@@ -245,16 +247,10 @@ const makeXsnap = async ({ spawn, fs, os }, { forceBuild = false } = {}) => {
|
|
|
245
247
|
: '';
|
|
246
248
|
|
|
247
249
|
const expectedConfigEnvs = configEnvs.concat('').join('\n');
|
|
248
|
-
if (
|
|
250
|
+
if (force || existingConfigEnvs.trim() !== expectedConfigEnvs.trim()) {
|
|
249
251
|
await fs.writeFile(configEnvFile, expectedConfigEnvs);
|
|
250
252
|
}
|
|
251
253
|
|
|
252
|
-
const platform = ModdableSDK.platforms[os.type()];
|
|
253
|
-
if (!platform) {
|
|
254
|
-
throw Error(`Unsupported OS found: ${os.type()}`);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const make = makeCLI(platform.make || 'make', { spawn });
|
|
258
254
|
for (const goal of ModdableSDK.buildGoals) {
|
|
259
255
|
await make.run(
|
|
260
256
|
[
|
|
@@ -280,15 +276,9 @@ const makeXsnap = async ({ spawn, fs, os }, { forceBuild = false } = {}) => {
|
|
|
280
276
|
* env: Record<string, string | undefined>,
|
|
281
277
|
* stdout: typeof process.stdout,
|
|
282
278
|
* spawn: typeof import('child_process').spawn,
|
|
283
|
-
* fs:
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* readFile: typeof import('fs').promises.readFile,
|
|
287
|
-
* writeFile: typeof import('fs').promises.writeFile,
|
|
288
|
-
* },
|
|
289
|
-
* os: {
|
|
290
|
-
* type: typeof import('os').type,
|
|
291
|
-
* }
|
|
279
|
+
* fs: Pick<typeof import('fs'), 'existsSync' | 'rmdirSync'> &
|
|
280
|
+
* Pick<typeof import('fs').promises, 'readFile' | 'writeFile'>,
|
|
281
|
+
* os: Pick<typeof import('os'), 'type'>,
|
|
292
282
|
* }} io
|
|
293
283
|
*/
|
|
294
284
|
async function main(args, { env, stdout, spawn, fs, os }) {
|
|
@@ -297,76 +287,77 @@ async function main(args, { env, stdout, spawn, fs, os }) {
|
|
|
297
287
|
await null;
|
|
298
288
|
|
|
299
289
|
const osType = os.type();
|
|
300
|
-
const platform =
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// Windows_NT: 'win', // One can dream.
|
|
304
|
-
}[osType];
|
|
305
|
-
if (platform === undefined) {
|
|
306
|
-
throw Error(`xsnap does not support platform ${osType}`);
|
|
290
|
+
const platform = ModdableSDK.platforms[osType];
|
|
291
|
+
if (!platform) {
|
|
292
|
+
throw Error(`xsnap does not support OS ${osType}`);
|
|
307
293
|
}
|
|
308
294
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
// We build both release and debug, so checking for one should suffice.
|
|
295
|
+
const git = makeCLI('git', { spawn });
|
|
296
|
+
const make = makeCLI(platform.make || 'make', { spawn });
|
|
297
|
+
|
|
298
|
+
// When changing/adding entries here, make sure to search the whole project
|
|
299
|
+
// for `@@AGORIC_DOCKER_SUBMODULES@@`
|
|
300
|
+
const submodules = [
|
|
301
|
+
{
|
|
302
|
+
url: env.MODDABLE_URL || 'https://github.com/agoric-labs/moddable.git',
|
|
303
|
+
path: ModdableSDK.MODDABLE,
|
|
304
|
+
commitHash: env.MODDABLE_COMMIT_HASH,
|
|
305
|
+
envPrefix: 'MODDABLE_',
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
url:
|
|
309
|
+
env.XSNAP_NATIVE_URL || 'https://github.com/agoric-labs/xsnap-pub.git',
|
|
310
|
+
path: asset('../xsnap-native'),
|
|
311
|
+
commitHash: env.XSNAP_NATIVE_COMMIT_HASH,
|
|
312
|
+
envPrefix: 'XSNAP_NATIVE_',
|
|
313
|
+
},
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
// We build both release and debug executables, so checking for only the
|
|
317
|
+
// former is fine.
|
|
333
318
|
// XXX This will need to account for the .exe extension if we recover support
|
|
334
319
|
// for Windows.
|
|
335
|
-
const
|
|
336
|
-
|
|
320
|
+
const bin = asset(
|
|
321
|
+
`../xsnap-native/xsnap/build/bin/${platform.path}/release/xsnap-worker`,
|
|
337
322
|
);
|
|
338
|
-
|
|
323
|
+
const hasBin = fs.existsSync(bin);
|
|
324
|
+
const hasSource = fs.existsSync(asset('../moddable/xs/includes/xs.h'));
|
|
339
325
|
const hasGit = fs.existsSync(asset('../moddable/.git'));
|
|
326
|
+
|
|
327
|
+
// If a git submodule is present or source files and prebuilt executables are
|
|
328
|
+
// both absent, consider ourselves to be in an active git checkout (as opposed
|
|
329
|
+
// to e.g. an extracted npm tarball).
|
|
340
330
|
const isWorkingCopy = hasGit || (!hasSource && !hasBin);
|
|
341
|
-
const showEnv = args.includes('--show-env');
|
|
342
331
|
|
|
343
|
-
|
|
344
|
-
|
|
332
|
+
// --show-env reports submodule status without making changes.
|
|
333
|
+
if (args.includes('--show-env')) {
|
|
334
|
+
if (!isWorkingCopy) {
|
|
345
335
|
throw Error('XSnap requires a working copy and git to --show-env');
|
|
346
336
|
}
|
|
347
|
-
await
|
|
348
|
-
|
|
337
|
+
await showEnv(submodules, { git, stdout });
|
|
338
|
+
return;
|
|
349
339
|
}
|
|
350
340
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
341
|
+
// Fetch/update source files via `git submodule` as appropriate.
|
|
342
|
+
if (isWorkingCopy) {
|
|
343
|
+
await updateSubmodules(submodules, { fs, git });
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// If we now have source files, (re)build from them.
|
|
347
|
+
// Otherwise, require presence of a previously-built executable.
|
|
348
|
+
if (hasSource || isWorkingCopy) {
|
|
349
|
+
// Force a rebuild if for some reason the binary is out of date
|
|
350
|
+
// since the make checks may not always detect that situation.
|
|
351
|
+
const npm = makeCLI('npm', { spawn });
|
|
352
|
+
const force = await (!hasBin ||
|
|
353
|
+
isRejected(
|
|
354
|
+
npm.run(['run', '-s', 'check-version'], { cwd: asset('..') }),
|
|
355
|
+
));
|
|
356
|
+
await buildXsnap(platform, force, { fs, make });
|
|
357
|
+
} else if (!hasBin) {
|
|
358
|
+
throw Error(
|
|
359
|
+
'XSnap has neither sources nor a pre-built binary. Docker? .dockerignore? npm files?',
|
|
360
|
+
);
|
|
370
361
|
}
|
|
371
362
|
}
|
|
372
363
|
|
|
@@ -376,10 +367,10 @@ const run = () =>
|
|
|
376
367
|
stdout: process.stdout,
|
|
377
368
|
spawn: childProcessTop.spawn,
|
|
378
369
|
fs: {
|
|
379
|
-
readFile: fsTop.promises.readFile,
|
|
380
|
-
writeFile: fsTop.promises.writeFile,
|
|
381
370
|
existsSync: fsTop.existsSync,
|
|
382
371
|
rmdirSync: fsTop.rmdirSync,
|
|
372
|
+
readFile: fsTop.promises.readFile,
|
|
373
|
+
writeFile: fsTop.promises.writeFile,
|
|
383
374
|
},
|
|
384
375
|
os: {
|
|
385
376
|
type: osTop.type,
|