Skip to content

Commit 22c2493

Browse files
authored
Implement destination.json schema v3.0 (#6186)
This brings the implementation in line with changes proposed in swiftlang/swift-evolution#1942.
1 parent d733140 commit 22c2493

File tree

12 files changed

+748
-284
lines changed

12 files changed

+748
-284
lines changed

.swiftformat

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@
4040
## Rules
4141

4242
# Prefer `&&` over `,` comma in `if`, `guard` or `while` conditions.
43-
--disable andOperator
43+
# Preserve `nil` default value (Optional `var`s are `nil` by default).
44+
--disable andOperator,redundantNilInit

Sources/CoreCommands/SwiftTool.swift

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,22 @@ public struct ToolWorkspaceConfiguration {
5454
let wantsMultipleTestProducts: Bool
5555
let wantsREPLProduct: Bool
5656

57-
public init(wantsMultipleTestProducts: Bool = false,
58-
wantsREPLProduct: Bool = false)
59-
{
57+
public init(
58+
wantsMultipleTestProducts: Bool = false,
59+
wantsREPLProduct: Bool = false
60+
) {
6061
self.wantsMultipleTestProducts = wantsMultipleTestProducts
6162
self.wantsREPLProduct = wantsREPLProduct
6263
}
6364
}
6465

65-
public typealias WorkspaceDelegateProvider = (_ observabilityScope: ObservabilityScope, _ outputHandler: @escaping (String, Bool) -> Void, _ progressHandler: @escaping (Int64, Int64, String?) -> Void) -> WorkspaceDelegate
66-
public typealias WorkspaceLoaderProvider = (_ fileSystem: FileSystem, _ observabilityScope: ObservabilityScope) -> WorkspaceLoader
66+
public typealias WorkspaceDelegateProvider = (
67+
_ observabilityScope: ObservabilityScope,
68+
_ outputHandler: @escaping (String, Bool) -> Void,
69+
_ progressHandler: @escaping (Int64, Int64, String?) -> Void
70+
) -> WorkspaceDelegate
71+
public typealias WorkspaceLoaderProvider = (_ fileSystem: FileSystem, _ observabilityScope: ObservabilityScope)
72+
-> WorkspaceLoader
6773

6874
public protocol SwiftCommand: ParsableCommand {
6975
var globalOptions: GlobalOptions { get }
@@ -105,7 +111,7 @@ extension SwiftCommand {
105111
public static var _errorLabel: String { "error" }
106112

107113
public var toolWorkspaceConfiguration: ToolWorkspaceConfiguration {
108-
return .init()
114+
.init()
109115
}
110116
}
111117

@@ -137,7 +143,8 @@ public final class SwiftTool {
137143
let packages: [AbsolutePath]
138144

139145
if let workspace = options.locations.multirootPackageDataFile {
140-
packages = try self.workspaceLoaderProvider(self.fileSystem, self.observabilityScope).load(workspace: workspace)
146+
packages = try self.workspaceLoaderProvider(self.fileSystem, self.observabilityScope)
147+
.load(workspace: workspace)
141148
} else {
142149
packages = [try getPackageRoot()]
143150
}
@@ -201,17 +208,34 @@ public final class SwiftTool {
201208
/// Create an instance of this tool.
202209
///
203210
/// - parameter options: The command line options to be passed to this tool.
204-
public convenience init(options: GlobalOptions, toolWorkspaceConfiguration: ToolWorkspaceConfiguration = .init(), workspaceDelegateProvider: @escaping WorkspaceDelegateProvider, workspaceLoaderProvider: @escaping WorkspaceLoaderProvider) throws {
211+
public convenience init(
212+
options: GlobalOptions,
213+
toolWorkspaceConfiguration: ToolWorkspaceConfiguration = .init(),
214+
workspaceDelegateProvider: @escaping WorkspaceDelegateProvider,
215+
workspaceLoaderProvider: @escaping WorkspaceLoaderProvider
216+
) throws {
205217
// output from background activities goes to stderr, this includes diagnostics and output from build operations,
206218
// package resolution that take place as part of another action
207219
// CLI commands that have user facing output, use stdout directly to emit the final result
208220
// this means that the build output from "swift build" goes to stdout
209221
// but the build output from "swift test" goes to stderr, while the tests output go to stdout
210-
try self.init(outputStream: TSCBasic.stderrStream, options: options, toolWorkspaceConfiguration: toolWorkspaceConfiguration, workspaceDelegateProvider: workspaceDelegateProvider, workspaceLoaderProvider: workspaceLoaderProvider)
222+
try self.init(
223+
outputStream: TSCBasic.stderrStream,
224+
options: options,
225+
toolWorkspaceConfiguration: toolWorkspaceConfiguration,
226+
workspaceDelegateProvider: workspaceDelegateProvider,
227+
workspaceLoaderProvider: workspaceLoaderProvider
228+
)
211229
}
212230

213231
// marked internal for testing
214-
internal init(outputStream: OutputByteStream, options: GlobalOptions, toolWorkspaceConfiguration: ToolWorkspaceConfiguration, workspaceDelegateProvider: @escaping WorkspaceDelegateProvider, workspaceLoaderProvider: @escaping WorkspaceLoaderProvider) throws {
232+
internal init(
233+
outputStream: OutputByteStream,
234+
options: GlobalOptions,
235+
toolWorkspaceConfiguration: ToolWorkspaceConfiguration,
236+
workspaceDelegateProvider: @escaping WorkspaceDelegateProvider,
237+
workspaceLoaderProvider: @escaping WorkspaceLoaderProvider
238+
) throws {
215239
self.fileSystem = localFileSystem
216240
// first, bootstrap the observability system
217241
self.logLevel = options.logging.logLevel
@@ -283,7 +307,8 @@ public final class SwiftTool {
283307
var action = sigaction()
284308
action.__sigaction_handler = unsafeBitCast(
285309
SIG_DFL,
286-
to: sigaction.__Unnamed_union___sigaction_handler.self)
310+
to: sigaction.__Unnamed_union___sigaction_handler.self
311+
)
287312
sigaction(SIGINT, &action, nil)
288313
kill(getpid(), SIGINT)
289314
#endif
@@ -308,11 +333,15 @@ public final class SwiftTool {
308333

309334
// make sure common directories are created
310335
self.sharedSecurityDirectory = try getSharedSecurityDirectory(options: options, fileSystem: fileSystem)
311-
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(options: options, fileSystem: fileSystem)
312-
self.sharedCacheDirectory = try getSharedCacheDirectory(options: options, fileSystem: fileSystem)
313-
self.sharedCrossCompilationDestinationsDirectory = try fileSystem.getSharedCrossCompilationDestinationsDirectory(
314-
explicitDirectory: options.locations.crossCompilationDestinationsDirectory
336+
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(
337+
options: options,
338+
fileSystem: fileSystem
315339
)
340+
self.sharedCacheDirectory = try getSharedCacheDirectory(options: options, fileSystem: fileSystem)
341+
self.sharedCrossCompilationDestinationsDirectory = try fileSystem
342+
.getSharedCrossCompilationDestinationsDirectory(
343+
explicitDirectory: options.locations.crossCompilationDestinationsDirectory
344+
)
316345

317346
// set global process logging handler
318347
Process.loggingHandler = { self.observabilityScope.emit(debug: $0) }
@@ -334,12 +363,18 @@ public final class SwiftTool {
334363
// --enable-test-discovery should never be called on darwin based platforms
335364
#if canImport(Darwin)
336365
if options.build.enableTestDiscovery {
337-
observabilityScope.emit(warning: "'--enable-test-discovery' option is deprecated; tests are automatically discovered on all platforms")
366+
observabilityScope
367+
.emit(
368+
warning: "'--enable-test-discovery' option is deprecated; tests are automatically discovered on all platforms"
369+
)
338370
}
339371
#endif
340372

341373
if options.caching.shouldDisableManifestCaching {
342-
observabilityScope.emit(warning: "'--disable-package-manifest-caching' option is deprecated; use '--manifest-caching' instead")
374+
observabilityScope
375+
.emit(
376+
warning: "'--disable-package-manifest-caching' option is deprecated; use '--manifest-caching' instead"
377+
)
343378
}
344379

345380
if let _ = options.security.netrcFilePath, options.security.netrc == false {
@@ -357,7 +392,11 @@ public final class SwiftTool {
357392
return workspace
358393
}
359394

360-
let delegate = self.workspaceDelegateProvider(self.observabilityScope, self.observabilityHandler.print, self.observabilityHandler.progress)
395+
let delegate = self.workspaceDelegateProvider(
396+
self.observabilityScope,
397+
self.observabilityHandler.print,
398+
self.observabilityHandler.progress
399+
)
361400
let isXcodeBuildSystemEnabled = self.options.build.buildSystem == .xcode
362401
let workspace = try Workspace(
363402
fileSystem: self.fileSystem,
@@ -417,13 +456,25 @@ public final class SwiftTool {
417456
if let multiRootPackageDataFile = options.locations.multirootPackageDataFile {
418457
// migrate from legacy location
419458
let legacyPath = multiRootPackageDataFile.appending(components: "xcshareddata", "swiftpm", "config")
420-
let newPath = Workspace.DefaultLocations.mirrorsConfigurationFile(at: multiRootPackageDataFile.appending(components: "xcshareddata", "swiftpm", "configuration"))
421-
return try Workspace.migrateMirrorsConfiguration(from: legacyPath, to: newPath, observabilityScope: observabilityScope)
459+
let newPath = Workspace.DefaultLocations
460+
.mirrorsConfigurationFile(
461+
at: multiRootPackageDataFile
462+
.appending(components: "xcshareddata", "swiftpm", "configuration")
463+
)
464+
return try Workspace.migrateMirrorsConfiguration(
465+
from: legacyPath,
466+
to: newPath,
467+
observabilityScope: observabilityScope
468+
)
422469
} else {
423470
// migrate from legacy location
424471
let legacyPath = try self.getPackageRoot().appending(components: ".swiftpm", "config")
425472
let newPath = try Workspace.DefaultLocations.mirrorsConfigurationFile(forRootPackage: self.getPackageRoot())
426-
return try Workspace.migrateMirrorsConfiguration(from: legacyPath, to: newPath, observabilityScope: observabilityScope)
473+
return try Workspace.migrateMirrorsConfiguration(
474+
from: legacyPath,
475+
to: newPath,
476+
observabilityScope: observabilityScope
477+
)
427478
}
428479
}
429480

@@ -441,7 +492,10 @@ public final class SwiftTool {
441492
authorization.keychain = self.options.security.keychain ? .enabled : .disabled
442493
#endif
443494

444-
return try authorization.makeAuthorizationProvider(fileSystem: self.fileSystem, observabilityScope: self.observabilityScope)
495+
return try authorization.makeAuthorizationProvider(
496+
fileSystem: self.fileSystem,
497+
observabilityScope: self.observabilityScope
498+
)
445499
}
446500

447501
public func getRegistryAuthorizationProvider() throws -> AuthorizationProvider? {
@@ -457,7 +511,10 @@ public final class SwiftTool {
457511
authorization.keychain = self.options.security.forceNetrc ? .disabled : .enabled
458512
#endif
459513

460-
return try authorization.makeRegistryAuthorizationProvider(fileSystem: self.fileSystem, observabilityScope: self.observabilityScope)
514+
return try authorization.makeRegistryAuthorizationProvider(
515+
fileSystem: self.fileSystem,
516+
observabilityScope: self.observabilityScope
517+
)
461518
}
462519

463520
/// Resolve the dependencies.
@@ -481,7 +538,8 @@ public final class SwiftTool {
481538
/// Fetch and load the complete package graph.
482539
///
483540
/// - Parameters:
484-
/// - explicitProduct: The product specified on the command line to a “swift run” or “swift build” command. This allows executables from dependencies to be run directly without having to hook them up to any particular target.
541+
/// - explicitProduct: The product specified on the command line to a “swift run” or “swift build” command. This
542+
/// allows executables from dependencies to be run directly without having to hook them up to any particular target.
485543
@discardableResult
486544
public func loadPackageGraph(
487545
explicitProduct: String? = nil,
@@ -527,15 +585,15 @@ public final class SwiftTool {
527585

528586
/// Returns the user toolchain to compile the actual product.
529587
public func getDestinationToolchain() throws -> UserToolchain {
530-
return try _destinationToolchain.get()
588+
try _destinationToolchain.get()
531589
}
532590

533591
public func getHostToolchain() throws -> UserToolchain {
534-
return try _hostToolchain.get()
592+
try _hostToolchain.get()
535593
}
536594

537595
func getManifestLoader() throws -> ManifestLoader {
538-
return try _manifestLoader.get()
596+
try _manifestLoader.get()
539597
}
540598

541599
public func canUseCachedBuildManifest() throws -> Bool {
@@ -555,7 +613,7 @@ public final class SwiftTool {
555613
// Perform steps for build manifest caching if we can enabled it.
556614
//
557615
// FIXME: We don't add edited packages in the package structure command yet (SR-11254).
558-
let hasEditedPackages = try self.getActiveWorkspace().state.dependencies.contains(where: { $0.isEdited })
616+
let hasEditedPackages = try self.getActiveWorkspace().state.dependencies.contains(where: \.isEdited)
559617
if hasEditedPackages {
560618
return false
561619
}
@@ -654,9 +712,24 @@ public final class SwiftTool {
654712

655713
// Create custom toolchain if present.
656714
if let customDestination = options.locations.customCompileDestination {
657-
destination = try Destination(fromFile: customDestination, fileSystem: fileSystem)
658-
} else if let target = options.build.customCompileTriple,
659-
let targetDestination = Destination.defaultDestination(for: target, host: hostDestination) {
715+
let destinations = try Destination.decode(
716+
fromFile: customDestination,
717+
fileSystem: fileSystem,
718+
observabilityScope: observabilityScope
719+
)
720+
if destinations.count == 1 {
721+
destination = destinations[0]
722+
} else if destinations.count > 1,
723+
let triple = options.build.customCompileTriple,
724+
let matchingDestination = destinations.first(where: { $0.targetTriple == triple })
725+
{
726+
destination = matchingDestination
727+
} else {
728+
return .failure(DestinationError.noDestinationsDecoded(customDestination))
729+
}
730+
} else if let triple = options.build.customCompileTriple,
731+
let targetDestination = Destination.defaultDestination(for: triple, host: hostDestination)
732+
{
660733
destination = targetDestination
661734
} else if let destinationSelector = options.build.crossCompilationDestinationSelector {
662735
destination = try DestinationsBundle.selectDestination(
@@ -678,7 +751,7 @@ public final class SwiftTool {
678751
destination.targetTriple = triple
679752
}
680753
if let binDir = options.build.customCompileToolchain {
681-
destination.toolchainBinDir = binDir.appending(components: "usr", "bin")
754+
destination.add(toolsetRootPath: binDir.appending(components: "usr", "bin"))
682755
}
683756
if let sdk = options.build.customCompileSDK {
684757
destination.sdkRootDir = sdk
@@ -886,8 +959,8 @@ extension BuildOptions.TargetDependencyImportCheckingMode {
886959
}
887960
}
888961

889-
public extension Basics.Diagnostic {
890-
static func mutuallyExclusiveArgumentsError(arguments: [String]) -> Self {
962+
extension Basics.Diagnostic {
963+
public static func mutuallyExclusiveArgumentsError(arguments: [String]) -> Self {
891964
.error(arguments.map { "'\($0)'" }.spm_localizedJoin(type: .conjunction) + " are mutually exclusive")
892965
}
893966
}

Sources/CrossCompilationDestinationsTool/ListDestinations.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
import ArgumentParser
1414
import Basics
1515
import CoreCommands
16-
import SPMBuildCore
1716
import PackageModel
17+
import SPMBuildCore
1818
import TSCBasic
1919

2020
public struct ListDestinations: ParsableCommand {
2121
public static let configuration = CommandConfiguration(
2222
commandName: "list",
2323
abstract:
24-
"""
25-
Print a list of IDs of available cross-compilation destinations available on the filesystem.
26-
"""
24+
"""
25+
Print a list of IDs of available cross-compilation destinations available on the filesystem.
26+
"""
2727
)
2828

2929
@OptionGroup()

Sources/PackageModel/BuildFlags.swift

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,32 @@
1212

1313
/// Build-tool independent flags.
1414
public struct BuildFlags: Equatable, Encodable {
15-
1615
/// Flags to pass to the C compiler.
1716
public var cCompilerFlags: [String]
18-
17+
1918
/// Flags to pass to the C++ compiler.
2019
public var cxxCompilerFlags: [String]
21-
20+
2221
/// Flags to pass to the Swift compiler.
2322
public var swiftCompilerFlags: [String]
24-
23+
2524
/// Flags to pass to the linker.
2625
public var linkerFlags: [String]
27-
26+
2827
/// Flags to pass to xcbuild.
2928
public var xcbuildFlags: [String]?
30-
29+
3130
public init(
32-
cCompilerFlags: [String]? = .none,
33-
cxxCompilerFlags: [String]? = .none,
34-
swiftCompilerFlags: [String]? = .none,
35-
linkerFlags: [String]? = .none,
36-
xcbuildFlags: [String]? = .none
31+
cCompilerFlags: [String] = [],
32+
cxxCompilerFlags: [String] = [],
33+
swiftCompilerFlags: [String] = [],
34+
linkerFlags: [String] = [],
35+
xcbuildFlags: [String] = []
3736
) {
38-
self.cCompilerFlags = cCompilerFlags ?? []
39-
self.cxxCompilerFlags = cxxCompilerFlags ?? []
40-
self.swiftCompilerFlags = swiftCompilerFlags ?? []
41-
self.linkerFlags = linkerFlags ?? []
42-
self.xcbuildFlags = xcbuildFlags ?? []
37+
self.cCompilerFlags = cCompilerFlags
38+
self.cxxCompilerFlags = cxxCompilerFlags
39+
self.swiftCompilerFlags = swiftCompilerFlags
40+
self.linkerFlags = linkerFlags
41+
self.xcbuildFlags = xcbuildFlags
4342
}
4443
}

0 commit comments

Comments
 (0)