Skip to content

Commit 79cc924

Browse files
Merge pull request #121 from telerik/vladimirov/fix-xcrun
fix: popup is shown when searching for iOS Simulators
2 parents f347e0a + 5c6675c commit 79cc924

File tree

5 files changed

+43
-33
lines changed

5 files changed

+43
-33
lines changed

lib/child-process.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as child_process from "child_process";
22

3-
export function execSync(command: string, opts?: any): any {
3+
export function execSync(command: string, execSyncOptions?: child_process.ExecSyncOptions, opts?: ISkipErrorComposition): any {
44
try {
5-
return child_process.execSync(command, opts);
5+
return child_process.execSync(command, execSyncOptions);
66
} catch (err) {
77
if (opts && opts.skipError) {
88
return err;
@@ -12,9 +12,9 @@ export function execSync(command: string, opts?: any): any {
1212
}
1313
}
1414

15-
export function spawnSync(command: string, args: string[], opts?: any): any {
15+
export function spawnSync(command: string, args: string[], spawnSyncOpts?: child_process.SpawnSyncOptions, opts?: ISkipErrorComposition): any {
1616
try {
17-
return child_process.spawnSync(command, args, opts);
17+
return child_process.spawnSync(command, args, spawnSyncOpts);
1818
} catch (err) {
1919
if (opts && opts.skipError) {
2020
return err;
@@ -24,12 +24,12 @@ export function spawnSync(command: string, args: string[], opts?: any): any {
2424
}
2525
}
2626

27-
export function spawn(command: string, args: string[], opts?: any): Promise<string> {
27+
export function spawn(command: string, args: string[], spawnOpts?: child_process.SpawnOptions, opts?: ISkipErrorComposition): Promise<string> {
2828
return new Promise<string>((resolve, reject) => {
2929
let capturedOut = "";
3030
let capturedErr = "";
3131

32-
let childProcess = child_process.spawn(command, args);
32+
let childProcess = child_process.spawn(command, args, spawnOpts);
3333

3434
if (childProcess.stdout) {
3535
childProcess.stdout.on("data", (data: string) => {
@@ -60,4 +60,4 @@ export function spawn(command: string, args: string[], opts?: any): Promise<stri
6060
reject(err);
6161
});
6262
});
63-
}
63+
}

lib/declarations.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@ interface IDevice {
2626
rawDevice?: any; // NodObjC wrapper to device
2727
}
2828

29+
interface ISkipErrorComposition {
30+
skipError: boolean;
31+
}
32+
2933
interface ISimctl {
3034
launch(deviceId: string, applicationIdentifier: string, options: IOptions): Promise<string>;
3135
boot(deviceId: string): Promise<void>;
3236
terminate(deviceId: string, appIdentifier: string): Promise<string>;
3337
install(deviceId: string, applicationPath: string): Promise<void>;
34-
uninstall(deviceId: string, applicationIdentifier: string, opts?: any): Promise<void>;
38+
uninstall(deviceId: string, applicationIdentifier: string, opts?: ISkipErrorComposition): Promise<void>;
3539
notifyPost(deviceId: string, notification: string): Promise<void>;
3640
getDevices(): Promise<IDevice[]>;
3741
getLog(deviceId: string, predicate?: string): any;

lib/iphone-simulator-xcode-simctl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
9797
try {
9898
let pid = this.getPid(deviceId, bundleExecutable);
9999
while (pid) {
100-
childProcess.execSync(`kill -9 ${pid}`, { skipError: true });
100+
childProcess.execSync(`kill -9 ${pid}`, null, { skipError: true });
101101
pid = this.getPid(deviceId, bundleExecutable);
102102
if (pid) {
103103
utils.sleep(0.1);
@@ -117,7 +117,7 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
117117
// The process, that is execed by Node.js is also returned, so we need to exclude it from the result.
118118
// To achieve this, remove the command we've executed from the ps result.
119119
const grepAppProcessCommand = `ps -ef | grep ${bundleExecutable} | grep \/${deviceId}\/`;
120-
return childProcess.execSync(`${grepAppProcessCommand} | grep -v "${grepAppProcessCommand}" | awk '{print $2}'`, { skipError: true }).toString().trim();
120+
return childProcess.execSync(`${grepAppProcessCommand} | grep -v "${grepAppProcessCommand}" | awk '{print $2}'`, null, { skipError: true }).toString().trim();
121121
}
122122

123123
public async getDeviceLogProcess(deviceId: string, predicate?: string): Promise<child_process.ChildProcess> {

lib/simctl.ts

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ export class Simctl implements ISimctl {
3333
return this.spawnAsync("boot", [deviceId]);
3434
}
3535

36-
public terminate(deviceId: string, appIdentifier: string): Promise<string> {
36+
public terminate(deviceId: string, appIdentifier: string): Promise<string> {
3737
return this.spawnAsync("terminate", [deviceId, appIdentifier]);
3838
}
3939

40-
public install(deviceId: string, applicationPath: string): Promise<void> {
40+
public install(deviceId: string, applicationPath: string): Promise<void> {
4141
return this.spawnAsync("install", [deviceId, applicationPath]);
4242
}
4343

44-
public uninstall(deviceId: string, appIdentifier: string, opts?: any): Promise<void> {
44+
public uninstall(deviceId: string, appIdentifier: string, opts?: any): Promise<void> {
4545
return this.spawnAsync("uninstall", [deviceId, appIdentifier], opts);
4646
}
4747

@@ -138,31 +138,37 @@ export class Simctl implements ISimctl {
138138
return this.simctlSpawn("spawn", [deviceId, "log", "stream", "--style", "syslog"].concat(predicateArgs));
139139
}
140140

141-
private simctlExec(command: string, args: string[], opts?: any): string {
142-
const result = childProcess.spawnSync("xcrun", ["simctl", command].concat(args), opts);
143-
if (result && result.stderr && !_.isEmpty(result.stderr)) {
144-
throw new Error(`Error while executing command '${["xcrun", "simctl", command].concat(args).join(" ")}'. Please ensure your tools are configured correctly. More info: ${result.stderr.toString()}`);
145-
}
146-
if (result) {
147-
if (result.signal) {
148-
// In some cases, sending Ctrl + C (SIGINT) is handled by the simctl itself and spawnSync finishes, but the SIGINT does not stop current process.
149-
// In order to ensure the same signal is sent to the caller (CLI for example), send the signal manually:
150-
process.send(result.signal);
151-
}
152-
153-
if (result.stdout) {
154-
return result.stdout.toString().trim();
141+
private async spawnAsync(command: string, args: string[], spawnOpts?: child_process.SpawnOptions, opts?: ISkipErrorComposition): Promise<any> {
142+
const { canExecuteXcrun, xcodeToolsError } = this.verifyXcodeCommandLineToolsAreInstalled();
143+
if (!canExecuteXcrun) {
144+
if (opts.skipError) {
145+
return null;
146+
} else {
147+
throw xcodeToolsError;
155148
}
156149
}
157150

158-
return '';
151+
return childProcess.spawn("xcrun", ["simctl", command].concat(args), spawnOpts, opts);
159152
}
160153

161-
private simctlSpawn(command: string, args: string[], opts?: child_process.SpawnOptions): child_process.ChildProcess {
162-
return child_process.spawn("xcrun", ["simctl", command].concat(args), opts);
154+
private verifyXcodeCommandLineToolsAreInstalled(): { canExecuteXcrun: boolean, xcodeToolsError: Error } {
155+
let canExecuteXcrun = false;
156+
let xcodeToolsError: Error = null;
157+
158+
try {
159+
const result = childProcess.execSync("xcode-select -p", { stdio: "pipe" });
160+
canExecuteXcrun = !!(result && result.toString().trim());
161+
if (!canExecuteXcrun) {
162+
xcodeToolsError = new Error("Unable to work with iOS Simulator as Xcode Command Line Tools cannot be found.");
163+
}
164+
} catch (err) {
165+
xcodeToolsError = err
166+
}
167+
168+
return { canExecuteXcrun, xcodeToolsError };
163169
}
164170

165-
private spawnAsync(command: string, args: string[], opts?: child_process.SpawnOptions): Promise<any> {
166-
return childProcess.spawn("xcrun", ["simctl", command].concat(args), opts);
171+
private simctlSpawn(command: string, args: string[], spawnOpts?: child_process.SpawnOptions): child_process.ChildProcess {
172+
return child_process.spawn("xcrun", ["simctl", command].concat(args), spawnOpts);
167173
}
168174
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ios-sim-portable",
3-
"version": "4.0.8",
3+
"version": "4.0.9",
44
"description": "",
55
"main": "./lib/ios-sim.js",
66
"scripts": {

0 commit comments

Comments
 (0)