/*
* Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.apple.simulator;
import com.facebook.buck.log.Logger;
import com.facebook.buck.util.ProcessExecutor;
import com.facebook.buck.util.ProcessExecutorParams;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Optional;
/** Utilty class to discover state about Apple simulators installed on the host system. */
public class AppleSimulatorDiscovery {
private static final Logger LOG = Logger.get(AppleSimulatorDiscovery.class);
// Utility class, do not instantiate.
private AppleSimulatorDiscovery() {}
/** Discovers information about Apple simulators installed on the system. */
public static ImmutableSet<AppleSimulator> discoverAppleSimulators(
ProcessExecutor processExecutor, Path simctlPath) throws InterruptedException, IOException {
LOG.debug("Running xcrun simctl list to get list of simulators");
ProcessExecutorParams processExecutorParams =
ProcessExecutorParams.builder()
.setCommand(ImmutableList.of(simctlPath.toString(), "list"))
.build();
ProcessExecutor.LaunchedProcess simctlListProcess =
processExecutor.launchProcess(processExecutorParams);
ImmutableSet.Builder<AppleSimulator> simulatorsBuilder = ImmutableSet.builder();
try (InputStreamReader stdoutReader =
new InputStreamReader(simctlListProcess.getInputStream(), StandardCharsets.UTF_8)) {
LOG.debug("Parsing output of xcrun simctl list...");
SimctlListOutputParsing.parseOutputFromReader(stdoutReader, simulatorsBuilder);
}
ProcessExecutor.Result result = processExecutor.waitForLaunchedProcess(simctlListProcess);
if (result.getExitCode() != 0) {
throw new IOException(result.getMessageForUnexpectedResult("simctl list"));
}
ImmutableSet<AppleSimulator> simulators = simulatorsBuilder.build();
LOG.debug("Discovered simulators: %s", simulators);
return simulators;
}
/**
* Given a simulators, looks up metadata on the supported architectures and product families for
* that simulator (if present).
*/
public static Optional<AppleSimulatorProfile> discoverAppleSimulatorProfile(
AppleSimulator appleSimulator, Path iphonesimulatorPlatformRoot) throws IOException {
Path simulatorProfilePlistPath =
iphonesimulatorPlatformRoot.resolve(
String.format(
"Developer/Library/CoreSimulator/Profiles/DeviceTypes/%s.simdevicetype/"
+ "Contents/Resources/profile.plist",
appleSimulator.getName()));
LOG.debug("Parsing simulator profile plist %s", simulatorProfilePlistPath);
try (InputStream inputStream = Files.newInputStream(simulatorProfilePlistPath)) {
// This might return Optional.empty() if the input could not be parsed.
return AppleSimulatorProfileParsing.parseProfilePlistStream(inputStream);
} catch (FileNotFoundException | NoSuchFileException e) {
LOG.warn(e, "Could not open simulator profile %s, ignoring", simulatorProfilePlistPath);
return Optional.empty();
}
}
}