Skip to content

Commit e46eb56

Browse files
committed
scrub duplicates from groups while doing a sync
1 parent ba2d124 commit e46eb56

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

Sources/XcodeProject/Objects+Extensions/PBXGroup+FolderSync.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,30 @@ public extension PBXGroup {
4141

4242
func sync(recursive: Bool, target: PBXTarget? = nil) {
4343
let target = target ?? parentProject?.targets.first
44+
removeDuplicateFiles(recursive: recursive)
4445
addMissingFiles(recursive: recursive, target: target)
4546
removeMissingFiles(recursive: recursive)
4647
}
4748

49+
private func removeDuplicateFiles(recursive: Bool) {
50+
var seen: Set<PBXReference> = []
51+
var duplicates: [Int] = []
52+
for i in 0..<children.count {
53+
let child = children[i]
54+
if seen.contains(child) {
55+
duplicates.append(i)
56+
} else {
57+
seen.insert(child)
58+
if recursive, let group = child as? PBXGroup {
59+
group.removeDuplicateFiles(recursive: recursive)
60+
}
61+
}
62+
}
63+
duplicates.reversed().forEach {
64+
children.remove(at: $0)
65+
}
66+
}
67+
4868
private func removeMissingFiles(recursive: Bool) {
4969
var newChildren: [PBXReference] = []
5070
children.forEach {

Sources/XcodeProject/Workspace.swift

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ extension WorkspaceItem {
5656
}
5757

5858
public final class Workspace: WorkspaceReference {
59+
enum Error: Swift.Error {
60+
case invalid
61+
}
5962
let url: URL
6063
public var referenceURL: URL? { return url.deletingLastPathComponent() }
6164
public let fileWrapper: FileWrapper
@@ -83,31 +86,22 @@ public final class Workspace: WorkspaceReference {
8386
}
8487
}
8588

86-
public init?(url: URL) {
89+
public init(url: URL) throws {
8790
self.url = url
88-
do {
89-
self.fileWrapper = try FileWrapper(url: url, options: [])
90-
} catch {
91-
return nil
92-
}
91+
self.fileWrapper = try FileWrapper(url: url, options: [])
9392
if fileWrapper.isDirectory == false {
9493
//throw
9594
}
9695

97-
guard let workspaceData = fileWrapper.fileWrappers?["contents.xcworkspacedata"], workspaceData.isRegularFile else {
98-
// throw
99-
return nil
96+
guard let workspaceData = fileWrapper.fileWrappers?["contents.xcworkspacedata"], workspaceData.isRegularFile,
97+
let data = workspaceData.regularFileContents else {
98+
throw Error.invalid
10099
}
101100

102-
guard let data = workspaceData.regularFileContents else { return nil }
103-
104-
do {
105-
let document = try XMLDocument(data: data, options: [])
106-
guard let children = document.rootElement()?.children as? [XMLElement] else { return nil }
107-
self.references = children.flatMap {
108-
childOf(element: $0, parent: self)
109-
}
110-
} catch {
101+
let document = try XMLDocument(data: data, options: [])
102+
guard let children = document.rootElement()?.children as? [XMLElement] else { throw Error.invalid }
103+
self.references = children.flatMap {
104+
childOf(element: $0, parent: self)
111105
}
112106
}
113107

0 commit comments

Comments
 (0)