Skip to content

Commit 1356e5a

Browse files
authored
Merge pull request #783 from owenv/owenv/toolchain-id-lookup
Add a method to lookup the identifier of a registered toolchain
2 parents 1a2b65d + 7714d29 commit 1356e5a

File tree

6 files changed

+103
-4
lines changed

6 files changed

+103
-4
lines changed

Sources/SWBBuildService/Messages.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,14 @@ private struct SetSessionUserPreferencesMsg: MessageHandler {
302302
}
303303
}
304304

305+
private struct LookupToolchainMsg: MessageHandler {
306+
func handle(request: Request, message: LookupToolchainRequest) throws -> LookupToolchainResponse {
307+
let session = try request.session(for: message)
308+
let toolchain = try session.core.toolchainRegistry.lookup(path: message.path)
309+
return LookupToolchainResponse(toolchainIdentifier: toolchain?.identifier)
310+
}
311+
}
312+
305313
/// Start a PIF transfer from the client.
306314
///
307315
/// This will establish a workspace context in the relevant session by exchanging a PIF from the client to the service incrementally, only transferring subobjects as necessary.
@@ -1543,6 +1551,7 @@ public struct ServiceSessionMessageHandlers: ServiceExtension {
15431551
service.registerMessageHandler(SetSessionUserInfoMsg.self)
15441552
service.registerMessageHandler(SetSessionUserPreferencesMsg.self)
15451553
service.registerMessageHandler(DeveloperPathHandler.self)
1554+
service.registerMessageHandler(LookupToolchainMsg.self)
15461555
}
15471556
}
15481557

Sources/SWBCore/ToolchainRegistry.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,16 @@ public final class ToolchainRegistry: @unchecked Sendable {
540540
}
541541
}
542542

543+
public func lookup(path: Path) throws -> Toolchain? {
544+
let path = try self.fs.realpath(path)
545+
for toolchain in toolchains {
546+
if try self.fs.realpath(toolchain.path) == path {
547+
return toolchain
548+
}
549+
}
550+
return nil
551+
}
552+
543553
public var defaultToolchain: Toolchain? {
544554
return self.lookup("default")
545555
}

Sources/SWBProtocol/Message.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,31 @@ public struct SetSessionUserPreferencesRequest: SessionMessage, RequestMessage,
632632
}
633633
}
634634

