Skip to content

Commit a0e7a8a

Browse files
[5.10] Fix non-tarballed SDK installation with remote URL (#7312) (#7321)
* **Explanation**: 4714ea9 introduced a regression where non-tarball SDKs could not be installed from a remote URL due to the wrong assumption that the downloaded file would always be a tarball. * **Scope**: Experimental Swift SDK installation * **Risk**: Low, only affects to `swift experimental-sdk` command, which is still experimental. Also doesn't impact other binaries or SwiftPM clients/libraries. * **Testing**: Some new unit tests are added in this change. * **Reviewer**: @MaxDesiatov * **Main branch PR**: #7312
1 parent 0ec3473 commit a0e7a8a

File tree

3 files changed

+43
-34
lines changed

3 files changed

+43
-34
lines changed
1.03 KB
Binary file not shown.

Sources/PackageModel/SwiftSDKs/SwiftSDKBundleStore.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,10 @@ public final class SwiftSDKBundleStore {
151151
{
152152
let bundleName: String
153153
let fileNameComponent = bundleURL.lastPathComponent
154-
if fileNameComponent.hasSuffix(".tar.gz") {
154+
if archiver.supportedExtensions.contains(where: { fileNameComponent.hasSuffix($0) }) {
155155
bundleName = fileNameComponent
156156
} else {
157+
// Assume that the bundle is a tarball if it doesn't have a recognized extension.
157158
bundleName = "bundle.tar.gz"
158159
}
159160
let downloadedBundlePath = temporaryDirectory.appending(component: bundleName)

Tests/PackageModelTests/SwiftSDKBundleTests.swift

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ private func generateTestFileSystem(bundleArtifacts: [MockArtifact]) throws -> (
113113
private let arm64Triple = try! Triple("arm64-apple-macosx13.0")
114114
private let i686Triple = try! Triple("i686-apple-macosx13.0")
115115

116-
private let fixtureArchivePath = try! AbsolutePath(validating: #file)
116+
private let fixtureSDKsPath = try! AbsolutePath(validating: #file)
117117
.parentDirectory
118118
.parentDirectory
119119
.parentDirectory
120-
.appending(components: ["Fixtures", "SwiftSDKs", "test-sdk.artifactbundle.tar.gz"])
120+
.appending(components: ["Fixtures", "SwiftSDKs"])
121121

122122
final class SwiftSDKBundleTests: XCTestCase {
123123
func testInstallRemote() async throws {
@@ -126,43 +126,51 @@ final class SwiftSDKBundleTests: XCTestCase {
126126
#endif
127127

128128
let system = ObservabilitySystem.makeForTesting()
129-
var output = [SwiftSDKBundleStore.Output]()
130129
let observabilityScope = system.topScope
131130
let cancellator = Cancellator(observabilityScope: observabilityScope)
132131
let archiver = UniversalArchiver(localFileSystem, cancellator)
133132

134-
let httpClient = HTTPClient { request, _ in
135-
guard case let .download(_, downloadPath) = request.kind else {
136-
XCTFail("Unexpected HTTPClient.Request.Kind")
137-
return .init(statusCode: 400)
133+
let fixtureAndURLs: [(url: String, fixture: String)] = [
134+
("https://localhost/archive?test=foo", "test-sdk.artifactbundle.tar.gz"),
135+
("https://localhost/archive.tar.gz", "test-sdk.artifactbundle.tar.gz"),
136+
("https://localhost/archive.zip", "test-sdk.artifactbundle.zip"),
137+
]
138+
139+
for (bundleURLString, fixture) in fixtureAndURLs {
140+
let httpClient = HTTPClient { request, _ in
141+
guard case let .download(_, downloadPath) = request.kind else {
142+
XCTFail("Unexpected HTTPClient.Request.Kind")
143+
return .init(statusCode: 400)
144+
}
145+
let fixturePath = fixtureSDKsPath.appending(component: fixture)
146+
try localFileSystem.copy(from: fixturePath, to: downloadPath)
147+
return .init(statusCode: 200)
138148
}
139-
try localFileSystem.copy(from: fixtureArchivePath, to: downloadPath)
140-
return .init(statusCode: 200)
141-
}
142149

143-
try await withTemporaryDirectory(fileSystem: localFileSystem, removeTreeOnDeinit: true) { tmpDir in
144-
let store = SwiftSDKBundleStore(
145-
swiftSDKsDirectory: tmpDir,
146-
fileSystem: localFileSystem,
147-
observabilityScope: observabilityScope,
148-
outputHandler: {
149-
output.append($0)
150-
}
151-
)
152-
let bundleURLString = "https://localhost/archive?test=foo"
153-
try await store.install(bundlePathOrURL: bundleURLString, archiver, httpClient)
154-
155-
let bundleURL = URL(string: bundleURLString)!
156-
XCTAssertEqual(output, [
157-
.downloadStarted(bundleURL),
158-
.downloadFinishedSuccessfully(bundleURL),
159-
.unpackingArchive(bundlePathOrURL: bundleURLString),
160-
.installationSuccessful(
161-
bundlePathOrURL: bundleURLString,
162-
bundleName: "test-sdk.artifactbundle"
163-
),
164-
])
165-
}.value
150+
try await withTemporaryDirectory(fileSystem: localFileSystem, removeTreeOnDeinit: true) { tmpDir in
151+
var output = [SwiftSDKBundleStore.Output]()
152+
let store = SwiftSDKBundleStore(
153+
swiftSDKsDirectory: tmpDir,
154+
fileSystem: localFileSystem,
155+
observabilityScope: observabilityScope,
156+
outputHandler: {
157+
output.append($0)
158+
}
159+
)
160+
try await store.install(bundlePathOrURL: bundleURLString, archiver, httpClient)
161+
162+
let bundleURL = URL(string: bundleURLString)!
163+
XCTAssertEqual(output, [
164+
.downloadStarted(bundleURL),
165+
.downloadFinishedSuccessfully(bundleURL),
166+
.unpackingArchive(bundlePathOrURL: bundleURLString),
167+
.installationSuccessful(
168+
bundlePathOrURL: bundleURLString,
169+
bundleName: "test-sdk.artifactbundle"
170+
),
171+
])
172+
}.value
173+
}
166174
}
167175

168176
func testInstall() async throws {

0 commit comments

Comments
 (0)