Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions Sources/PackageModel/SwiftSDKBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,30 +79,30 @@ public struct SwiftSDKBundle {
/// - observabilityScope: observability scope to log warnings about multiple matches.
/// - Returns: `Destination` value matching `query` either by artifact ID or target triple, `nil` if none found.
public static func selectBundle(
fromBundlesAt destinationsDirectory: AbsolutePath?,
fromBundlesAt swiftSDKsDirectory: AbsolutePath?,
fileSystem: FileSystem,
matching selector: String,
hostTriple: Triple,
observabilityScope: ObservabilityScope
) throws -> Destination {
guard let destinationsDirectory = destinationsDirectory else {
guard let swiftSDKsDirectory else {
throw StringError(
"""
No directory found for installed Swift SDKs, specify one
No directory found for installed Swift SDKs, specify one \
with `--experimental-swift-sdks-path` option.
"""
)
}

let validBundles = try SwiftSDKBundle.getAllValidBundles(
swiftSDKsDirectory: destinationsDirectory,
swiftSDKsDirectory: swiftSDKsDirectory,
fileSystem: fileSystem,
observabilityScope: observabilityScope
)

guard !validBundles.isEmpty else {
throw StringError(
"No valid Swift SDK bundles found at \(destinationsDirectory)."
"No valid Swift SDK bundles found at \(swiftSDKsDirectory)."
)
}

Expand All @@ -113,8 +113,8 @@ public struct SwiftSDKBundle {
) else {
throw StringError(
"""
No Swift SDK found matching query `\(selector)` and host triple
`\(hostTriple.tripleString)`. Use `swift experimental-sdk list` command to see
No Swift SDK found matching query `\(selector)` and host triple \
`\(hostTriple.tripleString)`. Use `swift experimental-sdk list` command to see \
available destinations.
"""
)
Expand Down Expand Up @@ -434,7 +434,22 @@ extension [SwiftSDKBundle] {
for bundle in self {
for (artifactID, variants) in bundle.artifacts {
for variant in variants {
guard variant.metadata.supportedTriples.contains(hostTriple) else {
guard variant.metadata.supportedTriples.contains(where: { variantTriple in
if
hostTriple.arch == variantTriple.arch &&
hostTriple.vendor == variantTriple.vendor &&
hostTriple.os == variantTriple.os &&
hostTriple.environment == variantTriple.environment
{
if let hostOSVersion = hostTriple.osVersion, let variantOSVersion = variantTriple.osVersion {
return hostOSVersion >= variantOSVersion
} else {
return true
}
} else {
return false
}
}) else {
continue
}

Expand Down
119 changes: 89 additions & 30 deletions Tests/PackageModelTests/SwiftSDKBundleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import PackageModel
@testable import PackageModel
import SPMTestSupport
import XCTest

Expand All @@ -22,27 +22,58 @@ import class TSCBasic.InMemoryFileSystem

private let testArtifactID = "test-artifact"

private func generateInfoJSON(artifacts: [MockArtifact]) -> String {
"""
{
"artifacts" : {
\(artifacts.map {
"""
"\($0.id)" : {
"type" : "swiftSDK",
"version" : "0.0.1",
"variants" : [
{
"path" : "\($0.id)/aarch64-unknown-linux",
"supportedTriples" : \($0.supportedTriples.map(\.tripleString))
private let targetTriple = try! Triple("aarch64-unknown-linux")

private let jsonEncoder = JSONEncoder()

private func generateBundleFiles(bundle: MockBundle) throws -> [(String, ByteString)] {
try [
(
"\(bundle.path)/info.json",
ByteString("""
{
"artifacts" : {
\(bundle.artifacts.map {
"""
"\($0.id)" : {
"type" : "swiftSDK",
"version" : "0.0.1",
"variants" : [
{
"path" : "\($0.id)/\(targetTriple.triple)",
"supportedTriples" : \($0.supportedTriples.map(\.tripleString))
}
]
}
]
}
"""
}.joined(separator: ",\n")
)
},
"schemaVersion" : "1.0"
"""
}.joined(separator: ",\n")
)
},
"schemaVersion" : "1.0"
}
""".utf8)
),

] + bundle.artifacts.map {
(
"\(bundle.path)/\($0.id)/\(targetTriple.tripleString)/swift-sdk.json",
ByteString(try generateSwiftSDKMetadata(jsonEncoder).utf8)
)
}
}

private func generateSwiftSDKMetadata(_ encoder: JSONEncoder) throws -> String {
try """
{
"schemaVersion": "4.0",
"targetTriples": \(
String(
bytes: encoder.encode([
targetTriple.tripleString: SwiftSDKMetadataV4.TripleProperties(sdkRootPath: "sdk")
]),
encoding: .utf8
)!
)
}
"""
}
Expand All @@ -64,15 +95,13 @@ private func generateTestFileSystem(bundleArtifacts: [MockArtifact]) throws -> (
return MockBundle(name: "test\(i).artifactbundle", path: "/\(bundleName)", artifacts: [artifacts])
}

let fileSystem = InMemoryFileSystem(
files: Dictionary(uniqueKeysWithValues: bundles.map {
(
"\($0.path)/info.json",
ByteString(
encodingAsUTF8: generateInfoJSON(artifacts: $0.artifacts)
)
)
})

let fileSystem = try InMemoryFileSystem(
files: Dictionary(
uniqueKeysWithValues: bundles.flatMap {
try generateBundleFiles(bundle: $0)
}
)
)

let swiftSDKsDirectory = try AbsolutePath(validating: "/sdks")
Expand Down Expand Up @@ -209,4 +238,34 @@ final class SwiftSDKBundleTests: XCTestCase {

XCTAssertEqual(validBundles.count, bundles.count)
}

func testBundleSelection() async throws {
let (fileSystem, bundles, swiftSDKsDirectory) = try generateTestFileSystem(
bundleArtifacts: [
.init(id: "\(testArtifactID)1", supportedTriples: [arm64Triple]),
.init(id: "\(testArtifactID)2", supportedTriples: [i686Triple])
]
)
let system = ObservabilitySystem.makeForTesting()

for bundle in bundles {
try SwiftSDKBundle.install(
bundlePathOrURL: bundle.path,
swiftSDKsDirectory: swiftSDKsDirectory,
fileSystem,
MockArchiver(),
system.topScope
)
}

let sdk = try SwiftSDKBundle.selectBundle(
fromBundlesAt: swiftSDKsDirectory,
fileSystem: fileSystem,
matching: "\(testArtifactID)1",
hostTriple: Triple("arm64-apple-macosx14.0"),
observabilityScope: system.topScope
)

XCTAssertEqual(sdk.targetTriple, targetTriple)
}
}