Skip to content

Commit 4fdc6fe

Browse files
committed
Move SDK configuration to SwiftSDKConfigurationStore and add tests
1 parent 72fb717 commit 4fdc6fe

File tree

5 files changed

+286
-220
lines changed

5 files changed

+286
-220
lines changed

Sources/PackageModel/SwiftSDKs/SwiftSDK.swift

Lines changed: 100 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,14 @@ public struct SwiftSDK: Equatable {
266266
/// deserialization.
267267
public private(set) var toolset: Toolset
268268

269-
public struct PathsConfiguration: Equatable {
269+
public struct PathsConfiguration<Path: Equatable>: Equatable {
270270
public init(
271-
sdkRootPath: Basics.AbsolutePath?,
272-
swiftResourcesPath: Basics.AbsolutePath? = nil,
273-
swiftStaticResourcesPath: Basics.AbsolutePath? = nil,
274-
includeSearchPaths: [Basics.AbsolutePath]? = nil,
275-
librarySearchPaths: [Basics.AbsolutePath]? = nil,
276-
toolsetPaths: [Basics.AbsolutePath]? = nil
271+
sdkRootPath: Path? = nil,
272+
swiftResourcesPath: Path? = nil,
273+
swiftStaticResourcesPath: Path? = nil,
274+
includeSearchPaths: [Path]? = nil,
275+
librarySearchPaths: [Path]? = nil,
276+
toolsetPaths: [Path]? = nil
277277
) {
278278
self.sdkRootPath = sdkRootPath
279279
self.swiftResourcesPath = swiftResourcesPath
@@ -284,22 +284,22 @@ public struct SwiftSDK: Equatable {
284284
}
285285

286286
/// Root directory path of the SDK used to compile for the target triple.
287-
public var sdkRootPath: Basics.AbsolutePath?
287+
public var sdkRootPath: Path?
288288

289289
/// Path containing Swift resources for dynamic linking.
290-
public var swiftResourcesPath: Basics.AbsolutePath?
290+
public var swiftResourcesPath: Path?
291291

292292
/// Path containing Swift resources for static linking.
293-
public var swiftStaticResourcesPath: Basics.AbsolutePath?
293+
public var swiftStaticResourcesPath: Path?
294294

295295
/// Array of paths containing headers.
296-
public var includeSearchPaths: [Basics.AbsolutePath]?
296+
public var includeSearchPaths: [Path]?
297297

298298
/// Array of paths containing libraries.
299-
public var librarySearchPaths: [Basics.AbsolutePath]?
299+
public var librarySearchPaths: [Path]?
300300

301301
/// Array of paths containing toolset files.
302-
public var toolsetPaths: [Basics.AbsolutePath]?
302+
public var toolsetPaths: [Path]?
303303

304304
/// Initialize paths configuration from values deserialized using v3 schema.
305305
/// - Parameters:
@@ -308,92 +308,50 @@ public struct SwiftSDK: Equatable {
308308
fileprivate init(
309309
_ properties: SerializedDestinationV3.TripleProperties,
310310
swiftSDKDirectory: Basics.AbsolutePath? = nil
311-
) throws {
312-
if let swiftSDKDirectory {
313-
self.init(
314-
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: swiftSDKDirectory),
315-
swiftResourcesPath: try properties.swiftResourcesPath.map {
316-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
317-
},
318-
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
319-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
320-
},
321-
includeSearchPaths: try properties.includeSearchPaths?.map {
322-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
323-
},
324-
librarySearchPaths: try properties.librarySearchPaths?.map {
325-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
326-
},
327-
toolsetPaths: try properties.toolsetPaths?.map {
328-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
329-
}
330-
)
331-
} else {
332-
self.init(
333-
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath),
334-
swiftResourcesPath: try properties.swiftResourcesPath.map {
335-
try AbsolutePath(validating: $0)
336-
},
337-
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
338-
try AbsolutePath(validating: $0)
339-
},
340-
includeSearchPaths: try properties.includeSearchPaths?.map {
341-
try AbsolutePath(validating: $0)
342-
},
343-
librarySearchPaths: try properties.librarySearchPaths?.map {
344-
try AbsolutePath(validating: $0)
345-
},
346-
toolsetPaths: try properties.toolsetPaths?.map {
347-
try AbsolutePath(validating: $0)
348-
}
349-
)
350-
}
311+
) throws where Path == Basics.AbsolutePath {
312+
self.init(
313+
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: swiftSDKDirectory),
314+
swiftResourcesPath: try properties.swiftResourcesPath.map {
315+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
316+
},
317+
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
318+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
319+
},
320+
includeSearchPaths: try properties.includeSearchPaths?.map {
321+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
322+
},
323+
librarySearchPaths: try properties.librarySearchPaths?.map {
324+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
325+
},
326+
toolsetPaths: try properties.toolsetPaths?.map {
327+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
328+
}
329+
)
351330
}
352331