635+
public struct LookupToolchainRequest: SessionMessage, RequestMessage, Equatable, SerializableCodable {
636+
public typealias ResponseMessage = LookupToolchainResponse
637+
638+
public static let name = "LOOKUP_TOOLCHAIN"
639+
640+
public let sessionHandle: String
641+
642+
public let path: Path
643+
644+
public init(sessionHandle: String, path: Path) {
645+
self.sessionHandle = sessionHandle
646+
self.path = path
647+
}
648+
}
649+
650+
public struct LookupToolchainResponse: Message, Equatable, SerializableCodable {
651+
public static let name = "LOOKUP_TOOLCHAIN_RESPONSE"
652+
653+
public let toolchainIdentifier: String?
654+
655+
public init(toolchainIdentifier: String?) {
656+
self.toolchainIdentifier = toolchainIdentifier
657+
}
658+
}
659+
635660
public struct ListSessionsRequest: RequestMessage, Equatable {
636661
public typealias ResponseMessage = ListSessionsResponse
637662

@@ -1176,6 +1201,8 @@ public struct IPCMessage: Serializable, Sendable {
11761201
SetSessionSystemInfoRequest.self,
11771202
SetSessionUserInfoRequest.self,
11781203
SetSessionUserPreferencesRequest.self,
1204+
LookupToolchainRequest.self,
1205+
LookupToolchainResponse.self,
11791206
ListSessionsRequest.self,
11801207
ListSessionsResponse.self,
11811208
WaitForQuiescenceRequest.self,

Sources/SwiftBuild/SWBBuildServiceSession.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,14 @@ public final class SWBBuildServiceSession: Sendable {
629629
public func setUserPreferences(enableDebugActivityLogs: Bool, enableBuildDebugging: Bool, enableBuildSystemCaching: Bool, activityTextShorteningLevel: Int, usePerConfigurationBuildLocations: Bool?, allowsExternalToolExecution: Bool) async throws {
630630
_ = try await service.send(request: SetSessionUserPreferencesRequest(sessionHandle: self.uid, enableDebugActivityLogs: enableDebugActivityLogs, enableBuildDebugging: enableBuildDebugging, enableBuildSystemCaching: enableBuildSystemCaching, activityTextShorteningLevel: ActivityTextShorteningLevel(rawValue: activityTextShorteningLevel) ?? .default, usePerConfigurationBuildLocations: usePerConfigurationBuildLocations, allowsExternalToolExecution: allowsExternalToolExecution))
631631
}
632+
633+
public func lookupToolchain(at path: String) async throws -> SWBToolchainIdentifier? {
634+
return try await service.send(request: LookupToolchainRequest(sessionHandle: self.uid, path: Path(path))).toolchainIdentifier.map { SWBToolchainIdentifier(rawValue: $0) }
635+
}
636+
}
637+
638+
public struct SWBToolchainIdentifier {
639+
public var rawValue: String
632640
}
633641

634642
extension SWBBuildServiceSession {

Sources/SwiftBuildTestSupport/TestUtilities.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ package actor TestSWBSession {
3737
package nonisolated let sessionDiagnostics: [SwiftBuildMessage.DiagnosticInfo]
3838
private var closed = false
3939

40-
package init(connectionMode: SWBBuildServiceConnectionMode = .default, variant: SWBBuildServiceVariant = .default, temporaryDirectory: NamedTemporaryDirectory?) async throws {
40+
package init(connectionMode: SWBBuildServiceConnectionMode = .default, variant: SWBBuildServiceVariant = .default, temporaryDirectory: NamedTemporaryDirectory?, environment: [String: String] = [:]) async throws {
4141
self.tmpDir = try temporaryDirectory ?? NamedTemporaryDirectory()
4242
// Construct the test session.
4343
self.service = try await SWBBuildService(connectionMode: connectionMode, variant: variant)
44-
let (result, sessionDiagnostics) = await service.createSession(name: #function, cachePath: tmpDir.path.str)
44+
let (result, sessionDiagnostics) = await service.createSession(name: #function, cachePath: tmpDir.path.str, environment: environment)
4545
self.sessionDiagnostics = sessionDiagnostics
4646
do {
4747
self.session = try result.get()
@@ -203,8 +203,8 @@ extension SWBRunDestinationInfo: _RunDestinationInfo {
203203

204204
extension SWBBuildService {
205205
/// Overload of `createSession` which supplies an inferior products path.
206-
package func createSession(name: String, developerPath: String? = nil, cachePath: String?) async -> (Result<SWBBuildServiceSession, any Error>, [SwiftBuildMessage.DiagnosticInfo]) {
207-
return await createSession(name: name, developerPath: developerPath, cachePath: cachePath, inferiorProductsPath: Core.inferiorProductsPath()?.str, environment: [:])
206+
package func createSession(name: String, developerPath: String? = nil, cachePath: String?, environment: [String:String] = [:]) async -> (Result<SWBBuildServiceSession, any Error>, [SwiftBuildMessage.DiagnosticInfo]) {
207+
return await createSession(name: name, developerPath: developerPath, cachePath: cachePath, inferiorProductsPath: Core.inferiorProductsPath()?.str, environment: environment)
208208
}
209209
}
210210

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import struct Foundation.UUID
14+
15+
import SwiftBuild
16+
import SwiftBuildTestSupport
17+
18+
import SWBCore
19+
import SWBTestSupport
20+
@_spi(Testing) import SWBUtil
21+
22+
import Testing
23+
24+
@Suite
25+
fileprivate struct ToolchainTests: CoreBasedTests {
26+
@Test(.skipIfEnvironmentVariableSet(key: .externalToolchainsDir))
27+
func toolchainLookupByPath() async throws {
28+
try await withTemporaryDirectory { (temporaryDirectory: NamedTemporaryDirectory) in
29+
let tmpDir = temporaryDirectory.path
30+
try await withAsyncDeferrable { deferrable in
31+
try localFS.createDirectory(tmpDir.join("toolchain.xctoolchain"))
32+
try await localFS.writePlist(tmpDir.join("toolchain.xctoolchain/Info.plist"), .plDict(["Identifier": "com.foo.bar"]))
33+
let testSession = try await TestSWBSession(temporaryDirectory: temporaryDirectory, environment: ["EXTERNAL_TOOLCHAINS_DIR": tmpDir.str])
34+
await deferrable.addBlock {
35+
await #expect(throws: Never.self) {
36+
try await testSession.close()
37+
}
38+
}
39+
40+
let id = try await testSession.session.lookupToolchain(at: tmpDir.join("toolchain.xctoolchain").str)
41+
#expect(id?.rawValue == "com.foo.bar")
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)