forked from qt-creator/qt-creator
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 <christian.stenger@qt.io>
This commit is contained in:
@@ -272,6 +272,12 @@ bool QbsBuildSystem::renameFiles(Node *context, const FilePairs &filesToRename,
|
|||||||
if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
|
if (auto *n = dynamic_cast<QbsGroupNode *>(context)) {
|
||||||
const QbsProductNode * const prdNode = parentQbsProductNode(n);
|
const QbsProductNode * const prdNode = parentQbsProductNode(n);
|
||||||
QTC_ASSERT(prdNode, return false);
|
QTC_ASSERT(prdNode, return false);
|
||||||
|
|
||||||
|
if (session()->apiLevel() >= 6) {
|
||||||
|
return renameFilesInProduct(
|
||||||
|
filesToRename, prdNode->productData(), n->groupData(), notRenamed);
|
||||||
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
|
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
|
||||||
if (!renameFileInProduct(
|
if (!renameFileInProduct(
|
||||||
@@ -288,6 +294,9 @@ bool QbsBuildSystem::renameFiles(Node *context, const FilePairs &filesToRename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
|
if (auto *n = dynamic_cast<QbsProductNode *>(context)) {
|
||||||
|
if (session()->apiLevel() >= 6)
|
||||||
|
return renameFilesInProduct(filesToRename, n->productData(), n->mainGroup(), notRenamed);
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
|
for (const auto &[oldFilePath, newFilePath] : filesToRename) {
|
||||||
if (!renameFileInProduct(
|
if (!renameFileInProduct(
|
||||||
@@ -433,6 +442,40 @@ bool QbsBuildSystem::renameFileInProduct(
|
|||||||
return addFilesToProduct({FilePath::fromString(newPath)}, product, group, &dummy);
|
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
|
QString QbsBuildSystem::profile() const
|
||||||
{
|
{
|
||||||
return QbsProfileManager::ensureProfileForKit(target()->kit());
|
return QbsProfileManager::ensureProfileForKit(target()->kit());
|
||||||
|
@@ -87,6 +87,11 @@ public:
|
|||||||
bool renameFileInProduct(const QString &oldPath,
|
bool renameFileInProduct(const QString &oldPath,
|
||||||
const QString &newPath, const QJsonObject &product,
|
const QString &newPath, const QJsonObject &product,
|
||||||
const QJsonObject &group);
|
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);
|
static ProjectExplorer::FileType fileTypeFor(const QSet<QString> &tags);
|
||||||
|
|
||||||
|
@@ -142,6 +142,7 @@ public:
|
|||||||
QHash<QString, QStringList> generatedFilesForSources;
|
QHash<QString, QStringList> generatedFilesForSources;
|
||||||
std::optional<Error> lastError;
|
std::optional<Error> lastError;
|
||||||
State state = State::Inactive;
|
State state = State::Inactive;
|
||||||
|
int apiLevel = 0;
|
||||||
bool fileUpdatePossible = true;
|
bool fileUpdatePossible = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -259,6 +260,11 @@ QJsonObject QbsSession::projectData() const
|
|||||||
return d->projectData;
|
return d->projectData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QbsSession::apiLevel() const
|
||||||
|
{
|
||||||
|
return d->apiLevel;
|
||||||
|
}
|
||||||
|
|
||||||
void QbsSession::sendRequest(const QJsonObject &request)
|
void QbsSession::sendRequest(const QJsonObject &request)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->currentRequest.isEmpty(),
|
QTC_ASSERT(d->currentRequest.isEmpty(),
|
||||||
@@ -317,6 +323,12 @@ FileChangeResult QbsSession::removeFiles(const QStringList &files, const QString
|
|||||||
return updateFileList("remove-files", files, product, group);
|
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(
|
RunEnvironmentResult QbsSession::getRunEnvironment(
|
||||||
const QString &product,
|
const QString &product,
|
||||||
const QProcessEnvironment &baseEnv,
|
const QProcessEnvironment &baseEnv,
|
||||||
@@ -456,7 +468,8 @@ void QbsSession::handlePacket(const QJsonObject &packet)
|
|||||||
setError(Error::VersionMismatch);
|
setError(Error::VersionMismatch);
|
||||||
return;
|
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();
|
const QString lspSocket = packet.value("lsp-socket").toString();
|
||||||
if (!lspSocket.isEmpty())
|
if (!lspSocket.isEmpty())
|
||||||
d->languageClient = new QbsLanguageClient(lspSocket,
|
d->languageClient = new QbsLanguageClient(lspSocket,
|
||||||
@@ -585,14 +598,38 @@ void QbsSession::setInactive()
|
|||||||
d->languageClient = nullptr; // Owned by LanguageClientManager
|
d->languageClient = nullptr; // Owned by LanguageClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
FileChangeResult QbsSession::updateFileList(const char *action, const QStringList &files,
|
FileChangeResult QbsSession::updateFileList(
|
||||||
const QString &product, const QString &group)
|
const char *action,
|
||||||
|
const std::variant<QStringList, QList<std::pair<QString, QString>>> &files,
|
||||||
|
const QString &product,
|
||||||
|
const QString &group)
|
||||||
{
|
{
|
||||||
if (d->state != State::Active)
|
const bool filesAreStrings = std::holds_alternative<QStringList>(files);
|
||||||
return FileChangeResult(files, Tr::tr("The qbs session is not in a valid state."));
|
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{
|
const QJsonObject fileUpdateRequest{
|
||||||
{"type", QLatin1String(action)},
|
{"type", QLatin1String(action)},
|
||||||
{"files", QJsonArray::fromStringList(files)},
|
{"files", filesAsJson},
|
||||||
{"product", product},
|
{"product", product},
|
||||||
{"group", group}};
|
{"group", group}};
|
||||||
if (d->fileUpdatePossible)
|
if (d->fileUpdatePossible)
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace ProjectExplorer { class Target; }
|
namespace ProjectExplorer { class Target; }
|
||||||
|
|
||||||
@@ -114,6 +116,8 @@ public:
|
|||||||
static QString errorString(Error error);
|
static QString errorString(Error error);
|
||||||
QJsonObject projectData() const;
|
QJsonObject projectData() const;
|
||||||
|
|
||||||
|
int apiLevel() const;
|
||||||
|
|
||||||
void sendRequest(const QJsonObject &request);
|
void sendRequest(const QJsonObject &request);
|
||||||
void cancelCurrentJob();
|
void cancelCurrentJob();
|
||||||
void requestFilesGeneratedFrom(const QHash<QString, QStringList> &sourceFilesPerProduct);
|
void requestFilesGeneratedFrom(const QHash<QString, QStringList> &sourceFilesPerProduct);
|
||||||
@@ -122,6 +126,10 @@ public:
|
|||||||
const QString &group);
|
const QString &group);
|
||||||
FileChangeResult removeFiles(const QStringList &files, const QString &product,
|
FileChangeResult removeFiles(const QStringList &files, const QString &product,
|
||||||
const QString &group);
|
const QString &group);
|
||||||
|
FileChangeResult renameFiles(
|
||||||
|
const QList<std::pair<QString, QString>> &files,
|
||||||
|
const QString &product,
|
||||||
|
const QString &group);
|
||||||
RunEnvironmentResult getRunEnvironment(const QString &product,
|
RunEnvironmentResult getRunEnvironment(const QString &product,
|
||||||
const QProcessEnvironment &baseEnv,
|
const QProcessEnvironment &baseEnv,
|
||||||
const QStringList &config);
|
const QStringList &config);
|
||||||
@@ -170,8 +178,11 @@ private:
|
|||||||
void setProjectDataFromReply(const QJsonObject &packet, bool withBuildSystemFiles);
|
void setProjectDataFromReply(const QJsonObject &packet, bool withBuildSystemFiles);
|
||||||
void setError(Error error);
|
void setError(Error error);
|
||||||
void setInactive();
|
void setInactive();
|
||||||
FileChangeResult updateFileList(const char *action, const QStringList &files,
|
FileChangeResult updateFileList(
|
||||||
const QString &product, const QString &group);
|
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 handleFileListUpdated(const QJsonObject &reply);
|
||||||
void sendNextPendingFileUpdateRequest();
|
void sendNextPendingFileUpdateRequest();
|
||||||
void sendFileUpdateRequest(const QJsonObject &request);
|
void sendFileUpdateRequest(const QJsonObject &request);
|
||||||
|
Reference in New Issue
Block a user