From 89dac600a9caea6033ac12c73e0da0ed1edf544d Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 24 May 2023 20:00:16 +0800 Subject: [PATCH 1/6] Add macOS related configs to craftmaster.ini Signed-off-by: Claudio Cambra --- craftmaster.ini | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/craftmaster.ini b/craftmaster.ini index da7d7f5c902fc..095286a8686fa 100644 --- a/craftmaster.ini +++ b/craftmaster.ini @@ -15,6 +15,8 @@ CreateCache = False # Category is case sensitive [GeneralSettings] +General/MacDeploymentTarget = 10.15 + ## This is the location of your python installation. ## This value must be set. Paths/Python = C:\Python39-x64 @@ -42,6 +44,13 @@ Packager/UseCache = ${Variables:UseCache} Packager/CreateCache = ${Variables:CreateCache} Packager/CacheDir = ${Variables:Root}\cache +#CodeSigning/Enabled = ${Env:SIGN_PACKAGE} +#CodeSigning/Protected = True +#CodeSigning/Certificate = ${Env:CRAFT_CODESIGN_CERTIFICATE} +#CodeSigning/CommonName = +#CodeSigning/MacDeveloperId = ownCloud GmbH (4AP2STM4H5) +#CodeSigning/MacKeychainPath = sign-${Env:DRONE_BUILD_NUMBER}.keychain + [BlueprintSettings] # don't try to pip install on the ci python-modules.ignored = True @@ -53,3 +62,22 @@ binary/mysql.useMariaDB = False [windows-msvc2019_64-cl] QtSDK/Compiler = msvc2019_64 General/ABI = windows-msvc2019_64-cl + +[macos-64-clang] +General/ABI = macos-64-clang +# Packager/PackageType = MacPkgPackager + +[macos-64-clang-debug] +General/ABI = macos-64-clang +Compile/BuildType = Debug + +[macos-clang-arm64] +General/ABI = macos-clang-arm64 + +[macos-clang-arm64-debug] +General/ABI = macos-clang-arm64 +Compile/BuildType = Debug + +[Env] +CRAFT_CODESIGN_CERTIFICATE = +SIGN_PACKAGE = False \ No newline at end of file From 04a7bae03787d30b01d425f1eb4487f1da3627db Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 24 May 2023 15:40:52 +0800 Subject: [PATCH 2/6] Add macOS workflow Signed-off-by: Claudio Cambra Fetch inkscape for client build in macOS workflow Signed-off-by: Claudio Cambra --- .github/workflows/macos-build-and-test.yml | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/macos-build-and-test.yml diff --git a/.github/workflows/macos-build-and-test.yml b/.github/workflows/macos-build-and-test.yml new file mode 100644 index 0000000000000..13286bd985071 --- /dev/null +++ b/.github/workflows/macos-build-and-test.yml @@ -0,0 +1,54 @@ +name: macOS Build and Test +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] +jobs: + build: + name: Build + runs-on: macos-latest + env: + CRAFT_TARGET: macos-64-clang + CRAFT_MASTER_LOCATION: ${{ github.workspace }}/CraftMaster + CRAFT_MASTER_CONFIG: ${{ github.workspace }}/craftmaster.ini + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 1 + + - name: Restore cache + uses: actions/cache@v2 + with: + path: ~/cache + key: macos-latest-${{ env.CRAFT_TARGET }} + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: 3.9 + + - name: Install Homebrew dependencies + run: | + brew install inkscape + + - name: Download Craft + run: | + git clone -q --depth=1 https://invent.kde.org/packaging/craftmaster.git ${{ env.CRAFT_MASTER_LOCATION }} + + - name: Add Nextcloud client blueprints + run: | + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --add-blueprint-repository https://github.com/nextcloud/desktop-client-blueprints.git + + - name: Setup Craft + run: | + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c craft + + - name: Install Craft Nextcloud client dependencies + run: | + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --install-deps nextcloud-client + + - name: Build Client + run: | + python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --src-dir ${{ github.workspace }} nextcloud-client From b543a504e642f443c6741cbf7d1975a6b2b2c4b5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 25 May 2023 19:10:41 +0800 Subject: [PATCH 3/6] Add test run to macOS CI Signed-off-by: Claudio Cambra --- .github/workflows/macos-build-and-test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/macos-build-and-test.yml b/.github/workflows/macos-build-and-test.yml index 13286bd985071..a1bbe8d25b882 100644 --- a/.github/workflows/macos-build-and-test.yml +++ b/.github/workflows/macos-build-and-test.yml @@ -49,6 +49,12 @@ jobs: run: | python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --install-deps nextcloud-client - - name: Build Client + - name: Build client run: | python "${{ env.CRAFT_MASTER_LOCATION }}/CraftMaster.py" --config "${{ env.CRAFT_MASTER_CONFIG }}" --target ${{ env.CRAFT_TARGET }} -c --src-dir ${{ github.workspace }} nextcloud-client + + - name: Run tests + run: | + cd ${{ github.workspace }}/${{ env.CRAFT_TARGET }}/build/nextcloud-client/work/build + ctest --output-on-failure --output-junit testResult.xml + From e9c4bdcfe93d5c24388fb97c848eb17ce18c6bc6 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 18 Sep 2023 11:31:20 +0800 Subject: [PATCH 4/6] Ensure that full rescan flags in macOS folder watcher reply are properly responded to Signed-off-by: Claudio Cambra --- src/gui/folderwatcher_mac.cpp | 34 ++++++++++++++++++++++++++++++---- src/gui/folderwatcher_mac.h | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/gui/folderwatcher_mac.cpp b/src/gui/folderwatcher_mac.cpp index fcce031cdaf66..576d37067496a 100644 --- a/src/gui/folderwatcher_mac.cpp +++ b/src/gui/folderwatcher_mac.cpp @@ -48,18 +48,31 @@ static void callback( const FSEventStreamEventId eventIds[]) { Q_UNUSED(streamRef) - Q_UNUSED(eventFlags) Q_UNUSED(eventIds) - const FSEventStreamEventFlags c_interestingFlags = kFSEventStreamEventFlagItemCreated // for new folder/file + qCDebug(lcFolderWatcher) << "FolderWatcherPrivate::callback by OS X"; + + // These flags indicate that either due to system error or for unknown reasons, the entire + // directory structure must be rescanned (including files) + const auto c_fullScanFlags = kFSEventStreamEventFlagMustScanSubDirs + | kFSEventStreamEventFlagKernelDropped + | kFSEventStreamEventFlagUserDropped; + + for (int i = 0; i < static_cast(numEvents); ++i) { + const auto flag = eventFlags[i]; + if (flag & c_fullScanFlags) { + reinterpret_cast(clientCallBackInfo)->notifyAll(); + return; + } + } + + const auto c_interestingFlags = kFSEventStreamEventFlagItemCreated // for new folder/file | kFSEventStreamEventFlagItemRemoved // for rm | kFSEventStreamEventFlagItemInodeMetaMod // for mtime change | kFSEventStreamEventFlagItemRenamed // also coming for moves to trash in finder | kFSEventStreamEventFlagItemModified; // for content change //We ignore other flags, e.g. for owner change, xattr change, Finder label change etc - qCDebug(lcFolderWatcher) << "FolderWatcherPrivate::callback by OS X"; - QStringList paths; CFArrayRef eventPaths = (CFArrayRef)eventPathsVoid; for (int i = 0; i < static_cast(numEvents); ++i) { @@ -128,5 +141,18 @@ void FolderWatcherPrivate::doNotifyParent(const QStringList &paths) _parent->changeDetected(totalPaths); } +void FolderWatcherPrivate::notifyAll() +{ + QDirIterator dirIterator(_folder, QDirIterator::Subdirectories); + QStringList allPaths; + + while(dirIterator.hasNext()) { + const auto dirEntry = dirIterator.next(); + allPaths.append(dirEntry); + } + + _parent->changeDetected(allPaths); +} + } // ns mirall diff --git a/src/gui/folderwatcher_mac.h b/src/gui/folderwatcher_mac.h index e68124f824326..b2d9eaa40452d 100644 --- a/src/gui/folderwatcher_mac.h +++ b/src/gui/folderwatcher_mac.h @@ -36,6 +36,7 @@ class FolderWatcherPrivate void startWatching(); QStringList addCoalescedPaths(const QStringList &) const; void doNotifyParent(const QStringList &); + void notifyAll(); /// On OSX the watcher is ready when the ctor finished. bool _ready = true; From 2488fd64600518b325427c6f57c8830fe00e0b23 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 18 Sep 2023 11:32:09 +0800 Subject: [PATCH 5/6] Make sure to respond to cloned item event flags in mac folder watcher Signed-off-by: Claudio Cambra --- src/gui/folderwatcher_mac.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/folderwatcher_mac.cpp b/src/gui/folderwatcher_mac.cpp index 576d37067496a..d81ae22169ea6 100644 --- a/src/gui/folderwatcher_mac.cpp +++ b/src/gui/folderwatcher_mac.cpp @@ -70,7 +70,8 @@ static void callback( | kFSEventStreamEventFlagItemRemoved // for rm | kFSEventStreamEventFlagItemInodeMetaMod // for mtime change | kFSEventStreamEventFlagItemRenamed // also coming for moves to trash in finder - | kFSEventStreamEventFlagItemModified; // for content change + | kFSEventStreamEventFlagItemModified // for content change + | kFSEventStreamEventFlagItemCloned; // for cloned items (since 10.13) //We ignore other flags, e.g. for owner change, xattr change, Finder label change etc QStringList paths; From 00f464ca92cf62bb4b838728a40559c6d7b53a48 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 18 Sep 2023 11:32:55 +0800 Subject: [PATCH 6/6] Fix files being skipped in coalesced path traersal in mac folder watcher Signed-off-by: Claudio Cambra --- src/gui/folderwatcher_mac.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/folderwatcher_mac.cpp b/src/gui/folderwatcher_mac.cpp index d81ae22169ea6..588b94a27b561 100644 --- a/src/gui/folderwatcher_mac.cpp +++ b/src/gui/folderwatcher_mac.cpp @@ -124,11 +124,11 @@ QStringList FolderWatcherPrivate::addCoalescedPaths(const QStringList &paths) co QStringList coalescedPaths; for (const auto &eventPath : paths) { if (QDir(eventPath).exists()) { - QDirIterator it(eventPath, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDirIterator it(eventPath, QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { - auto subfolder = it.next(); - if (!paths.contains(subfolder)) { - coalescedPaths.append(subfolder); + const auto path = it.next(); + if (!paths.contains(path)) { + coalescedPaths.append(path); } } }