353332
/// Initialize paths configuration from values deserialized using v4 schema.
354333
/// - Parameters:
355334
/// - properties: properties of a Swift SDK for the given triple.
356335
/// - swiftSDKDirectory: directory used for converting relative paths in `properties` to absolute paths.
357-
fileprivate init(_ properties: SwiftSDKMetadataV4.TripleProperties, swiftSDKDirectory: Basics.AbsolutePath? = nil) throws {
358-
if let swiftSDKDirectory {
359-
self.init(
360-
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: swiftSDKDirectory),
361-
swiftResourcesPath: try properties.swiftResourcesPath.map {
362-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
363-
},
364-
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
365-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
366-
},
367-
includeSearchPaths: try properties.includeSearchPaths?.map {
368-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
369-
},
370-
librarySearchPaths: try properties.librarySearchPaths?.map {
371-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
372-
},
373-
toolsetPaths: try properties.toolsetPaths?.map {
374-
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
375-
}
376-
)
377-
} else {
378-
self.init(
379-
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath),
380-
swiftResourcesPath: try properties.swiftResourcesPath.map {
381-
try AbsolutePath(validating: $0)
382-
},
383-
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
384-
try AbsolutePath(validating: $0)
385-
},
386-
includeSearchPaths: try properties.includeSearchPaths?.map {
387-
try AbsolutePath(validating: $0)
388-
},
389-
librarySearchPaths: try properties.librarySearchPaths?.map {
390-
try AbsolutePath(validating: $0)
391-
},
392-
toolsetPaths: try properties.toolsetPaths?.map {
393-
try AbsolutePath(validating: $0)
394-
}
395-
)
396-
}
336+
fileprivate init(_ properties: SwiftSDKMetadataV4.TripleProperties, swiftSDKDirectory: Basics.AbsolutePath? = nil) throws where Path == Basics.AbsolutePath {
337+
self.init(
338+
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: swiftSDKDirectory),
339+
swiftResourcesPath: try properties.swiftResourcesPath.map {
340+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
341+
},
342+
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
343+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
344+
},
345+
includeSearchPaths: try properties.includeSearchPaths?.map {
346+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
347+
},
348+
librarySearchPaths: try properties.librarySearchPaths?.map {
349+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
350+
},
351+
toolsetPaths: try properties.toolsetPaths?.map {
352+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
353+
}
354+
)
397355
}
398356

