forked from qt-creator/qt-creator
iOS: Extract basic devicectl output processing
Put creating the JSON document and error parsing into a separate function. Change-Id: I257f82249a07220467c33220c6b8e4650266b8d9 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -3,6 +3,8 @@ add_qtc_plugin(Ios
|
|||||||
PLUGIN_DEPENDS Core Debugger ProjectExplorer QmakeProjectManager CMakeProjectManager
|
PLUGIN_DEPENDS Core Debugger ProjectExplorer QmakeProjectManager CMakeProjectManager
|
||||||
SOURCES
|
SOURCES
|
||||||
createsimulatordialog.cpp createsimulatordialog.h
|
createsimulatordialog.cpp createsimulatordialog.h
|
||||||
|
devicectlutils.cpp
|
||||||
|
devicectlutils.h
|
||||||
ios.qrc
|
ios.qrc
|
||||||
iosbuildconfiguration.cpp iosbuildconfiguration.h
|
iosbuildconfiguration.cpp iosbuildconfiguration.h
|
||||||
iosbuildstep.cpp iosbuildstep.h
|
iosbuildstep.cpp iosbuildstep.h
|
||||||
|
47
src/plugins/ios/devicectlutils.cpp
Normal file
47
src/plugins/ios/devicectlutils.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "devicectlutils.h"
|
||||||
|
|
||||||
|
#include "iostr.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
Utils::expected_str<QJsonValue> Ios::Internal::parseDevicectlResult(const QByteArray &rawOutput)
|
||||||
|
{
|
||||||
|
// there can be crap (progress info) at front and/or end
|
||||||
|
const int firstCurly = rawOutput.indexOf('{');
|
||||||
|
const int start = std::max(firstCurly, 0);
|
||||||
|
const int lastCurly = rawOutput.lastIndexOf('}');
|
||||||
|
const int end = lastCurly >= 0 ? lastCurly : rawOutput.size() - 1;
|
||||||
|
QJsonParseError parseError;
|
||||||
|
auto jsonOutput = QJsonDocument::fromJson(rawOutput.sliced(start, end - start + 1), &parseError);
|
||||||
|
if (jsonOutput.isNull()) {
|
||||||
|
// parse error
|
||||||
|
return Utils::make_unexpected(
|
||||||
|
Tr::tr("Failed to parse devicectl output: %1.").arg(parseError.errorString()));
|
||||||
|
}
|
||||||
|
const QJsonValue errorValue = jsonOutput["error"];
|
||||||
|
if (!errorValue.isUndefined()) {
|
||||||
|
// error
|
||||||
|
QString error
|
||||||
|
= Tr::tr("Operation failed: %1.")
|
||||||
|
.arg(errorValue["userInfo"]["NSLocalizedDescription"]["string"].toString());
|
||||||
|
const QJsonValue userInfo
|
||||||
|
= errorValue["userInfo"]["NSUnderlyingError"]["error"]["userInfo"];
|
||||||
|
const QList<QJsonValue> moreInfo{userInfo["NSLocalizedDescription"]["string"],
|
||||||
|
userInfo["NSLocalizedFailureReason"]["string"],
|
||||||
|
userInfo["NSLocalizedRecoverySuggestion"]["string"]};
|
||||||
|
for (const QJsonValue &v : moreInfo) {
|
||||||
|
if (!v.isUndefined())
|
||||||
|
error += "\n" + v.toString();
|
||||||
|
}
|
||||||
|
return Utils::make_unexpected(error);
|
||||||
|
}
|
||||||
|
const QJsonValue resultValue = jsonOutput["result"];
|
||||||
|
if (resultValue.isUndefined()) {
|
||||||
|
return Utils::make_unexpected(
|
||||||
|
Tr::tr("Failed to parse devicectl output: 'result' is missing"));
|
||||||
|
}
|
||||||
|
return resultValue;
|
||||||
|
}
|
14
src/plugins/ios/devicectlutils.h
Normal file
14
src/plugins/ios/devicectlutils.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utils/expected.h>
|
||||||
|
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
|
namespace Ios::Internal {
|
||||||
|
|
||||||
|
Utils::expected_str<QJsonValue> parseDevicectlResult(const QByteArray &rawOutput);
|
||||||
|
|
||||||
|
} // namespace Ios::Internal
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "iosdeploystep.h"
|
#include "iosdeploystep.h"
|
||||||
|
|
||||||
|
#include "devicectlutils.h"
|
||||||
#include "iosconstants.h"
|
#include "iosconstants.h"
|
||||||
#include "iosdevice.h"
|
#include "iosdevice.h"
|
||||||
#include "iosrunconfiguration.h"
|
#include "iosrunconfiguration.h"
|
||||||
@@ -141,48 +142,23 @@ GroupItem createDeviceCtlDeployTask(
|
|||||||
Task::Error);
|
Task::Error);
|
||||||
return DoneResult::Error;
|
return DoneResult::Error;
|
||||||
}
|
}
|
||||||
const QByteArray rawOutput = process.rawStdOut();
|
const Utils::expected_str<QJsonValue> resultValue = parseDevicectlResult(
|
||||||
// there can be crap (progress info) at front and/or end
|
process.rawStdOut());
|
||||||
const int firstCurly = rawOutput.indexOf('{');
|
if (resultValue) {
|
||||||
const int start = std::max(firstCurly, 0);
|
// success
|
||||||
const int lastCurly = rawOutput.lastIndexOf('}');
|
if ((*resultValue)["installedApplications"].isUndefined()) {
|
||||||
const int end = lastCurly >= 0 ? lastCurly : rawOutput.size() - 1;
|
// something unexpected happened ...
|
||||||
QJsonParseError parseError;
|
errorHandler(
|
||||||
auto jsonOutput = QJsonDocument::fromJson(rawOutput.sliced(start, end - start + 1),
|
Tr::tr(
|
||||||
&parseError);
|
"devicectl returned unexpected output ... deployment might have failed."),
|
||||||
if (jsonOutput.isNull()) {
|
Task::Error);
|
||||||
// parse error
|
// ... proceed anyway
|
||||||
errorHandler(Tr::tr("Failed to parse devicectl output: %1.")
|
|
||||||
.arg(parseError.errorString()),
|
|
||||||
Task::Error);
|
|
||||||
return DoneResult::Error;
|
|
||||||
}
|
|
||||||
const QJsonValue errorValue = jsonOutput["error"];
|
|
||||||
if (!errorValue.isUndefined()) {
|
|
||||||
// error
|
|
||||||
QString error
|
|
||||||
= Tr::tr("Deployment failed: %1.")
|
|
||||||
.arg(errorValue["userInfo"]["NSLocalizedDescription"]["string"].toString());
|
|
||||||
const QJsonValue userInfo
|
|
||||||
= errorValue["userInfo"]["NSUnderlyingError"]["error"]["userInfo"];
|
|
||||||
const QList<QJsonValue> moreInfo{userInfo["NSLocalizedDescription"]["string"],
|
|
||||||
userInfo["NSLocalizedFailureReason"]["string"],
|
|
||||||
userInfo["NSLocalizedRecoverySuggestion"]["string"]};
|
|
||||||
for (const QJsonValue &v : moreInfo) {
|
|
||||||
if (!v.isUndefined())
|
|
||||||
error += "\n" + v.toString();
|
|
||||||
}
|
}
|
||||||
errorHandler(error, Task::Error);
|
|
||||||
return DoneResult::Error;
|
|
||||||
}
|
|
||||||
if (jsonOutput["result"]["installedApplications"].isUndefined()) {
|
|
||||||
// something unexpected happened ... proceed anyway
|
|
||||||
errorHandler(
|
|
||||||
Tr::tr("devicectl returned unexpected output ... deployment might have failed."),
|
|
||||||
Task::Error);
|
|
||||||
return DoneResult::Success;
|
return DoneResult::Success;
|
||||||
}
|
}
|
||||||
return DoneResult::Success;
|
// failure
|
||||||
|
errorHandler(resultValue.error(), Task::Error);
|
||||||
|
return DoneResult::Error;
|
||||||
};
|
};
|
||||||
return ProcessTask(onSetup, onDone);
|
return ProcessTask(onSetup, onDone);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user