From 4802fc3a964946d957dc2971e85e90b488eb3521 Mon Sep 17 00:00:00 2001 From: alex-z Date: Sat, 2 Mar 2024 19:16:07 +0100 Subject: [PATCH 1/2] Bugfix. Exclude list. Fix stuck 'excluded' status in Windows Explorer after removing the exclude pattern. Signed-off-by: alex-z --- src/libsync/syncengine.cpp | 1 + src/libsync/syncfilestatustracker.cpp | 13 +++++++++++++ src/libsync/syncfilestatustracker.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 4c884acdc0..e25ea716d2 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -450,6 +450,7 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item) return; } else if (item->_instruction == CSYNC_INSTRUCTION_NONE) { _hasNoneFiles = true; + _syncFileStatusTracker->slotCheckAndRemoveSilentlyExcluded(item->_file); if (_account->capabilities().uploadConflictFiles() && Utility::isConflictFile(item->_file)) { // For uploaded conflict files, files with no action performed on them should // be displayed: but we mustn't overwrite the instruction if something happens diff --git a/src/libsync/syncfilestatustracker.cpp b/src/libsync/syncfilestatustracker.cpp index e3ffca288d..67ad27ad0e 100644 --- a/src/libsync/syncfilestatustracker.cpp +++ b/src/libsync/syncfilestatustracker.cpp @@ -172,9 +172,19 @@ void SyncFileStatusTracker::slotPathTouched(const QString &fileName) void SyncFileStatusTracker::slotAddSilentlyExcluded(const QString &folderPath) { _syncProblems[folderPath] = SyncFileStatus::StatusExcluded; + _syncSilentExcludes[folderPath] = SyncFileStatus::StatusExcluded; emit fileStatusChanged(getSystemDestination(folderPath), resolveSyncAndErrorStatus(folderPath, NotShared)); } +void SyncFileStatusTracker::slotCheckAndRemoveSilentlyExcluded(const QString &folderPath) +{ + const auto foundIt = _syncSilentExcludes.find(folderPath); + if (foundIt != _syncSilentExcludes.end()) { + _syncSilentExcludes.erase(foundIt); + emit fileStatusChanged(getSystemDestination(folderPath), SyncFileStatus::StatusUpToDate); + } +} + void SyncFileStatusTracker::incSyncCountAndEmitStatusChanged(const QString &relativePath, SharedFlag sharedFlag) { // Will return 0 (and increase to 1) if the path wasn't in the map yet @@ -231,9 +241,11 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector &items) if (hasErrorStatus(*item)) { _syncProblems[item->destination()] = SyncFileStatus::StatusError; + _syncSilentExcludes.erase(item->destination()); invalidateParentPaths(item->destination()); } else if (hasExcludedStatus(*item)) { _syncProblems[item->destination()] = SyncFileStatus::StatusExcluded; + _syncSilentExcludes.erase(item->destination()); } SharedFlag sharedFlag = item->_remotePerm.hasPermission(RemotePermissions::IsShared) ? Shared : NotShared; @@ -281,6 +293,7 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItemPtr &item) } else { _syncProblems.erase(item->destination()); } + _syncSilentExcludes.erase(item->destination()); SharedFlag sharedFlag = item->_remotePerm.hasPermission(RemotePermissions::IsShared) ? Shared : NotShared; if (item->_instruction != CSYNC_INSTRUCTION_NONE diff --git a/src/libsync/syncfilestatustracker.h b/src/libsync/syncfilestatustracker.h index 83f2e459a4..06dc957834 100644 --- a/src/libsync/syncfilestatustracker.h +++ b/src/libsync/syncfilestatustracker.h @@ -42,6 +42,7 @@ public slots: void slotPathTouched(const QString &fileName); // path relative to folder void slotAddSilentlyExcluded(const QString &folderPath); + void slotCheckAndRemoveSilentlyExcluded(const QString &folderPath); signals: void fileStatusChanged(const QString &systemFileName, OCC::SyncFileStatus fileStatus); @@ -74,6 +75,7 @@ private: SyncEngine *_syncEngine; ProblemsMap _syncProblems; + ProblemsMap _syncSilentExcludes; QSet _dirtyPaths; // Counts the number direct children currently being synced (has unfinished propagation jobs). // We'll show a file/directory as SYNC as long as its sync count is > 0. From a566272b1f95f21eecb028e6db3102653369869a Mon Sep 17 00:00:00 2001 From: alex-z Date: Mon, 4 Mar 2024 16:50:10 +0100 Subject: [PATCH 2/2] Unit tests for ignorelist exclude status stuck. Signed-off-by: alex-z --- test/testsyncfilestatustracker.cpp | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/testsyncfilestatustracker.cpp b/test/testsyncfilestatustracker.cpp index 9020a98b60..13bb6c9e91 100644 --- a/test/testsyncfilestatustracker.cpp +++ b/test/testsyncfilestatustracker.cpp @@ -511,6 +511,52 @@ private slots: statusSpy.clear(); } + void silentlyExcludedFilesRemovedFromExclude() + { + FakeFolder fakeFolder{{}}; + fakeFolder.localModifier().mkdir("A"); + fakeFolder.localModifier().mkdir("A/photos"); + fakeFolder.localModifier().insert("A/photos/image.png"); + fakeFolder.localModifier().insert("A/photos/image1.png"); + fakeFolder.localModifier().insert("A/photos/image2.png"); + StatusPushSpy statusSpy(fakeFolder.syncEngine()); + + fakeFolder.scheduleSync(); + fakeFolder.execUntilFinished(); + verifyThatPushMatchesPull(fakeFolder, statusSpy); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QCOMPARE(statusSpy.statusOf("A/photos/image.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + QCOMPARE(statusSpy.statusOf("A/photos/image1.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + QCOMPARE(statusSpy.statusOf("A/photos/image2.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + statusSpy.clear(); + + // add ignore pattern for .png files and Allow to Delete + fakeFolder.syncEngine().excludedFiles().addManualExclude(QStringLiteral("]*.png")); + + // sync again and make sure .png files are ignored + fakeFolder.scheduleSync(); + fakeFolder.execUntilFinished(); + verifyThatPushMatchesPull(fakeFolder, statusSpy); + QCOMPARE(statusSpy.statusOf("A/photos/image.png"), SyncFileStatus(SyncFileStatus::StatusExcluded)); + QCOMPARE(statusSpy.statusOf("A/photos/image1.png"), SyncFileStatus(SyncFileStatus::StatusExcluded)); + QCOMPARE(statusSpy.statusOf("A/photos/image2.png"), SyncFileStatus(SyncFileStatus::StatusExcluded)); + statusSpy.clear(); + + // remove exclude for .png files + fakeFolder.syncEngine().excludedFiles().clearManualExcludes(); + fakeFolder.syncEngine().excludedFiles().reloadExcludeFiles(); + + // make sure the status is again correct + fakeFolder.scheduleSync(); + fakeFolder.execUntilFinished(); + verifyThatPushMatchesPull(fakeFolder, statusSpy); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + QCOMPARE(statusSpy.statusOf("A/photos/image.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + QCOMPARE(statusSpy.statusOf("A/photos/image1.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + QCOMPARE(statusSpy.statusOf("A/photos/image2.png"), SyncFileStatus(SyncFileStatus::StatusUpToDate)); + statusSpy.clear(); + } + }; QTEST_GUILESS_MAIN(TestSyncFileStatusTracker)