399357
public mutating func merge(with newConfiguration: Self) {
@@ -421,10 +379,45 @@ public struct SwiftSDK: Equatable {
421379
self.toolsetPaths = toolsetPaths
422380
}
423381
}
382+
383+
public mutating func merge(with newConfiguration: PathsConfiguration<String>, relativeTo basePath: Path?) throws -> [String] where Path == Basics.AbsolutePath {
384+
var updatedProperties: [String] = []
385+
if let sdkRootPath = newConfiguration.sdkRootPath {
386+
self.sdkRootPath = try AbsolutePath(validating: sdkRootPath, relativeTo: basePath)
387+
updatedProperties.append("sdkRootPath")
388+
}
389+
390+
if let swiftResourcesPath = newConfiguration.swiftResourcesPath {
391+
self.swiftResourcesPath = try AbsolutePath(validating: swiftResourcesPath, relativeTo: basePath)
392+
updatedProperties.append("swiftResourcesPath")
393+
}
394+
395+
if let swiftStaticResourcesPath = newConfiguration.swiftStaticResourcesPath {
396+
self.swiftResourcesPath = try AbsolutePath(validating: swiftStaticResourcesPath, relativeTo: basePath)
397+
updatedProperties.append("swiftStaticResourcesPath")
398+
}
399+
400+
if let includeSearchPaths = newConfiguration.includeSearchPaths, !includeSearchPaths.isEmpty {
401+
self.includeSearchPaths = try includeSearchPaths.map { try AbsolutePath(validating: $0, relativeTo: basePath) }
402+
updatedProperties.append("includeSearchPath")
403+
}
404+
405+
if let librarySearchPaths = newConfiguration.librarySearchPaths, !librarySearchPaths.isEmpty {
406+
self.librarySearchPaths = try librarySearchPaths.map { try AbsolutePath(validating: $0, relativeTo: basePath) }
407+
updatedProperties.append("librarySearchPath")
408+
}
409+
410+
if let toolsetPaths = newConfiguration.toolsetPaths, !toolsetPaths.isEmpty {
411+
self.toolsetPaths = try toolsetPaths.map { try AbsolutePath(validating: $0, relativeTo: basePath) }
412+
updatedProperties.append("toolsetPath")
413+
}
414+
415+
return updatedProperties
416+
}
424417
}
425418

426419
/// Configuration of file system paths used by this Swift SDK when building.
427-
public var pathsConfiguration: PathsConfiguration
420+
public var pathsConfiguration: PathsConfiguration<Basics.AbsolutePath>
428421

