in src/com/facebook/buck/cli/InstallCommand.java [932:1110]
private InstallResult installAppleBundleForSimulator(
CommandRunnerParams params,
AppleBundle appleBundle,
SourcePathResolverAdapter pathResolver,
ProjectFilesystem projectFilesystem,
ProcessExecutor processExecutor)
throws IOException, InterruptedException {
AppleConfig appleConfig = params.getBuckConfig().getView(AppleConfig.class);
Optional<Path> xcodeDeveloperPath =
appleConfig.getAppleDeveloperDirectorySupplier(processExecutor).get();
if (!xcodeDeveloperPath.isPresent()) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (Xcode not found)", appleBundle.getFullyQualifiedName()));
return FAILURE;
}
UnixUserIdFetcher userIdFetcher = new UnixUserIdFetcher();
AppleCoreSimulatorServiceController appleCoreSimulatorServiceController =
new AppleCoreSimulatorServiceController(processExecutor);
Optional<Path> coreSimulatorServicePath =
appleCoreSimulatorServiceController.getCoreSimulatorServicePath(userIdFetcher);
boolean shouldWaitForSimulatorsToShutdown = false;
if (!coreSimulatorServicePath.isPresent()
|| !coreSimulatorServicePath
.get()
.toRealPath()
.startsWith(xcodeDeveloperPath.get().toRealPath())) {
LOG.warn(
"Core simulator service path %s does not match developer directory %s, "
+ "killing all simulators.",
coreSimulatorServicePath, xcodeDeveloperPath.get());
if (!appleCoreSimulatorServiceController.killSimulatorProcesses()) {
params.getConsole().printBuildFailure("Could not kill running simulator processes.");
return FAILURE;
}
shouldWaitForSimulatorsToShutdown = true;
}
Path simctlPath = xcodeDeveloperPath.get().resolve("usr/bin/simctl");
Optional<AppleSimulator> appleSimulator =
getAppleSimulatorForBundle(appleBundle, processExecutor, simctlPath);
if (!appleSimulator.isPresent()) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (no appropriate simulator found)",
appleBundle.getFullyQualifiedName()));
return FAILURE;
}
Path iosSimulatorPath = null;
Path xcodeApplicationsPath = xcodeDeveloperPath.get().resolve("Applications");
for (String simulatorApp : APPLE_SIMULATOR_APPS) {
Path resolvedSimulatorPath = xcodeApplicationsPath.resolve(simulatorApp);
if (projectFilesystem.isDirectory(resolvedSimulatorPath)) {
iosSimulatorPath = resolvedSimulatorPath;
break;
}
}
if (iosSimulatorPath == null) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (could not find simulator under %s, checked %s)",
appleBundle.getFullyQualifiedName(),
xcodeApplicationsPath,
APPLE_SIMULATOR_APPS));
return FAILURE;
}
AppleSimulatorController appleSimulatorController =
new AppleSimulatorController(processExecutor, simctlPath, iosSimulatorPath);
if (!appleSimulatorController.canStartSimulator(appleSimulator.get().getUdid())) {
LOG.info("Cannot start simulator %s, killing simulators and trying again.");
if (!appleCoreSimulatorServiceController.killSimulatorProcesses()) {
params.getConsole().printBuildFailure("Could not kill running simulator processes.");
return FAILURE;
}
shouldWaitForSimulatorsToShutdown = true;
// Killing the simulator can cause the UDIDs to change, so we need to fetch them again.
appleSimulator = getAppleSimulatorForBundle(appleBundle, processExecutor, simctlPath);
if (!appleSimulator.isPresent()) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (no appropriate simulator found)",
appleBundle.getFullyQualifiedName()));
return FAILURE;
}
}
long remainingMillis = APPLE_SIMULATOR_WAIT_MILLIS;
if (shouldWaitForSimulatorsToShutdown) {
Optional<Long> shutdownMillis =
appleSimulatorController.waitForSimulatorsToShutdown(remainingMillis);
if (!shutdownMillis.isPresent()) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (simulators did not shut down within %d ms).",
appleBundle.getFullyQualifiedName(), APPLE_SIMULATOR_WAIT_MILLIS));
return FAILURE;
}
LOG.debug("Simulators shut down in %d millis.", shutdownMillis.get());
remainingMillis -= shutdownMillis.get();
}
LOG.debug("Starting up simulator %s", appleSimulator.get());
Optional<Long> startMillis =
appleSimulatorController.startSimulator(appleSimulator.get().getUdid(), remainingMillis);
if (!startMillis.isPresent()) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (could not start simulator %s within %d ms)",
appleBundle.getFullyQualifiedName(),
appleSimulator.get().getName(),
APPLE_SIMULATOR_WAIT_MILLIS));
return FAILURE;
}
LOG.debug(
"Simulator started in %d ms. Installing Apple bundle %s in simulator %s",
startMillis.get(), appleBundle, appleSimulator.get());
if (!appleSimulatorController.installBundleInSimulator(
appleSimulator.get().getUdid(),
pathResolver.getAbsolutePath(
Objects.requireNonNull(appleBundle.getSourcePathToOutput())))) {
params
.getConsole()
.printBuildFailure(
String.format(
"Cannot install %s (could not install bundle %s in simulator %s)",
appleBundle.getFullyQualifiedName(),
pathResolver.getAbsolutePath(appleBundle.getSourcePathToOutput()),
appleSimulator.get().getName()));
return FAILURE;
}
if (run) {
return launchAppleBundle(
params, appleBundle, appleSimulatorController, projectFilesystem, appleSimulator.get());
} else {
params
.getBuckEventBus()
.post(
ConsoleEvent.info(
params
.getConsole()
.getAnsi()
.asHighlightedSuccessText(
"Successfully installed %s. (Use `buck install -r %s` to run.)"),
getArguments().get(0),
getArguments().get(0)));
return ImmutableInstallResult.of(ExitCode.SUCCESS, Optional.empty());
}
}