Skip to content

Commit e2f887b

Browse files
authored
Merge pull request #9335 from nextcloud/i2h3/fix/9682755-excluded-sync-status
Fix: File Provider Synchronization Status
2 parents c4336e7 + 36cb343 commit e2f887b

41 files changed

Lines changed: 723 additions & 440 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,56 @@
33
- SPDX-License-Identifier: GPL-2.0-or-later
44
-->
55
# Agents.md
6-
This `AGENTS.md` file provides guidelines for OpenAI Codex and other AI agents interacting with this codebase, including which directories are safe to read from or write to.
6+
7+
You are an experienced engineer specialized on C++ and Qt and familiar with the platform-specific details of Windows, macOS and Linux.
8+
9+
## Your Role
10+
11+
- You implement features and fix bugs.
12+
- Your documentation and explanations are written for less experienced contributors to ease understanding and learning.
13+
- You work on an open source project and lowering the barrier for contributors is part of your work.
714

815
## Project Overview
16+
917
The Nextcloud Desktop Client is a tool to synchronize files from Nextcloud Server with your computer.
18+
Qt, C++, CMake and KDE Craft are the key technologies used for building the app on Windows, macOS and Linux.
19+
Beyond that, there are platform-specific extensions of the multi-platform app in the `./shell_integration` directory.
1020

1121
## Project Structure: AI Agent Handling Guidelines
1222

1323
| Directory | Description | Agent Action |
1424
|-----------------|-----------------------------------------------------|----------------------|
15-
| `/translations` | Translation files from Transifex. | Do not modify |
25+
| `./admin/osx/mac-crafter` | Build tool for macOS | Ignore unless the build process must be updated |
26+
| `./shell_integration/MacOSX/NextcloudIntegration` | Xcode project for macOS app extensions | Look here first for changes in context of the file provider extension |
27+
| `./translations` | Translation files from Transifex. | Do not modify |
1628

1729
## General Guidance
1830