429422
/// Creates a Swift SDK with the specified properties.
430423
@available(*, deprecated, message: "use `init(targetTriple:sdkRootDir:toolset:)` instead")
@@ -471,7 +464,7 @@ public struct SwiftSDK: Equatable {
471464
hostTriple: Triple? = nil,
472465
targetTriple: Triple? = nil,
473466
toolset: Toolset,
474-
pathsConfiguration: PathsConfiguration,
467+
pathsConfiguration: PathsConfiguration<Basics.AbsolutePath>,
475468
supportsTesting: Bool
476469
) {
477470
let xctestSupport: XCTestSupport
@@ -496,7 +489,7 @@ public struct SwiftSDK: Equatable {
496489
hostTriple: Triple? = nil,
497490
targetTriple: Triple? = nil,
498491
toolset: Toolset,
499-
pathsConfiguration: PathsConfiguration,
492+
pathsConfiguration: PathsConfiguration<Basics.AbsolutePath>,
500493
xctestSupport: XCTestSupport = .supported
501494
) {
502495
self.hostTriple = hostTriple
@@ -1208,7 +1201,7 @@ extension Optional where Wrapped == [Basics.AbsolutePath] {
12081201
}
12091202
}
12101203

1211-
extension SwiftSDK.PathsConfiguration: CustomStringConvertible {
1204+
extension SwiftSDK.PathsConfiguration: CustomStringConvertible where Path == Basics.AbsolutePath {
12121205
public var description: String {
12131206
"""
12141207
sdkRootPath: \(sdkRootPath.configurationString)
@@ -1220,3 +1213,13 @@ extension SwiftSDK.PathsConfiguration: CustomStringConvertible {
12201213
"""
12211214
}
12221215
}
1216+
1217+
extension Basics.AbsolutePath {
1218+
fileprivate init(validating string: String, relativeTo basePath: Basics.AbsolutePath?) throws {
1219+
if let basePath {
1220+
try self.init(validating: string, relativeTo: basePath)
1221+
} else {
1222+
try self.init(validating: string)
1223+
}
1224+
}
1225+
}

Sources/PackageModel/SwiftSDKs/SwiftSDKBundleStore.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public final class SwiftSDKBundleStore {
7070
let fileSystem: any FileSystem
7171

7272
/// Observability scope used for logging.
73-
private let observabilityScope: ObservabilityScope
73+
let observabilityScope: ObservabilityScope
7474

7575
/// Closure invoked for output produced by this store during its operation.
7676
private let outputHandler: (Output) -> Void

Sources/PackageModel/SwiftSDKs/SwiftSDKConfigurationStore.swift

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,92 @@ public final class SwiftSDKConfigurationStore {
157157
try fileSystem.removeFileTree(configurationPath)
158158
return true
159159
}
160+
161+
public func configure(
162+
sdkID: String,
163+
targetTriple: String?,
164+
showConfiguration: Bool,
165+
resetConfiguration: Bool,
166+
config: SwiftSDK.PathsConfiguration<String>
167+
) throws -> Bool {
168+
let targetTriples: [Triple]
169+
if let targetTriple = targetTriple {
170+
targetTriples = try [Triple(targetTriple)]
171+
} else {
172+
// when target-triple is unspecified, configure every triple for the SDK
173+
let validBundles = try self.swiftSDKs(for: sdkID)
174+
targetTriples = validBundles.compactMap(\.targetTriple)
175+
if targetTriples.isEmpty {
176+
throw SwiftSDKError.swiftSDKNotFound(
177+
artifactID: sdkID,
178+
hostTriple: hostTriple,
179+
targetTriple: nil
180+
)
181+
}
182+
}
183+
184+
for targetTriple in targetTriples {
185+
guard let swiftSDK = try self.readConfiguration(
186+
sdkID: sdkID,
187+
targetTriple: targetTriple
188+
) else {
189+
throw SwiftSDKError.swiftSDKNotFound(
190+
artifactID: sdkID,
191+
hostTriple: hostTriple,
192+
targetTriple: targetTriple
193+
)
194+
}
195+
196+
if showConfiguration {
197+
print(swiftSDK.pathsConfiguration)
198+
continue
199+
}
200+
201+
if resetConfiguration {
202+
if try !self.resetConfiguration(sdkID: sdkID, targetTriple: targetTriple) {
203+
swiftSDKBundleStore.observabilityScope.emit(
204+
warning: "No configuration for Swift SDK `\(sdkID)`"
205+
)
206+
} else {
207+
swiftSDKBundleStore.observabilityScope.emit(
208+
info: """
209+
All configuration properties of Swift SDK `\(sdkID)` for target triple \
210+
`\(targetTriple)` were successfully reset.
211+
"""
212+
)
213+
}
214+
} else {
215+
var configuration = swiftSDK.pathsConfiguration
216+
let updatedProperties = try configuration.merge(with: config, relativeTo: fileSystem.currentWorkingDirectory)
217+
218+
guard !updatedProperties.isEmpty else {
219+
swiftSDKBundleStore.observabilityScope.emit(
220+
error: """
221+
No properties of Swift SDK `\(sdkID)` for target triple `\(targetTriple)` were updated \
222+
since none were specified. Pass `--help` flag to see the list of all available properties.
223+
"""
224+
)
225+
return false
226+
}
227+
228+
var swiftSDK = swiftSDK
229+
swiftSDK.pathsConfiguration = configuration
230+
swiftSDK.targetTriple = targetTriple
231+
try self.updateConfiguration(sdkID: sdkID, swiftSDK: swiftSDK)
232+
233+
swiftSDKBundleStore.observabilityScope.emit(
234+
info: """
235+
These properties of Swift SDK `\(sdkID)` for target triple \
236+
`\(targetTriple)` were successfully updated: \(updatedProperties.joined(separator: ", ")).
237+
"""
238+
)
239+
}
240+
241+
if swiftSDKBundleStore.observabilityScope.errorsReported {
242+
return false
243+
}
244+
}
245+
246+
return true
247+
}
160248
}

0 commit comments

Comments
 (0)