aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <[email protected]>2024-09-13 15:38:33 +0200
committerChristian Kandeler <[email protected]>2024-09-16 12:08:43 +0000
commit92b7df11c0cfb7b1c87cd45eb4274247742f9769 (patch)
treeda7ae585d182ab1d06f9a42ff129d43cd183c3f6
parent05430afdcf1e10f4cc9b43407f996993a6175854 (diff)
QbsProjectManager: Do renamings in bulk for qbs >= 2.5
Bulk renamings don't work reliably if we split them up on the client side. Change-Id: I5a1e58c80c1bac806dc92f535f4119d8f5374192 Reviewed-by: Christian Stenger <[email protected]>
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp43
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.h5
-rw-r--r--src/plugins/qbsprojectmanager/qbssession.cpp51
-rw-r--r--src/plugins/qbsprojectmanager/qbssession.h15
4 files changed, 105 insertions, 9 deletions
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index 19ba85ce1d7..b3acf6847de 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -272,6 +272,12 @@ bool QbsBuildSystem::renameFiles(Node *context, const FilePairs &filesToRename,
if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
const QbsProductNode * const prdNode = parentQbsProductNode(n);
QTC_ASSERT(prdNode, return false);
+
+ if (session()->apiLevel() >= 6) {
+ return renameFilesInProduct(
+ filesToRename, prdNode->productData(), n->groupData(), notRenamed);
+ }
+
bool success = true;
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
if (!renameFileInProduct(
@@ -288,6 +294,9 @@ bool QbsBuildSystem::renameFiles(Node *context, const FilePairs &filesToRename,
}
if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
+ if (session()->apiLevel() >= 6)
+ return renameFilesInProduct(filesToRename, n->productData(), n->mainGroup(), notRenamed);
+
bool success = true;
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
if (!renameFileInProduct(
@@ -433,6 +442,40 @@ bool QbsBuildSystem::renameFileInProduct(
return addFilesToProduct({FilePath::fromString(newPath)}, product, group, &dummy);
}
+bool QbsBuildSystem::renameFilesInProduct(
+ const Utils::FilePairs &files,
+ const QJsonObject &product,
+ const QJsonObject &group,
+ Utils::FilePaths *notRenamed)
+{
+ const auto allWildcardsInGroup = transform<QStringList>(
+ group.value("source-artifacts-from-wildcards").toArray(),
+ [](const QJsonValue &v) { return v.toObject().value("file-path").toString(); });
+ using FileStringPair = std::pair<QString, QString>;
+ using FileStringPairs = QList<FileStringPair>;
+ const FileStringPairs filesAsStrings = Utils::transform(files, [](const FilePair &fp) {
+ return std::make_pair(fp.first.path(), fp.second.path());
+ });
+ FileStringPairs nonWildcardFiles;
+ for (const FileStringPair &file : filesAsStrings) {
+ if (!allWildcardsInGroup.contains(file.first))
+ nonWildcardFiles << file;
+ }
+
+ const QString groupFilePath = group.value("location")
+ .toObject().value("file-path").toString();
+ ensureWriteableQbsFile(groupFilePath);
+ const FileChangeResult result = session()->renameFiles(
+ nonWildcardFiles,
+ product.value("name").toString(),
+ group.value("name").toString());
+
+ *notRenamed = FileUtils::toFilePathList(result.failedFiles());
+ if (result.error().hasError())
+ MessageManager::writeDisrupting(result.error().toString());
+ return notRenamed->isEmpty();
+}
+
QString QbsBuildSystem::profile() const
{
return QbsProfileManager::ensureProfileForKit(target()->kit());
diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h
index d7c5eaebd38..4dffaf01044 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.h
+++ b/src/plugins/qbsprojectmanager/qbsproject.h
@@ -87,6 +87,11 @@ public:
bool renameFileInProduct(const QString &oldPath,
const QString &newPath, const QJsonObject &product,
const QJsonObject &group);
+ bool renameFilesInProduct(
+ const Utils::FilePairs &files,
+ const QJsonObject &product,
+ const QJsonObject &group,
+ Utils::FilePaths *notRenamed);
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp
index 193d0396051..5920487bce8 100644
--- a/src/plugins/qbsprojectmanager/qbssession.cpp
+++ b/src/plugins/qbsprojectmanager/qbssession.cpp
@@ -142,6 +142,7 @@ public:
QHash<QString, QStringList> generatedFilesForSources;
std::optional<Error> lastError;
State state = State::Inactive;
+ int apiLevel = 0;
bool fileUpdatePossible = true;
};
@@ -259,6 +260,11 @@ QJsonObject QbsSession::projectData() const
return d->projectData;
}
+int QbsSession::apiLevel() const
+{
+ return d->apiLevel;
+}
+
void QbsSession::sendRequest(const QJsonObject &request)
{
QTC_ASSERT(d->currentRequest.isEmpty(),
@@ -317,6 +323,12 @@ FileChangeResult QbsSession::removeFiles(const QStringList &files, const QString
return updateFileList("remove-files", files, product, group);
}
+FileChangeResult QbsSession::renameFiles(
+ const QList<std::pair<QString, QString>> &files, const QString &product, const QString &group)
+{
+ return updateFileList("rename-files", files, product, group);
+}
+
RunEnvironmentResult QbsSession::getRunEnvironment(
const QString &product,
const QProcessEnvironment &baseEnv,
@@ -456,7 +468,8 @@ void QbsSession::handlePacket(const QJsonObject &packet)
setError(Error::VersionMismatch);
return;
}
- if (parent() && packet.value("api-level").toInt() > 4) {
+ d->apiLevel = packet.value("api-level").toInt();
+ if (parent() && d->apiLevel > 4) {
const QString lspSocket = packet.value("lsp-socket").toString();
if (!lspSocket.isEmpty())
d->languageClient = new QbsLanguageClient(lspSocket,
@@ -585,14 +598,38 @@ void QbsSession::setInactive()
d->languageClient = nullptr; // Owned by LanguageClientManager
}
-FileChangeResult QbsSession::updateFileList(const char *action, const QStringList &files,
- const QString &product, const QString &group)
-{
- if (d->state != State::Active)
- return FileChangeResult(files, Tr::tr("The qbs session is not in a valid state."));
+FileChangeResult QbsSession::updateFileList(
+ const char *action,
+ const std::variant<QStringList, QList<std::pair<QString, QString>>> &files,
+ const QString &product,
+ const QString &group)
+{
+ const bool filesAreStrings = std::holds_alternative<QStringList>(files);
+ if (d->state != State::Active) {
+ QStringList failedFiles;
+ if (filesAreStrings) {
+ failedFiles = std::get<QStringList>(files);
+ } else {
+ failedFiles = Utils::transform(
+ std::get<QList<std::pair<QString, QString>>>(files),
+ [](const std::pair<QString, QString> &p) { return p.first; });
+ }
+ return FileChangeResult(failedFiles, Tr::tr("The qbs session is not in a valid state."));
+ }
+ QJsonArray filesAsJson;
+ if (filesAreStrings) {
+ filesAsJson = QJsonArray::fromStringList(std::get<QStringList>(files));
+ } else {
+ for (const auto &[source, target] : std::get<QList<std::pair<QString, QString>>>(files)) {
+ const QJsonObject file(
+ {std::make_pair(QLatin1String("source-path"), source),
+ std::make_pair(QLatin1String("target-path"), target)});
+ filesAsJson << file;
+ }
+ }
const QJsonObject fileUpdateRequest{
{"type", QLatin1String(action)},
- {"files", QJsonArray::fromStringList(files)},
+ {"files", filesAsJson},
{"product", product},
{"group", group}};
if (d->fileUpdatePossible)
diff --git a/src/plugins/qbsprojectmanager/qbssession.h b/src/plugins/qbsprojectmanager/qbssession.h
index 6a6ad931540..2f0d906ee42 100644
--- a/src/plugins/qbsprojectmanager/qbssession.h
+++ b/src/plugins/qbsprojectmanager/qbssession.h
@@ -14,6 +14,8 @@
#include <functional>
#include <optional>
+#include <utility>
+#include <variant>
namespace ProjectExplorer { class Target; }
@@ -114,6 +116,8 @@ public:
static QString errorString(Error error);
QJsonObject projectData() const;
+ int apiLevel() const;
+
void sendRequest(const QJsonObject &request);
void cancelCurrentJob();
void requestFilesGeneratedFrom(const QHash<QString, QStringList> &sourceFilesPerProduct);
@@ -122,6 +126,10 @@ public:
const QString &group);
FileChangeResult removeFiles(const QStringList &files, const QString &product,
const QString &group);
+ FileChangeResult renameFiles(
+ const QList<std::pair<QString, QString>> &files,
+ const QString &product,
+ const QString &group);
RunEnvironmentResult getRunEnvironment(const QString &product,
const QProcessEnvironment &baseEnv,
const QStringList &config);
@@ -170,8 +178,11 @@ private:
void setProjectDataFromReply(const QJsonObject &packet, bool withBuildSystemFiles);
void setError(Error error);
void setInactive();
- FileChangeResult updateFileList(const char *action, const QStringList &files,
- const QString &product, const QString &group);
+ FileChangeResult updateFileList(
+ const char *action,
+ const std::variant<QStringList, QList<std::pair<QString, QString>>> &files,
+ const QString &product,
+ const QString &group);
void handleFileListUpdated(const QJsonObject &reply);
void sendNextPendingFileUpdateRequest();
void sendFileUpdateRequest(const QJsonObject &request);