1931
Every new file needs to get a SPDX header in the first rows according to this template.
20-
The year needs to be adjusted accordingly. The commenting signs need to be used depending on the file type.
21-
```
22-
SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
32+
The year in the first line must be replaced with the year when the file is created (for example, 2026 for files first added in 2026).
33+
The commenting signs need to be used depending on the file type.
34+
35+
```plaintext
36+
SPDX-FileCopyrightText: <YEAR> Nextcloud GmbH and Nextcloud contributors
2337
SPDX-License-Identifier: GPL-2.0-or-later
2438
```
2539

26-
## Commit & PR Guidelines
40+
## Commit and Pull Request Guidelines
41+
2742
- **Commits**: Follow Conventional Commits format. Use `feat: ...`, `fix: ...`, or `refactor: ...` as appropriate in the commit message prefix.
2843
- Include a short summary of what changed. *Example:* `fix: prevent crash on empty todo title`.
2944
- **Pull Request**: When the agent creates a PR, it should include a description summarizing the changes and why they were made. If a GitHub issue exists, reference it (e.g., “Closes #123”).
45+
46+
## macOS Specifics
47+
48+
The following details are important when working on the desktop client on macOS.
49+
50+
- Latest stable Xcode available is required to be installed in the development environment.
51+
- There is a self-contained and independent build tool called mac-crafter in `./admin/osx/mac-crafter` implemented as a Swift package which builds as an executable.
52+
- To enable a macOS app build, the file `./shell_integration/MacOSX/NextcloudIntegration/NextcloudDev/Build.xcconfig` must be created if not existent already and it must contain the Xcode build setting `CODE_SIGN_IDENTITY=Apple Development`.
53+
- To verify that the project builds successfully on macOS, mac-crafter can be run in its own directory with these arguments: `swift run mac-crafter --build-path=DerivedData --product-path=/Applications --build-type=Debug --dev --disable-auto-updater --build-file-provider-module`
54+
- The macOS app includes a FinderSync extension.
55+
- The macOS app can be built to include a file provider extension and file provider UI extension.
56+
- The macOS extensions bundled with the main app are built in the Xcode project in `./shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj`. The build system later copies the built extension bundles into the main app bundle on its own. The Xcode project does not build the main app.
57+
- The main app manages file provider domains and the communication with them via XPC in source code files located in `./src/gui/macOS` and usually are written in Objective-C++ (implementation files with `.mm` extension, sometimes having a `_mac` suffix in their name while their corresponding header files do not). The PIMPL pattern is an established convention here.
58+
- When writing code in Swift, respect strict concurrency rules and Swift 6 compatibility.

shell_integration/MacOSX/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ if(APPLE)
5656
endif()
5757

5858
if (BUILD_OWNCLOUD_OSX_BUNDLE)
59+
# Set debug entitlements conditionally based on build type
60+
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
61+
set(DEBUG_ENTITLEMENTS "\t<key>com.apple.security.get-task-allow</key>\n\t<true/>")
62+
else()
63+
set(DEBUG_ENTITLEMENTS "")
64+
endif()
65+
5966
set(OSX_PLUGINS_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${XCODE_TARGET_CONFIGURATION})
6067
set(OSX_PLUGINS_INSTALL_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/PlugIns)
6168

shell_integration/MacOSX/FileProviderExt.entitlements.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
<true/>
1313
<key>com.apple.security.network.server</key>
1414
<true/>
15+
@DEBUG_ENTITLEMENTS@
1516
</dict>
1617
</plist>

shell_integration/MacOSX/FileProviderUIExt.entitlements.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
<true/>
1313
<key>com.apple.security.network.server</key>
1414
<true/>
15+
@DEBUG_ENTITLEMENTS@
1516
</dict>
1617
</plist>

shell_integration/MacOSX/FinderSyncExt.entitlements.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
<array>
99
<string>@DEVELOPMENT_TEAM@.@APPLICATION_REV_DOMAIN@</string>
1010
</array>
11+
@DEBUG_ENTITLEMENTS@
1112
</dict>
1213
</plist>

shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Utilities/IgnoredFilesMatcher.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import Foundation
55

66
public class IgnoredFilesMatcher {
7+
private let logger: FileProviderLogger
78
private let regexes: [NSRegularExpression]
89

910
private static func patternToRegex(_ pattern: String, wildcardsMatchSlash: Bool) -> String {
@@ -42,7 +43,10 @@ public class IgnoredFilesMatcher {
4243
return hasSlash ? "^\(regex)$" : "(^|/)" + regex + "$"
4344
}
4445

45-
public init(ignoreList: [String], wildcardsMatchSlash: Bool = false) {
46+
public init(ignoreList: [String], wildcardsMatchSlash: Bool = false, log: any FileProviderLogging) {
47+
logger = FileProviderLogger(category: "IgnoredFilesMatcher", log: log)
48+
logger.debug("Initializing with ignore list:\n\n\(ignoreList.map { "- \"\($0)\"" }.joined(separator: "\n"))")
49+
4650
regexes = ignoreList
4751
.map { Self.patternToRegex($0, wildcardsMatchSlash: wildcardsMatchSlash) }
4852
.compactMap { try? NSRegularExpression(pattern: $0, options: [.caseInsensitive]) }

shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/IgnoredFilesMatcherTests.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: LGPL-3.0-or-later
33

44
@testable import NextcloudFileProviderKit
5+
import NextcloudFileProviderKitMocks
56
import Testing
67

78
struct IgnoredFilesMatcherTests {
@@ -14,7 +15,7 @@ struct IgnoredFilesMatcherTests {
1415
"deep/**"
1516
]
1617

17-
let matcher = IgnoredFilesMatcher(ignoreList: patterns)
18+
let matcher = IgnoredFilesMatcher(ignoreList: patterns, log: FileProviderLogMock())
1819

1920
#expect(matcher.isExcluded("foo.tmp"))
2021
#expect(matcher.isExcluded("a/b/c/hello.tmp"))

shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/ItemCreateTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ final class ItemCreateTests: NextcloudFileProviderKitTestCase {
524524
}
525525

526526
func testCreateDoesNotPropagateIgnoredFile() async throws {
527-
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.tmp", "/build/"])
527+
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.tmp", "/build/"], log: FileProviderLogMock())
528528
let remoteInterface = MockRemoteInterface(account: Self.account, rootItem: rootItem)
529529

530530
// We'll create a file that matches the ignored pattern

shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/ItemDeleteTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ final class ItemDeleteTests: NextcloudFileProviderKitTestCase {
162162
}
163163

164164
func testDeleteDoesNotPropagateIgnoredFile() async throws {
165-
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.log", "/tmp/"])
165+
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.log", "/tmp/"], log: FileProviderLogMock())
166166
let metadata = SendableItemMetadata(
167167
ocId: "ignored-file-id",
168168
fileName: "debug.log",

shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/ItemModifyTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ final class ItemModifyTests: NextcloudFileProviderKitTestCase {
13241324
}
13251325

13261326
func testModifyDoesNotPropagateIgnoredFile() async throws {
1327-
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.bak", "/logs/"])
1327+
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["*.bak", "/logs/"], log: FileProviderLogMock())
13281328
let metadata = SendableItemMetadata(
13291329
ocId: "ignored-modify-id",
13301330
fileName: "error.bak",
@@ -1355,7 +1355,7 @@ final class ItemModifyTests: NextcloudFileProviderKitTestCase {
13551355

13561356
func testModifyCreatesFileThatWasPreviouslyIgnoredWithContentsUrlProvided() async throws {
13571357
let remoteInterface = MockRemoteInterface(account: Self.account, rootItem: rootItem)
1358-
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["/logs/"])
1358+
let ignoredMatcher = IgnoredFilesMatcher(ignoreList: ["/logs/"], log: FileProviderLogMock())
13591359

13601360
let tempFileName = UUID().uuidString
13611361
let tempUrl = FileManager.default.temporaryDirectory.appendingPathComponent(tempFileName)

0 commit comments

Comments
 (0)