Skip to content

Commit df19638

Browse files
committed
duplicate version architecture changes
1 parent 9393832 commit df19638

4 files changed

Lines changed: 53 additions & 3 deletions

File tree

Sources/XcodesKit/Services/XcodeListPresentationService.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ public struct XcodeListPresentationService: Sendable {
4141
)
4242
: availableXcodes)
4343
.matchingArchitectureFilters(architectures)
44+
let visibleAvailableXcodes = XcodeListService.filteringPrereleasesWithDuplicateBuildMetadata(adjustedAvailableXcodes)
4445

4546
let adjustedInstalledXcodes = architectures.isEmpty
4647
? installedXcodes
4748
: installedXcodes.filter { architectures.matches($0.xcodeID.architectures) }
4849

49-
var releasedVersions = adjustedAvailableXcodes.map {
50+
var releasedVersions = visibleAvailableXcodes.map {
5051
ReleasedVersion(version: $0.version, releaseDate: $0.releaseDate, architectures: $0.architectures)
5152
}
5253

Sources/XcodesKit/Services/XcodeListService.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,14 @@ public struct XcodeListService: Sendable {
195195
$0.version.buildMetadataIdentifiers == availableXcode.version.buildMetadataIdentifiers
196196
}
197197

198+
let releaseWithSameBuildAndArchitecture = availableXcodesWithIdenticalBuildIdentifiers.contains {
199+
$0.version.prereleaseIdentifiers.isEmpty &&
200+
$0.architectures == availableXcode.architectures
201+
}
202+
198203
return availableXcodesWithIdenticalBuildIdentifiers.count == 1 ||
199204
availableXcodesWithIdenticalBuildIdentifiers.count > 1 &&
200-
(availableXcode.version.prereleaseIdentifiers.isEmpty || availableXcode.architectures?.isEmpty == false)
205+
(availableXcode.version.prereleaseIdentifiers.isEmpty || !releaseWithSameBuildAndArchitecture)
201206
}
202207
}
203208

Tests/XcodesKitTests/ArchitectureFilteringTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ final class ArchitectureFilteringTests: XCTestCase {
5252
])
5353
}
5454

55+
func testXcodeListPresentationServiceFiltersPrereleaseWithSameBuildAndArchitecture() throws {
56+
let release = availableXcode("26.5.0+17F42", filename: "Xcode-26.5-arm64.xip", architectures: [.arm64])
57+
let prerelease = availableXcode("26.5.0-Release.Candidate+17F42", filename: "Xcode-26.5-rc-arm64.xip", architectures: [.arm64])
58+
59+
let rows = XcodeListPresentationService().availableRows(
60+
availableXcodes: [release, prerelease],
61+
installedXcodes: [],
62+
selectedXcodePath: nil,
63+
dataSource: .xcodeReleases,
64+
architectures: [.variant(.appleSilicon)]
65+
)
66+
67+
XCTAssertEqual(rows.map(\.version), [release.version])
68+
XCTAssertEqual(rows.map(\.versionDescription), [
69+
"26.5 (17F42) [Apple Silicon]"
70+
])
71+
}
72+
5573
func testArchitectureFiltersParseRawArchitecturesAndVariants() {
5674
XCTAssertEqual(ArchitectureFilter("arm64"), .architecture(.arm64))
5775
XCTAssertEqual(ArchitectureFilter("x86_64"), .architecture(.x86_64))

Tests/XcodesKitTests/XcodesKitTests.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ final class XcodesKitTests: XCTestCase {
10761076
])
10771077
}
10781078

1079-
func testXcodeListServiceKeepsArchitectureSpecificPrereleaseWithDuplicateBuildMetadata() throws {
1079+
func testXcodeListServiceKeepsArchitectureSpecificPrereleaseWithDuplicateBuildMetadataWhenReleaseHasNoArchitecture() throws {
10801080
let release = AvailableXcode(
10811081
version: try XCTUnwrap(Version("16.0.0+16A1")),
10821082
url: try XCTUnwrap(URL(string: "https://apple.com/xcode.xip")),
@@ -1102,6 +1102,32 @@ final class XcodesKitTests: XCTestCase {
11021102
])
11031103
}
11041104

1105+
func testXcodeListServiceFiltersArchitectureSpecificPrereleaseWhenReleaseHasSameArchitecture() throws {
1106+
let release = AvailableXcode(
1107+
version: try XCTUnwrap(Version("26.5.0+17F42")),
1108+
url: try XCTUnwrap(URL(string: "https://apple.com/xcode-arm64.xip")),
1109+
filename: "mock-arm64.xip",
1110+
releaseDate: nil,
1111+
architectures: [.arm64]
1112+
)
1113+
let prerelease = AvailableXcode(
1114+
version: try XCTUnwrap(Version("26.5.0-Release.Candidate+17F42")),
1115+
url: try XCTUnwrap(URL(string: "https://apple.com/xcode-rc-arm64.xip")),
1116+
filename: "mock-rc-arm64.xip",
1117+
releaseDate: nil,
1118+
architectures: [.arm64]
1119+
)
1120+
1121+
let filtered = XcodeListService.filteringPrereleasesWithDuplicateBuildMetadata([
1122+
release,
1123+
prerelease
1124+
])
1125+
1126+
XCTAssertEqual(filtered.map(\.xcodeID), [
1127+
release.xcodeID
1128+
])
1129+
}
1130+
11051131
func testXcodeListServiceFiltersIdenticalBuildsToMatchingArchitectureVariant() throws {
11061132
let universalRelease = AvailableXcode(
11071133
version: try XCTUnwrap(Version("26.5.0+17F42")),

0 commit comments

Comments
 (0)