@wlfi-agent/cli 1.4.17 → 1.4.18
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/Cargo.lock +5 -0
- package/README.md +61 -28
- package/crates/vault-cli-admin/src/io_utils.rs +149 -1
- package/crates/vault-cli-admin/src/main.rs +639 -16
- package/crates/vault-cli-admin/src/shared_config.rs +18 -18
- package/crates/vault-cli-admin/src/tui/token_rpc.rs +190 -3
- package/crates/vault-cli-admin/src/tui/utils.rs +59 -0
- package/crates/vault-cli-admin/src/tui.rs +1205 -120
- package/crates/vault-cli-agent/Cargo.toml +1 -0
- package/crates/vault-cli-agent/src/io_utils.rs +163 -2
- package/crates/vault-cli-agent/src/main.rs +648 -32
- package/crates/vault-cli-daemon/Cargo.toml +4 -0
- package/crates/vault-cli-daemon/src/main.rs +617 -67
- package/crates/vault-cli-daemon/src/relay_sync.rs +776 -4
- package/crates/vault-cli-daemon/tests/system_keychain_helper_acl.rs +5 -0
- package/crates/vault-daemon/src/daemon_parts/api_impl_and_utils.rs +32 -1
- package/crates/vault-daemon/src/persistence.rs +637 -100
- package/crates/vault-daemon/src/tests.rs +1013 -3
- package/crates/vault-daemon/src/tests_parts/part2.rs +99 -0
- package/crates/vault-daemon/src/tests_parts/part4.rs +11 -7
- package/crates/vault-domain/src/nonce.rs +4 -0
- package/crates/vault-domain/src/tests.rs +616 -0
- package/crates/vault-policy/src/engine.rs +55 -32
- package/crates/vault-policy/src/tests.rs +195 -0
- package/crates/vault-sdk-agent/src/lib.rs +415 -22
- package/crates/vault-signer/Cargo.toml +3 -0
- package/crates/vault-signer/src/lib.rs +266 -40
- package/crates/vault-transport-unix/src/lib.rs +653 -5
- package/crates/vault-transport-xpc/src/tests.rs +531 -3
- package/crates/vault-transport-xpc/tests/e2e_flow.rs +3 -0
- package/dist/cli.cjs +663 -190
- package/dist/cli.cjs.map +1 -1
- package/package.json +5 -2
- package/packages/cache/.turbo/turbo-build.log +20 -20
- package/packages/cache/coverage/clover.xml +529 -394
- package/packages/cache/coverage/coverage-final.json +2 -2
- package/packages/cache/coverage/index.html +21 -21
- package/packages/cache/coverage/src/client/index.html +1 -1
- package/packages/cache/coverage/src/client/index.ts.html +1 -1
- package/packages/cache/coverage/src/errors/index.html +1 -1
- package/packages/cache/coverage/src/errors/index.ts.html +12 -12
- package/packages/cache/coverage/src/index.html +1 -1
- package/packages/cache/coverage/src/index.ts.html +1 -1
- package/packages/cache/coverage/src/service/index.html +21 -21
- package/packages/cache/coverage/src/service/index.ts.html +769 -313
- package/packages/cache/dist/{chunk-QNK6GOTI.js → chunk-KC53LH5Z.js} +35 -2
- package/packages/cache/dist/chunk-KC53LH5Z.js.map +1 -0
- package/packages/cache/dist/{chunk-QF4XKEIA.cjs → chunk-UVU7VFE3.cjs} +35 -2
- package/packages/cache/dist/chunk-UVU7VFE3.cjs.map +1 -0
- package/packages/cache/dist/index.cjs +2 -2
- package/packages/cache/dist/index.js +1 -1
- package/packages/cache/dist/service/index.cjs +2 -2
- package/packages/cache/dist/service/index.js +1 -1
- package/packages/cache/node_modules/.bin/tsc +2 -2
- package/packages/cache/node_modules/.bin/tsserver +2 -2
- package/packages/cache/node_modules/.bin/tsup +2 -2
- package/packages/cache/node_modules/.bin/tsup-node +2 -2
- package/packages/cache/node_modules/.bin/vitest +4 -4
- package/packages/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/cache/src/service/index.test.ts +165 -19
- package/packages/cache/src/service/index.ts +38 -1
- package/packages/config/.turbo/turbo-build.log +4 -4
- package/packages/config/dist/index.cjs +0 -17
- package/packages/config/dist/index.cjs.map +1 -1
- package/packages/config/src/index.ts +0 -17
- package/packages/rpc/.turbo/turbo-build.log +11 -11
- package/packages/rpc/dist/index.cjs +0 -17
- package/packages/rpc/dist/index.cjs.map +1 -1
- package/packages/rpc/src/index.js +1 -0
- package/packages/ui/node_modules/.bin/tsc +2 -2
- package/packages/ui/node_modules/.bin/tsserver +2 -2
- package/packages/ui/node_modules/.bin/tsup +2 -2
- package/packages/ui/node_modules/.bin/tsup-node +2 -2
- package/scripts/install-cli-launcher.mjs +37 -0
- package/scripts/install-rust-binaries.mjs +47 -0
- package/scripts/run-tests-isolated.mjs +210 -0
- package/src/cli.ts +310 -50
- package/src/lib/admin-reset.ts +15 -30
- package/src/lib/admin-setup.ts +246 -55
- package/src/lib/agent-auth-migrate.ts +5 -1
- package/src/lib/asset-broadcast.ts +15 -4
- package/src/lib/config-amounts.ts +6 -4
- package/src/lib/hidden-tty-prompt.js +1 -0
- package/src/lib/hidden-tty-prompt.ts +105 -0
- package/src/lib/keychain.ts +1 -0
- package/src/lib/local-admin-access.ts +4 -29
- package/src/lib/rust.ts +129 -33
- package/src/lib/signed-tx.ts +1 -0
- package/src/lib/sudo.ts +15 -5
- package/src/lib/wallet-profile.ts +3 -0
- package/src/lib/wallet-setup.ts +52 -0
- package/packages/cache/dist/chunk-QF4XKEIA.cjs.map +0 -1
- package/packages/cache/dist/chunk-QNK6GOTI.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.ts';
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../tsup/dist/cli-default.js" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../tsup/dist/cli-default.js" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../tsup/dist/cli-node.js" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../tsup/dist/cli-node.js" "$@"
|
|
17
17
|
fi
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { installCliLauncher } from './install-rust-binaries.mjs';
|
|
5
|
+
|
|
6
|
+
function resolveWlfiHome(env) {
|
|
7
|
+
return env.WLFI_HOME?.trim() || path.join(os.homedir(), '.wlfi_agent');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function installLocalCliLauncher({
|
|
11
|
+
env = process.env,
|
|
12
|
+
platform = process.platform,
|
|
13
|
+
cliEntrypoint,
|
|
14
|
+
} = {}) {
|
|
15
|
+
const wlfiHome = resolveWlfiHome(env);
|
|
16
|
+
const binDir = path.join(wlfiHome, 'bin');
|
|
17
|
+
return installCliLauncher({ binDir, platform, cliEntrypoint });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isDirectExecution() {
|
|
21
|
+
return (
|
|
22
|
+
Boolean(process.argv[1]) &&
|
|
23
|
+
import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (isDirectExecution()) {
|
|
28
|
+
try {
|
|
29
|
+
installLocalCliLauncher();
|
|
30
|
+
} catch (error) {
|
|
31
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
32
|
+
process.stderr.write(`${message}\n`);
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { installLocalCliLauncher };
|
|
@@ -86,6 +86,53 @@ function resolveHelperScripts(binDir) {
|
|
|
86
86
|
];
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
function resolveCliEntrypoint() {
|
|
90
|
+
return path.join(repoRoot, 'dist', 'cli.cjs');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function escapePosixShellArgument(value) {
|
|
94
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function installCliLauncher({
|
|
98
|
+
binDir,
|
|
99
|
+
cliEntrypoint = resolveCliEntrypoint(),
|
|
100
|
+
platform = process.platform,
|
|
101
|
+
allowMissingEntrypoint = false,
|
|
102
|
+
} = {}) {
|
|
103
|
+
if (!binDir) {
|
|
104
|
+
throw new Error('[wlfi-agent] binDir is required to install the CLI launcher.');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
fs.mkdirSync(binDir, { recursive: true, mode: 0o700 });
|
|
108
|
+
|
|
109
|
+
if (!fs.existsSync(cliEntrypoint)) {
|
|
110
|
+
if (allowMissingEntrypoint) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
throw new Error(
|
|
114
|
+
`[wlfi-agent] CLI entrypoint was not found at ${cliEntrypoint}. Run \`npm run build\` first.`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (platform === 'win32') {
|
|
119
|
+
const destination = path.join(binDir, 'wlfi-agent.cmd');
|
|
120
|
+
const escaped = cliEntrypoint.replace(/"/g, '""');
|
|
121
|
+
fs.writeFileSync(destination, `@echo off\r\nnode "${escaped}" %*\r\n`, {
|
|
122
|
+
mode: 0o755,
|
|
123
|
+
});
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const destination = path.join(binDir, 'wlfi-agent');
|
|
128
|
+
const script =
|
|
129
|
+
'#!/bin/sh\n' +
|
|
130
|
+
`exec node ${escapePosixShellArgument(cliEntrypoint)} "$@"\n`;
|
|
131
|
+
fs.writeFileSync(destination, script, { mode: 0o755 });
|
|
132
|
+
fs.chmodSync(destination, 0o755);
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
|
|
89
136
|
function checkCargoAvailable(spawnSyncImpl) {
|
|
90
137
|
const result = runCheck(spawnSyncImpl, 'cargo', ['--version']);
|
|
91
138
|
if (result.status === 0) {
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
|
|
8
|
+
function fail(message) {
|
|
9
|
+
console.error(message);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const forwardedArgs = process.argv.slice(2);
|
|
14
|
+
const commandArgs =
|
|
15
|
+
forwardedArgs[0] === '--' ? forwardedArgs.slice(1) : forwardedArgs;
|
|
16
|
+
|
|
17
|
+
if (commandArgs.length === 0) {
|
|
18
|
+
fail(
|
|
19
|
+
'usage: node ./scripts/run-tests-isolated.mjs -- <command> [args...]',
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const hostHome = process.env.HOME;
|
|
24
|
+
const sandboxBaseDir = hostHome ? path.join(hostHome, '.wt') : os.tmpdir();
|
|
25
|
+
fs.mkdirSync(sandboxBaseDir, { recursive: true, mode: 0o700 });
|
|
26
|
+
const sandboxRoot = fs.mkdtempSync(path.join(sandboxBaseDir, 't-'));
|
|
27
|
+
const homeDir = path.join(sandboxRoot, 'h');
|
|
28
|
+
const wlfiHome = path.join(sandboxRoot, 'w');
|
|
29
|
+
const tmpDir = path.join(sandboxRoot, 't');
|
|
30
|
+
const binDir = path.join(sandboxRoot, 'b');
|
|
31
|
+
const fakeKeychainRoot = path.join(sandboxRoot, 'k');
|
|
32
|
+
const keepSandbox = process.env.WLFI_TEST_KEEP_SANDBOX === '1';
|
|
33
|
+
const cargoHome =
|
|
34
|
+
process.env.CARGO_HOME ?? (hostHome ? path.join(hostHome, '.cargo') : undefined);
|
|
35
|
+
const rustupHome =
|
|
36
|
+
process.env.RUSTUP_HOME ?? (hostHome ? path.join(hostHome, '.rustup') : undefined);
|
|
37
|
+
const xdgCacheHome = path.join(sandboxRoot, 'c');
|
|
38
|
+
const xdgConfigHome = path.join(sandboxRoot, 'g');
|
|
39
|
+
|
|
40
|
+
for (const dir of [
|
|
41
|
+
homeDir,
|
|
42
|
+
wlfiHome,
|
|
43
|
+
tmpDir,
|
|
44
|
+
binDir,
|
|
45
|
+
fakeKeychainRoot,
|
|
46
|
+
xdgCacheHome,
|
|
47
|
+
xdgConfigHome,
|
|
48
|
+
]) {
|
|
49
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function writeExecutable(targetPath, contents) {
|
|
53
|
+
fs.writeFileSync(targetPath, contents, { mode: 0o755 });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
writeExecutable(
|
|
57
|
+
path.join(binDir, 'security'),
|
|
58
|
+
`#!/usr/bin/env node
|
|
59
|
+
import fs from 'node:fs';
|
|
60
|
+
import path from 'node:path';
|
|
61
|
+
|
|
62
|
+
const root = process.env.WLFI_TEST_FAKE_KEYCHAIN_ROOT;
|
|
63
|
+
if (!root) {
|
|
64
|
+
console.error('WLFI_TEST_FAKE_KEYCHAIN_ROOT is required');
|
|
65
|
+
process.exit(70);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const dbPath = path.join(root, 'keychain.json');
|
|
69
|
+
const [command, ...args] = process.argv.slice(2);
|
|
70
|
+
|
|
71
|
+
function loadDb() {
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(fs.readFileSync(dbPath, 'utf8'));
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error && typeof error === 'object' && error.code === 'ENOENT') {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function saveDb(db) {
|
|
83
|
+
fs.writeFileSync(dbPath, JSON.stringify(db, null, 2) + '\\n', { mode: 0o600 });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function readFlag(flag) {
|
|
87
|
+
const index = args.indexOf(flag);
|
|
88
|
+
if (index === -1 || index === args.length - 1) {
|
|
89
|
+
console.error('isolated security shim requires ' + flag);
|
|
90
|
+
process.exit(64);
|
|
91
|
+
}
|
|
92
|
+
return args[index + 1];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const service = readFlag('-s');
|
|
96
|
+
const account = readFlag('-a');
|
|
97
|
+
const key = service + '\\u0000' + account;
|
|
98
|
+
const db = loadDb();
|
|
99
|
+
|
|
100
|
+
switch (command) {
|
|
101
|
+
case 'add-generic-password': {
|
|
102
|
+
const secretHex = readFlag('-X');
|
|
103
|
+
db[key] = Buffer.from(secretHex, 'hex').toString('utf8');
|
|
104
|
+
saveDb(db);
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
case 'find-generic-password': {
|
|
108
|
+
if (!(key in db)) {
|
|
109
|
+
console.error('The specified item could not be found in the keychain.');
|
|
110
|
+
process.exit(44);
|
|
111
|
+
}
|
|
112
|
+
process.stdout.write(String(db[key]));
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
case 'delete-generic-password': {
|
|
116
|
+
if (!(key in db)) {
|
|
117
|
+
console.error('The specified item could not be found in the keychain.');
|
|
118
|
+
process.exit(44);
|
|
119
|
+
}
|
|
120
|
+
delete db[key];
|
|
121
|
+
saveDb(db);
|
|
122
|
+
process.exit(0);
|
|
123
|
+
}
|
|
124
|
+
default:
|
|
125
|
+
console.error('isolated security shim does not implement: ' + command);
|
|
126
|
+
process.exit(64);
|
|
127
|
+
}
|
|
128
|
+
`,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
for (const commandName of ['sudo', 'launchctl']) {
|
|
132
|
+
writeExecutable(
|
|
133
|
+
path.join(binDir, commandName),
|
|
134
|
+
`#!/bin/sh
|
|
135
|
+
echo "isolated test harness blocked real ${commandName}; inject a test double if this path is expected" >&2
|
|
136
|
+
exit 99
|
|
137
|
+
`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const child = spawn(commandArgs[0], commandArgs.slice(1), {
|
|
142
|
+
stdio: 'inherit',
|
|
143
|
+
env: {
|
|
144
|
+
...process.env,
|
|
145
|
+
HOME: homeDir,
|
|
146
|
+
WLFI_HOME: wlfiHome,
|
|
147
|
+
TMPDIR: tmpDir,
|
|
148
|
+
XDG_CACHE_HOME: xdgCacheHome,
|
|
149
|
+
XDG_CONFIG_HOME: xdgConfigHome,
|
|
150
|
+
PATH: `${binDir}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
151
|
+
WLFI_TEST_FAKE_KEYCHAIN_ROOT: fakeKeychainRoot,
|
|
152
|
+
WLFI_TEST_SANDBOX_ROOT: sandboxRoot,
|
|
153
|
+
WLFI_TEST_ISOLATED: '1',
|
|
154
|
+
...(cargoHome ? { CARGO_HOME: cargoHome } : {}),
|
|
155
|
+
...(rustupHome ? { RUSTUP_HOME: rustupHome } : {}),
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
let cleanedUp = false;
|
|
160
|
+
|
|
161
|
+
function cleanup() {
|
|
162
|
+
if (cleanedUp) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
cleanedUp = true;
|
|
166
|
+
|
|
167
|
+
if (keepSandbox) {
|
|
168
|
+
console.error(`kept test sandbox: ${sandboxRoot}`);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fs.rmSync(sandboxRoot, { recursive: true, force: true });
|
|
173
|
+
try {
|
|
174
|
+
fs.rmdirSync(sandboxBaseDir);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (!error || typeof error !== 'object') {
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
if (!('code' in error) || (error.code !== 'ENOENT' && error.code !== 'ENOTEMPTY')) {
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const signalExitCodes = {
|
|
186
|
+
SIGHUP: 129,
|
|
187
|
+
SIGINT: 130,
|
|
188
|
+
SIGTERM: 143,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
for (const signal of Object.keys(signalExitCodes)) {
|
|
192
|
+
process.on(signal, () => {
|
|
193
|
+
if (!child.killed) {
|
|
194
|
+
child.kill(signal);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
child.on('error', (error) => {
|
|
200
|
+
cleanup();
|
|
201
|
+
fail(`failed to start isolated test command: ${error.message}`);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
child.on('exit', (code, signal) => {
|
|
205
|
+
cleanup();
|
|
206
|
+
if (signal) {
|
|
207
|
+
process.exit(signalExitCodes[signal] ?? 1);
|
|
208
|
+
}
|
|
209
|
+
process.exit(code ?? 1);
|
|
210
|
+
});
|