forked from qt-creator/qt-creator
iOS: Unify error output handling for all simctl commands
If simctl fails, always include its stderr output in the error, if any. Change-Id: I7a5643ac81befc9d0595e9c3bd4fa009057ff85b Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -51,7 +51,6 @@ const char buildVersionTag[] = "buildversion";
|
|||||||
static expected_str<void> runCommand(
|
static expected_str<void> runCommand(
|
||||||
const CommandLine &command,
|
const CommandLine &command,
|
||||||
QString *stdOutput,
|
QString *stdOutput,
|
||||||
QString *allOutput = nullptr,
|
|
||||||
std::function<bool()> shouldStop = [] { return false; })
|
std::function<bool()> shouldStop = [] { return false; })
|
||||||
{
|
{
|
||||||
Process p;
|
Process p;
|
||||||
@@ -76,11 +75,15 @@ static expected_str<void> runCommand(
|
|||||||
|
|
||||||
if (stdOutput)
|
if (stdOutput)
|
||||||
*stdOutput = p.cleanedStdOut();
|
*stdOutput = p.cleanedStdOut();
|
||||||
if (allOutput)
|
|
||||||
*allOutput = p.allOutput();
|
|
||||||
|
|
||||||
if (p.result() != ProcessResult::FinishedWithSuccess)
|
if (p.result() != ProcessResult::FinishedWithSuccess) {
|
||||||
return make_unexpected(p.errorString());
|
QStringList error;
|
||||||
|
if (const QString procError = p.errorString(); !procError.isEmpty())
|
||||||
|
error << procError;
|
||||||
|
if (const QString stdError = p.cleanedStdErr(); !stdError.isEmpty())
|
||||||
|
error << stdError;
|
||||||
|
return make_unexpected(error.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -88,7 +91,6 @@ static expected_str<void> runCommand(
|
|||||||
static expected_str<void> runSimCtlCommand(
|
static expected_str<void> runSimCtlCommand(
|
||||||
const QStringList &args,
|
const QStringList &args,
|
||||||
QString *output,
|
QString *output,
|
||||||
QString *allOutput = nullptr,
|
|
||||||
std::function<bool()> shouldStop = [] { return false; })
|
std::function<bool()> shouldStop = [] { return false; })
|
||||||
{
|
{
|
||||||
// Cache xcrun's path, as this function will be called often.
|
// Cache xcrun's path, as this function will be called often.
|
||||||
@@ -97,7 +99,7 @@ static expected_str<void> runSimCtlCommand(
|
|||||||
return make_unexpected(Tr::tr("Cannot find xcrun."));
|
return make_unexpected(Tr::tr("Cannot find xcrun."));
|
||||||
else if (!xcrun.isExecutableFile())
|
else if (!xcrun.isExecutableFile())
|
||||||
return make_unexpected(Tr::tr("xcrun is not executable."));
|
return make_unexpected(Tr::tr("xcrun is not executable."));
|
||||||
return runCommand({xcrun, {"simctl", args}}, output, allOutput, shouldStop);
|
return runCommand({xcrun, {"simctl", args}}, output, shouldStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static expected_str<void> launchSimulator(const QString &simUdid, std::function<bool()> shouldStop)
|
static expected_str<void> launchSimulator(const QString &simUdid, std::function<bool()> shouldStop)
|
||||||
@@ -109,14 +111,13 @@ static expected_str<void> launchSimulator(const QString &simUdid, std::function<
|
|||||||
if (IosConfigurations::xcodeVersion() >= QVersionNumber(9)) {
|
if (IosConfigurations::xcodeVersion() >= QVersionNumber(9)) {
|
||||||
// For XCode 9 boot the second device instead of launching simulator app twice.
|
// For XCode 9 boot the second device instead of launching simulator app twice.
|
||||||
QString psOutput;
|
QString psOutput;
|
||||||
expected_str<void> result
|
expected_str<void> result = runCommand({"ps", {"-A", "-o", "comm"}}, &psOutput, shouldStop);
|
||||||
= runCommand({"ps", {"-A", "-o", "comm"}}, &psOutput, nullptr, shouldStop);
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
for (const QString &comm : psOutput.split('\n')) {
|
for (const QString &comm : psOutput.split('\n')) {
|
||||||
if (comm == simulatorAppPath.toString())
|
if (comm == simulatorAppPath.toString())
|
||||||
return runSimCtlCommand({"boot", simUdid}, nullptr, nullptr, shouldStop);
|
return runSimCtlCommand({"boot", simUdid}, nullptr, shouldStop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const bool started = Process::startDetached(
|
const bool started = Process::startDetached(
|
||||||
@@ -480,15 +481,12 @@ void installApp(QPromise<SimulatorControl::Response> &promise,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString allOutput;
|
expected_str<void> result
|
||||||
expected_str<void> result = runSimCtlCommand(
|
= runSimCtlCommand({"install", simUdid, bundlePath.toString()}, nullptr, [&promise] {
|
||||||
{"install", simUdid, bundlePath.toString()}, nullptr, &allOutput, [&promise] {
|
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
if (!result) {
|
if (!result) {
|
||||||
const QString error = result.error().isEmpty() ? allOutput
|
promise.addResult(make_unexpected(result.error()));
|
||||||
: (result.error() + "\n" + allOutput);
|
|
||||||
promise.addResult(make_unexpected(error));
|
|
||||||
} else {
|
} else {
|
||||||
promise.addResult(response);
|
promise.addResult(response);
|
||||||
}
|
}
|
||||||
@@ -527,7 +525,7 @@ void launchApp(QPromise<SimulatorControl::Response> &promise,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString stdOutput;
|
QString stdOutput;
|
||||||
expected_str<void> result = runSimCtlCommand(args, &stdOutput, nullptr, [&promise] {
|
expected_str<void> result = runSimCtlCommand(args, &stdOutput, [&promise] {
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -552,7 +550,7 @@ void launchApp(QPromise<SimulatorControl::Response> &promise,
|
|||||||
void deleteSimulator(QPromise<SimulatorControl::Response> &promise, const QString &simUdid)
|
void deleteSimulator(QPromise<SimulatorControl::Response> &promise, const QString &simUdid)
|
||||||
{
|
{
|
||||||
SimulatorControl::ResponseData response(simUdid);
|
SimulatorControl::ResponseData response(simUdid);
|
||||||
expected_str<void> result = runSimCtlCommand({"delete", simUdid}, nullptr, nullptr, [&promise] {
|
expected_str<void> result = runSimCtlCommand({"delete", simUdid}, nullptr, [&promise] {
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -565,7 +563,7 @@ void deleteSimulator(QPromise<SimulatorControl::Response> &promise, const QStrin
|
|||||||
void resetSimulator(QPromise<SimulatorControl::Response> &promise, const QString &simUdid)
|
void resetSimulator(QPromise<SimulatorControl::Response> &promise, const QString &simUdid)
|
||||||
{
|
{
|
||||||
SimulatorControl::ResponseData response(simUdid);
|
SimulatorControl::ResponseData response(simUdid);
|
||||||
expected_str<void> result = runSimCtlCommand({"erase", simUdid}, nullptr, nullptr, [&promise] {
|
expected_str<void> result = runSimCtlCommand({"erase", simUdid}, nullptr, [&promise] {
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -580,8 +578,7 @@ void renameSimulator(QPromise<SimulatorControl::Response> &promise,
|
|||||||
const QString &newName)
|
const QString &newName)
|
||||||
{
|
{
|
||||||
SimulatorControl::ResponseData response(simUdid);
|
SimulatorControl::ResponseData response(simUdid);
|
||||||
expected_str<void> result
|
expected_str<void> result = runSimCtlCommand({"rename", simUdid, newName}, nullptr, [&promise] {
|
||||||
= runSimCtlCommand({"rename", simUdid, newName}, nullptr, nullptr, [&promise] {
|
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
if (!result)
|
if (!result)
|
||||||
@@ -604,10 +601,9 @@ void createSimulator(QPromise<SimulatorControl::Response> &promise,
|
|||||||
|
|
||||||
QString stdOutput;
|
QString stdOutput;
|
||||||
expected_str<void> result = runSimCtlCommand(
|
expected_str<void> result = runSimCtlCommand(
|
||||||
{"create", name, deviceType.identifier, runtime.identifier},
|
{"create", name, deviceType.identifier, runtime.identifier}, &stdOutput, [&promise] {
|
||||||
&stdOutput,
|
return promise.isCanceled();
|
||||||
nullptr,
|
});
|
||||||
[&promise] { return promise.isCanceled(); });
|
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
response.simUdid = stdOutput.trimmed();
|
response.simUdid = stdOutput.trimmed();
|
||||||
@@ -624,7 +620,7 @@ void takeSceenshot(QPromise<SimulatorControl::Response> &promise,
|
|||||||
{
|
{
|
||||||
SimulatorControl::ResponseData response(simUdid);
|
SimulatorControl::ResponseData response(simUdid);
|
||||||
expected_str<void> result
|
expected_str<void> result
|
||||||
= runSimCtlCommand({"io", simUdid, "screenshot", filePath}, nullptr, nullptr, [&promise] {
|
= runSimCtlCommand({"io", simUdid, "screenshot", filePath}, nullptr, [&promise] {
|
||||||
return promise.isCanceled();
|
return promise.isCanceled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user