forked from appium/node-simctl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhelpers.ts
More file actions
72 lines (68 loc) · 2.24 KB
/
helpers.ts
File metadata and controls
72 lines (68 loc) · 2.24 KB
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
import * as semver from 'semver';
import {spawn} from 'node:child_process';
import {Readable} from 'node:stream';
export const DEFAULT_EXEC_TIMEOUT = 10 * 60 * 1000; // ms
export const SIM_RUNTIME_NAME = 'com.apple.CoreSimulator.SimRuntime.';
/**
* "Normalize" the version, since iOS uses 'major.minor' but the runtimes can
* be 'major.minor.patch'
*
* @param version - the string version
* @return The version in 'major.minor' form
* @throws {Error} If the version not parseable by the `semver` package
*/
export function normalizeVersion(version: string): string {
const semverVersion = semver.coerce(version);
if (!semverVersion) {
throw new Error(`Unable to parse version '${version}'`);
}
return `${semverVersion.major}.${semverVersion.minor}`;
}
/**
* @returns The xcrun binary name
*/
export function getXcrunBinary(): string {
return process.env.XCRUN_BINARY || 'xcrun';
}
/**
* Convert plist-style output to JSON using plutil
*
* @param plistInput - The plist-style string to convert
* @return Promise resolving to parsed JSON object
* @throws {Error} If plutil fails to convert the input
*/
export async function convertPlistToJson(plistInput: string): Promise<any> {
const plutilProcess = spawn('plutil', ['-convert', 'json', '-o', '-', '-']);
let jsonOutput = '';
plutilProcess.stdout.on('data', (chunk) => {
jsonOutput += chunk.toString();
});
const inputStream = Readable.from([plistInput]);
inputStream.pipe(plutilProcess.stdin);
try {
await new Promise<void>((resolve, reject) => {
inputStream.once('error', reject);
plutilProcess.once('exit', (code, signal) => {
inputStream.unpipe(plutilProcess.stdin);
if (code === 0) {
resolve();
} else {
reject(new Error(`plutil exited with code ${code}, signal ${signal}`));
}
});
plutilProcess.once('error', (e) => {
inputStream.unpipe(plutilProcess.stdin);
reject(e);
});
});
} catch (err) {
plutilProcess.kill(9);
throw new Error(
`Failed to convert plist to JSON: ${err instanceof Error ? err.message : String(err)}`,
);
} finally {
plutilProcess.removeAllListeners();
inputStream.removeAllListeners();
}
return JSON.parse(jsonOutput);
}