Skip to content

Commit c9c08b7

Browse files
authored
Report an error when detecting duplicate updates in generate_appcast (#2407)
1 parent 7c8fe1d commit c9c08b7

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

generate_appcast/Unarchive.swift

+31-7
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ func unarchiveUpdates(archivesSourceDir: URL, archivesDestDir: URL, disableNeste
5252

5353
let fileManager = FileManager.default
5454

55-
var unarchived: [ArchiveItem] = []
56-
55+
// Create a dictionary of archive destination directories -> archive source path
56+
// so we can ignore duplicate archive entries before trying to unarchive archives in parallel
57+
var fileEntries: [URL: URL] = [:]
5758
let dir = try fileManager.contentsOfDirectory(atPath: archivesSourceDir.path)
58-
var running = 0
5959
for item in dir.filter({ !$0.hasPrefix(".") && !$0.hasSuffix(".delta") && !$0.hasSuffix(".xml") && !$0.hasSuffix(".html") && !$0.hasSuffix(".txt") }) {
6060
let itemPath = archivesSourceDir.appendingPathComponent(item)
61+
62+
// Ignore directories
6163
var isDir: ObjCBool = false
6264
if fileManager.fileExists(atPath: itemPath.path, isDirectory: &isDir) && isDir.boolValue {
6365
continue
@@ -69,18 +71,36 @@ func unarchiveUpdates(archivesSourceDir: URL, archivesDestDir: URL, disableNeste
6971
} else {
7072
archiveDestDir = archivesDestDir.appendingPathComponent(itemPath.lastPathComponent)
7173
}
72-
74+
75+
// Ignore duplicate archives
76+
if let existingItemPath = fileEntries[archiveDestDir] {
77+
throw makeError(code: .appcastError, "Duplicate update archives are not supported. Found '\(existingItemPath.lastPathComponent)' and '\(itemPath.lastPathComponent)'. Please remove one of them from the appcast generation directory.")
78+
}
79+
80+
fileEntries[archiveDestDir] = itemPath
81+
}
82+
83+
var unarchived: [String: ArchiveItem] = [:]
84+
var updateParseError: Error? = nil
85+
86+
var running = 0
87+
for (archiveDestDir, itemPath) in fileEntries {
7388
let addItem = { (validateBundle: Bool) in
7489
do {
7590
let item = try ArchiveItem(fromArchive: itemPath, unarchivedDir: archiveDestDir, validateBundle: validateBundle, disableNestedCodeCheck: disableNestedCodeCheck)
7691
if verbose {
7792
print("Found archive", item)
7893
}
7994
objc_sync_enter(unarchived)
80-
unarchived.append(item)
95+
// Make sure different archives don't contain the same update too
96+
if let existingArchive = unarchived[item.version] {
97+
updateParseError = makeError(code: .appcastError, "Duplicate updates are not supported. Found archives '\(existingArchive.archivePath.lastPathComponent)' and '\(itemPath.lastPathComponent)' which contain the same bundle version. Please remove one of these archives from the appcast generation directory.")
98+
} else {
99+
unarchived[item.version] = item
100+
}
81101
objc_sync_exit(unarchived)
82102
} catch {
83-
print("Skipped", item, error)
103+
print("Skipped", itemPath.lastPathComponent, error)
84104
}
85105
}
86106

@@ -107,6 +127,10 @@ func unarchiveUpdates(archivesSourceDir: URL, archivesDestDir: URL, disableNeste
107127
}
108128

109129
group.wait()
130+
131+
if let updateParseError = updateParseError {
132+
throw updateParseError
133+
}
110134

111-
return unarchived
135+
return Array(unarchived.values)
112136
}

0 commit comments

Comments
 (0)