diff --git a/Examples/package-info/Sources/package-info/example.swift b/Examples/package-info/Sources/package-info/example.swift index 579a5331e25..ef56de98515 100644 --- a/Examples/package-info/Sources/package-info/example.swift +++ b/Examples/package-info/Sources/package-info/example.swift @@ -20,7 +20,7 @@ struct Example { let observability = ObservabilitySystem({ print("\($0): \($1)") }) - let workspace = try Workspace(forRootPackage: packagePath) + let workspace = try await Workspace.create(forRootPackage: packagePath) let manifest = try await workspace.loadRootManifest(at: packagePath, observabilityScope: observability.topScope) diff --git a/Sources/Commands/PackageCommands/APIDiff.swift b/Sources/Commands/PackageCommands/APIDiff.swift index a5221e8dfe2..921d4e06585 100644 --- a/Sources/Commands/PackageCommands/APIDiff.swift +++ b/Sources/Commands/PackageCommands/APIDiff.swift @@ -84,7 +84,12 @@ struct APIDiff: AsyncSwiftCommand { let repository = GitRepository(path: packageRoot) let baselineRevision = try repository.resolveRevision(identifier: treeish) - let baselineDir = try overrideBaselineDir?.appending(component: baselineRevision.identifier) ?? swiftCommandState.productsBuildParameters.apiDiff.appending(component: "\(baselineRevision.identifier)-baselines") + let baselineDir: Basics.AbsolutePath + if let overrideBaselineDir { + baselineDir = overrideBaselineDir.appending(component: baselineRevision.identifier) + } else { + baselineDir = try await swiftCommandState.productsBuildParameters.apiDiff.appending(component: "\(baselineRevision.identifier)-baselines") + } let packageGraph = try await swiftCommandState.loadPackageGraph() let modulesToDiff = try Self.determineModulesToDiff( packageGraph: packageGraph, @@ -115,7 +120,7 @@ struct APIDiff: AsyncSwiftCommand { } private func runWithSwiftPMCoordinatedDiffing(_ swiftCommandState: SwiftCommandState, buildSystem: any BuildSystem, baselineRevision: Revision, modulesToDiff: Set) async throws { - let apiDigesterPath = try swiftCommandState.getTargetToolchain().getSwiftAPIDigester() + let apiDigesterPath = try await swiftCommandState.getTargetToolchain().getSwiftAPIDigester() let apiDigesterTool = SwiftAPIDigester(fileSystem: swiftCommandState.fileSystem, tool: apiDigesterPath) // Build the current package. @@ -198,7 +203,7 @@ struct APIDiff: AsyncSwiftCommand { let modulesWithBaselines = try await generateAPIBaselineUsingIntegratedAPIDigesterSupport(swiftCommandState, baselineRevision: baselineRevision, baselineDir: baselineDir, modulesNeedingBaselines: modulesToDiff) // Build the package and run a comparison agains the baselines. - var productsBuildParameters = try swiftCommandState.productsBuildParameters + var productsBuildParameters = try await swiftCommandState.productsBuildParameters productsBuildParameters.apiDigesterMode = .compareToBaselines( baselinesDirectory: baselineDir, modulesToCompare: modulesWithBaselines, @@ -258,7 +263,7 @@ struct APIDiff: AsyncSwiftCommand { private func generateAPIBaselineUsingIntegratedAPIDigesterSupport(_ swiftCommandState: SwiftCommandState, baselineRevision: Revision, baselineDir: Basics.AbsolutePath, modulesNeedingBaselines: Set) async throws -> Set { // Setup a temporary directory where we can checkout and build the baseline treeish. - let baselinePackageRoot = try swiftCommandState.productsBuildParameters.apiDiff.appending("\(baselineRevision.identifier)-checkout") + let baselinePackageRoot = try await swiftCommandState.productsBuildParameters.apiDiff.appending("\(baselineRevision.identifier)-checkout") if swiftCommandState.fileSystem.exists(baselinePackageRoot) { try swiftCommandState.fileSystem.removeFileTree(baselinePackageRoot) } @@ -279,7 +284,7 @@ struct APIDiff: AsyncSwiftCommand { try workingCopy.checkout(revision: baselineRevision) // Create the workspace for this package. - let workspace = try Workspace( + let workspace = try await Workspace.create( forRootPackage: baselinePackageRoot, cancellator: swiftCommandState.cancellator ) @@ -307,7 +312,7 @@ struct APIDiff: AsyncSwiftCommand { } // Update the data path input build parameters so it's built in the sandbox. - var productsBuildParameters = try swiftCommandState.productsBuildParameters + var productsBuildParameters = try await swiftCommandState.productsBuildParameters productsBuildParameters.dataPath = workspace.location.scratchDirectory productsBuildParameters.apiDigesterMode = .generateBaselines(baselinesDirectory: baselineDir, modulesRequestingBaselines: modulesNeedingBaselines) diff --git a/Sources/Commands/PackageCommands/AddDependency.swift b/Sources/Commands/PackageCommands/AddDependency.swift index 03c49fc9661..4b78d8c2e1b 100644 --- a/Sources/Commands/PackageCommands/AddDependency.swift +++ b/Sources/Commands/PackageCommands/AddDependency.swift @@ -25,7 +25,7 @@ import Workspace import class PackageModel.Manifest extension SwiftPackageCommand { - struct AddDependency: SwiftCommand { + struct AddDependency: AsyncSwiftCommand { package static let configuration = CommandConfiguration( abstract: "Add a package dependency to the manifest." ) @@ -63,8 +63,8 @@ extension SwiftPackageCommand { case registry } - func run(_ swiftCommandState: SwiftCommandState) throws { - let workspace = try swiftCommandState.getActiveWorkspace() + func run(_ swiftCommandState: SwiftCommandState) async throws { + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") } diff --git a/Sources/Commands/PackageCommands/AddProduct.swift b/Sources/Commands/PackageCommands/AddProduct.swift index 288e691797b..b14c88c1c06 100644 --- a/Sources/Commands/PackageCommands/AddProduct.swift +++ b/Sources/Commands/PackageCommands/AddProduct.swift @@ -23,7 +23,7 @@ import TSCUtility import Workspace extension SwiftPackageCommand { - struct AddProduct: SwiftCommand { + struct AddProduct: AsyncSwiftCommand { /// The package product type used for the command-line. This is a /// subset of `ProductType` that expands out the library types. enum CommandProductType: String, Codable, ExpressibleByArgument, CaseIterable { @@ -52,8 +52,8 @@ extension SwiftPackageCommand { ) var targets: [String] = [] - func run(_ swiftCommandState: SwiftCommandState) throws { - let workspace = try swiftCommandState.getActiveWorkspace() + func run(_ swiftCommandState: SwiftCommandState) async throws { + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") diff --git a/Sources/Commands/PackageCommands/AddSetting.swift b/Sources/Commands/PackageCommands/AddSetting.swift index 4589bfa50f9..ed99783bf20 100644 --- a/Sources/Commands/PackageCommands/AddSetting.swift +++ b/Sources/Commands/PackageCommands/AddSetting.swift @@ -25,7 +25,7 @@ import TSCUtility import Workspace extension SwiftPackageCommand { - struct AddSetting: SwiftCommand { + struct AddSetting: AsyncSwiftCommand { /// The Swift language setting that can be specified on the command line. enum SwiftSetting: String, Codable, ExpressibleByArgument, CaseIterable { case experimentalFeature @@ -68,9 +68,9 @@ extension SwiftPackageCommand { } } - func run(_ swiftCommandState: SwiftCommandState) throws { + func run(_ swiftCommandState: SwiftCommandState) async throws { if !self._swiftSettings.isEmpty { - try Self.editSwiftSettings( + try await Self.editSwiftSettings( of: self.target, using: swiftCommandState, self.swiftSettings, @@ -84,8 +84,8 @@ extension SwiftPackageCommand { using swiftCommandState: SwiftCommandState, _ settings: [(SwiftSetting, String)], verbose: Bool = false - ) throws { - let workspace = try swiftCommandState.getActiveWorkspace() + ) async throws { + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") } diff --git a/Sources/Commands/PackageCommands/AddTarget.swift b/Sources/Commands/PackageCommands/AddTarget.swift index 089f148675f..c0d3716be8c 100644 --- a/Sources/Commands/PackageCommands/AddTarget.swift +++ b/Sources/Commands/PackageCommands/AddTarget.swift @@ -75,7 +75,7 @@ extension SwiftPackageCommand { var testingLibrary: AddPackageTarget.TestHarness = .default func run(_ swiftCommandState: SwiftCommandState) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") diff --git a/Sources/Commands/PackageCommands/AddTargetDependency.swift b/Sources/Commands/PackageCommands/AddTargetDependency.swift index c5daf524361..e4783a34ab4 100644 --- a/Sources/Commands/PackageCommands/AddTargetDependency.swift +++ b/Sources/Commands/PackageCommands/AddTargetDependency.swift @@ -24,7 +24,7 @@ import TSCUtility import Workspace extension SwiftPackageCommand { - struct AddTargetDependency: SwiftCommand { + struct AddTargetDependency: AsyncSwiftCommand { package static let configuration = CommandConfiguration( abstract: "Add a new target dependency to the manifest.") @@ -40,8 +40,8 @@ extension SwiftPackageCommand { @Option(help: "The package in which the dependency resides.") var package: String? - func run(_ swiftCommandState: SwiftCommandState) throws { - let workspace = try swiftCommandState.getActiveWorkspace() + func run(_ swiftCommandState: SwiftCommandState) async throws { + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") diff --git a/Sources/Commands/PackageCommands/AuditBinaryArtifact.swift b/Sources/Commands/PackageCommands/AuditBinaryArtifact.swift index ac290eea4c0..b688d4fb3f3 100644 --- a/Sources/Commands/PackageCommands/AuditBinaryArtifact.swift +++ b/Sources/Commands/PackageCommands/AuditBinaryArtifact.swift @@ -34,7 +34,7 @@ struct AuditBinaryArtifact: AsyncSwiftCommand { var path: AbsolutePath func run(_ swiftCommandState: SwiftCommandState) async throws { - let hostToolchain = try swiftCommandState.getHostToolchain() + let hostToolchain = try await swiftCommandState.getHostToolchain() let clang = try hostToolchain.getClangCompiler() let objdump = try hostToolchain.getLLVMObjdump() let hostTriple = try Triple.getVersionedHostTriple( diff --git a/Sources/Commands/PackageCommands/Config.swift b/Sources/Commands/PackageCommands/Config.swift index d5243a4503b..128c4e09fc4 100644 --- a/Sources/Commands/PackageCommands/Config.swift +++ b/Sources/Commands/PackageCommands/Config.swift @@ -28,7 +28,7 @@ extension SwiftPackageCommand { } extension SwiftPackageCommand.Config { - struct SetMirror: SwiftCommand { + struct SetMirror: AsyncSwiftCommand { static let configuration = CommandConfiguration( abstract: "Set a mirror for a dependency." ) @@ -51,8 +51,8 @@ extension SwiftPackageCommand.Config { @Option(help: "The mirror url or identity.") var mirror: String? - func run(_ swiftCommandState: SwiftCommandState) throws { - let config = try getMirrorsConfig(swiftCommandState) + func run(_ swiftCommandState: SwiftCommandState) async throws { + let config = try await getMirrorsConfig(swiftCommandState) if self._deprecate_packageURL != nil { swiftCommandState.observabilityScope.emit( @@ -86,7 +86,7 @@ extension SwiftPackageCommand.Config { } } - struct UnsetMirror: SwiftCommand { + struct UnsetMirror: AsyncSwiftCommand { static let configuration = CommandConfiguration( abstract: "Remove an existing mirror." ) @@ -109,8 +109,8 @@ extension SwiftPackageCommand.Config { @Option(help: "The mirror url or identity.") var mirror: String? - func run(_ swiftCommandState: SwiftCommandState) throws { - let config = try getMirrorsConfig(swiftCommandState) + func run(_ swiftCommandState: SwiftCommandState) async throws { + let config = try await getMirrorsConfig(swiftCommandState) if self._deprecate_packageURL != nil { swiftCommandState.observabilityScope.emit( @@ -141,7 +141,7 @@ extension SwiftPackageCommand.Config { } } - struct GetMirror: SwiftCommand { + struct GetMirror: AsyncSwiftCommand { static let configuration = CommandConfiguration( abstract: "Print mirror configuration for the given package dependency." ) @@ -157,8 +157,8 @@ extension SwiftPackageCommand.Config { @Option(help: "The original url or identity.") var original: String? - func run(_ swiftCommandState: SwiftCommandState) throws { - let config = try getMirrorsConfig(swiftCommandState) + func run(_ swiftCommandState: SwiftCommandState) async throws { + let config = try await getMirrorsConfig(swiftCommandState) if self._deprecate_packageURL != nil { swiftCommandState.observabilityScope.emit( @@ -186,8 +186,8 @@ extension SwiftPackageCommand.Config { } } - static func getMirrorsConfig(_ swiftCommandState: SwiftCommandState) throws -> Workspace.Configuration.Mirrors { - let workspace = try swiftCommandState.getActiveWorkspace() + static func getMirrorsConfig(_ swiftCommandState: SwiftCommandState) async throws -> Workspace.Configuration.Mirrors { + let workspace = try await swiftCommandState.getActiveWorkspace() return try .init( fileSystem: swiftCommandState.fileSystem, localMirrorsFile: workspace.location.localMirrorsConfigurationFile, diff --git a/Sources/Commands/PackageCommands/Describe.swift b/Sources/Commands/PackageCommands/Describe.swift index 99025ef41e6..7db096e34e8 100644 --- a/Sources/Commands/PackageCommands/Describe.swift +++ b/Sources/Commands/PackageCommands/Describe.swift @@ -32,7 +32,7 @@ extension SwiftPackageCommand { var type: DescribeMode = .text func run(_ swiftCommandState: SwiftCommandState) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") diff --git a/Sources/Commands/PackageCommands/DumpCommands.swift b/Sources/Commands/PackageCommands/DumpCommands.swift index a46630d1d0f..ba491f90d48 100644 --- a/Sources/Commands/PackageCommands/DumpCommands.swift +++ b/Sources/Commands/PackageCommands/DumpCommands.swift @@ -67,7 +67,7 @@ struct DumpSymbolGraph: AsyncSwiftCommand { ) ), .buildPlan]) - let symbolGraphDirectory = try swiftCommandState.productsBuildParameters.dataPath.appending("symbolgraph") + let symbolGraphDirectory = try await swiftCommandState.productsBuildParameters.dataPath.appending("symbolgraph") let fs = swiftCommandState.fileSystem @@ -76,12 +76,12 @@ struct DumpSymbolGraph: AsyncSwiftCommand { if let symbolGraph = buildResult.symbolGraph { // The build system produced symbol graphs for us, one for each target. - let buildPath = try swiftCommandState.productsBuildParameters.buildPath + let buildPath = try await swiftCommandState.productsBuildParameters.buildPath // Copy the symbol graphs from the target-specific locations to the single output directory for rootPackage in try await buildSystem.getPackageGraph().rootPackages { for module in rootPackage.modules { - let sgDir = symbolGraph.outputLocationForTarget(module.name, try swiftCommandState.productsBuildParameters) + let sgDir = symbolGraph.outputLocationForTarget(module.name, try await swiftCommandState.productsBuildParameters) if case let sgDir = buildPath.appending(components: sgDir), fs.exists(sgDir) { for sgFile in try fs.getDirectoryContents(sgDir) { @@ -92,9 +92,9 @@ struct DumpSymbolGraph: AsyncSwiftCommand { } } else if let buildPlan = buildResult.buildPlan { // Otherwise, with a build plan we can run the symbol graph extractor tool on the built targets. - let symbolGraphExtractor = try SymbolGraphExtract( + let symbolGraphExtractor = try await SymbolGraphExtract( fileSystem: swiftCommandState.fileSystem, - tool: swiftCommandState.getTargetToolchain().getSymbolGraphExtract(), + tool: await swiftCommandState.getTargetToolchain().getSymbolGraphExtract(), observabilityScope: swiftCommandState.observabilityScope, skipSynthesizedMembers: skipSynthesizedMembers, minimumAccessLevel: minimumAccessLevel, @@ -152,7 +152,7 @@ struct DumpPackage: AsyncSwiftCommand { var globalOptions: GlobalOptions func run(_ swiftCommandState: SwiftCommandState) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() let root = try swiftCommandState.getWorkspaceRoot() let rootManifests = try await workspace.loadRootManifests( diff --git a/Sources/Commands/PackageCommands/EditCommands.swift b/Sources/Commands/PackageCommands/EditCommands.swift index 5509c2ee51f..5791fdabd5d 100644 --- a/Sources/Commands/PackageCommands/EditCommands.swift +++ b/Sources/Commands/PackageCommands/EditCommands.swift @@ -38,7 +38,7 @@ extension SwiftPackageCommand { func run(_ swiftCommandState: SwiftCommandState) async throws { try await swiftCommandState.resolve() - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() // Put the dependency in edit mode. await workspace.edit( @@ -67,7 +67,7 @@ extension SwiftPackageCommand { func run(_ swiftCommandState: SwiftCommandState) async throws { try await swiftCommandState.resolve() - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() try await workspace.unedit( packageIdentity: packageIdentity, diff --git a/Sources/Commands/PackageCommands/Format.swift b/Sources/Commands/PackageCommands/Format.swift index 1c2341fb4a6..9a95c704613 100644 --- a/Sources/Commands/PackageCommands/Format.swift +++ b/Sources/Commands/PackageCommands/Format.swift @@ -44,7 +44,7 @@ extension SwiftPackageCommand { } // Get the root package. - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() guard let packagePath = try swiftCommandState.getWorkspaceRoot().packages.first else { throw StringError("unknown package") diff --git a/Sources/Commands/PackageCommands/Init.swift b/Sources/Commands/PackageCommands/Init.swift index 7057845a3df..2381aabe13f 100644 --- a/Sources/Commands/PackageCommands/Init.swift +++ b/Sources/Commands/PackageCommands/Init.swift @@ -21,7 +21,7 @@ import Workspace import SPMBuildCore extension SwiftPackageCommand { - struct Init: SwiftCommand { + struct Init: AsyncSwiftCommand { public static let configuration = CommandConfiguration( abstract: "Initialize a new package.") @@ -53,7 +53,7 @@ extension SwiftPackageCommand { // This command should support creating the supplied --package-path if it isn't created. var createPackagePath = true - func run(_ swiftCommandState: SwiftCommandState) throws { + func run(_ swiftCommandState: SwiftCommandState) async throws { guard let cwd = swiftCommandState.fileSystem.currentWorkingDirectory else { throw InternalError("Could not find the current working directory") } @@ -64,13 +64,19 @@ extension SwiftPackageCommand { // For macros this is reversed, since we don't support testing // macros with Swift Testing yet. var supportedTestingLibraries = Set() - if testLibraryOptions.isExplicitlyEnabled(.xctest, swiftCommandState: swiftCommandState) || - (initMode == .macro && testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState)) { + if await testLibraryOptions.isExplicitlyEnabled(.xctest, swiftCommandState: swiftCommandState) { supportedTestingLibraries.insert(.xctest) + } else if initMode == .macro { + if await testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { + supportedTestingLibraries.insert(.xctest) + } } - if testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) || - (initMode != .macro && testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState)) { + if await testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { supportedTestingLibraries.insert(.swiftTesting) + } else if initMode != .macro { + if await testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { + supportedTestingLibraries.insert(.swiftTesting) + } } let initPackage = try InitPackage( @@ -78,7 +84,7 @@ extension SwiftPackageCommand { packageType: initMode, supportedTestingLibraries: supportedTestingLibraries, destinationPath: cwd, - installedSwiftPMConfiguration: swiftCommandState.getHostToolchain().installedSwiftPMConfiguration, + installedSwiftPMConfiguration: await swiftCommandState.getHostToolchain().installedSwiftPMConfiguration, fileSystem: swiftCommandState.fileSystem ) initPackage.progressReporter = { message in diff --git a/Sources/Commands/PackageCommands/Install.swift b/Sources/Commands/PackageCommands/Install.swift index daea088980a..d5343974f9d 100644 --- a/Sources/Commands/PackageCommands/Install.swift +++ b/Sources/Commands/PackageCommands/Install.swift @@ -49,7 +49,7 @@ extension SwiftPackageCommand { let alreadyExisting = (try? InstalledPackageProduct.installedProducts(commandState.fileSystem)) ?? [] - let workspace = try commandState.getActiveWorkspace() + let workspace = try await commandState.getActiveWorkspace() let packageRoot = try commandState.getPackageRoot() let packageGraph = try await workspace.loadPackageGraph( @@ -91,7 +91,7 @@ extension SwiftPackageCommand { try await commandState.createBuildSystem(explicitProduct: productToInstall.name) .build(subset: .product(productToInstall.name), buildOutputs: []) - let binPath = try commandState.productsBuildParameters.buildPath.appending(component: productToInstall.name) + let binPath = try await commandState.productsBuildParameters.buildPath.appending(component: productToInstall.name) let finalBinPath = swiftpmBinDir.appending(component: binPath.basename) try commandState.fileSystem.copy(from: binPath, to: finalBinPath) diff --git a/Sources/Commands/PackageCommands/Migrate.swift b/Sources/Commands/PackageCommands/Migrate.swift index fca4dd4b3fe..6413e4bb7e6 100644 --- a/Sources/Commands/PackageCommands/Migrate.swift +++ b/Sources/Commands/PackageCommands/Migrate.swift @@ -68,7 +68,7 @@ extension SwiftPackageCommand { public func run(_ swiftCommandState: SwiftCommandState) async throws { // First, validate and resolve the requested feature names. - let features = try self.resolveRequestedFeatures(swiftCommandState) + let features = try await self.resolveRequestedFeatures(swiftCommandState) let buildSystem = try await createBuildSystem( swiftCommandState, @@ -163,7 +163,7 @@ extension SwiftPackageCommand { print("> Updating manifest") for target in targetsToMigrate.sorted() { swiftCommandState.observabilityScope.emit(debug: "Adding feature(s) to '\(target)'") - try self.updateManifest( + try await self.updateManifest( for: target, add: features, using: swiftCommandState @@ -176,8 +176,8 @@ extension SwiftPackageCommand { /// - Returns: An array of resolved features, sorted by name. private func resolveRequestedFeatures( _ swiftCommandState: SwiftCommandState - ) throws -> [SwiftCompilerFeature] { - let toolchain = try swiftCommandState.productsBuildParameters.toolchain + ) async throws -> [SwiftCompilerFeature] { + let toolchain = try await swiftCommandState.productsBuildParameters.toolchain // Query the compiler for supported features. let supportedFeatures = try toolchain.swiftCompilerSupportedFeatures @@ -218,8 +218,8 @@ extension SwiftPackageCommand { targets: OrderedSet, features: [SwiftCompilerFeature] ) async throws -> BuildSystem { - let toolsBuildParameters = try swiftCommandState.toolsBuildParameters - let destinationBuildParameters = try swiftCommandState.productsBuildParameters + let toolsBuildParameters = try await swiftCommandState.toolsBuildParameters + let destinationBuildParameters = try await swiftCommandState.productsBuildParameters let modulesGraph = try await swiftCommandState.loadPackageGraph() @@ -261,7 +261,7 @@ extension SwiftPackageCommand { for target: String, add features: [SwiftCompilerFeature], using swiftCommandState: SwiftCommandState - ) throws { + ) async throws { typealias SwiftSetting = SwiftPackageCommand.AddSetting.SwiftSetting let settings: [(SwiftSetting, String)] = try features.map { @@ -269,7 +269,7 @@ extension SwiftPackageCommand { } do { - try SwiftPackageCommand.AddSetting.editSwiftSettings( + try await SwiftPackageCommand.AddSetting.editSwiftSettings( of: target, using: swiftCommandState, settings, diff --git a/Sources/Commands/PackageCommands/PluginCommand.swift b/Sources/Commands/PackageCommands/PluginCommand.swift index 8bc238af22a..05d13425696 100644 --- a/Sources/Commands/PackageCommands/PluginCommand.swift +++ b/Sources/Commands/PackageCommands/PluginCommand.swift @@ -239,11 +239,11 @@ struct PluginCommand: AsyncSwiftCommand { ) // The `plugins` directory is inside the workspace's main data directory, and contains all temporary files related to this plugin in the workspace. - let pluginsDir = try swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory + let pluginsDir = try await swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory .appending(component: plugin.name) // The `cache` directory is in the plugin’s directory and is where the plugin script runner caches compiled plugin binaries and any other derived information for this plugin. - let pluginScriptRunner = try swiftCommandState.getPluginScriptRunner( + let pluginScriptRunner = try await swiftCommandState.getPluginScriptRunner( customPluginsDir: pluginsDir ) @@ -329,10 +329,10 @@ struct PluginCommand: AsyncSwiftCommand { .contains { package.path.isDescendantOfOrEqual(to: $0) } ? [] : [package.path] // Use the directory containing the compiler as an additional search directory, and add the $PATH. - let toolSearchDirs = [try swiftCommandState.getTargetToolchain().swiftCompilerPath.parentDirectory] + let toolSearchDirs = [try await swiftCommandState.getTargetToolchain().swiftCompilerPath.parentDirectory] + getEnvSearchPaths(pathString: Environment.current[.path], currentWorkingDirectory: .none) - var buildParameters = try swiftCommandState.toolsBuildParameters + var buildParameters = try await swiftCommandState.toolsBuildParameters buildParameters.buildSystemKind = buildSystemKind // Build or bring up-to-date any executable host-side tools on which this plugin depends. Add them and any binary dependencies to the tool-names-to-path map. diff --git a/Sources/Commands/PackageCommands/ResetCommands.swift b/Sources/Commands/PackageCommands/ResetCommands.swift index fdd491d7db3..b7c506ae4b5 100644 --- a/Sources/Commands/PackageCommands/ResetCommands.swift +++ b/Sources/Commands/PackageCommands/ResetCommands.swift @@ -15,15 +15,15 @@ import CoreCommands import Workspace extension SwiftPackageCommand { - struct Clean: SwiftCommand { + struct Clean: AsyncSwiftCommand { static let configuration = CommandConfiguration( abstract: "Delete build artifacts.") @OptionGroup(visibility: .hidden) var globalOptions: GlobalOptions - func run(_ swiftCommandState: SwiftCommandState) throws { - try swiftCommandState.getActiveWorkspace().clean(observabilityScope: swiftCommandState.observabilityScope) + func run(_ swiftCommandState: SwiftCommandState) async throws { + try await swiftCommandState.getActiveWorkspace().clean(observabilityScope: swiftCommandState.observabilityScope) } } diff --git a/Sources/Commands/PackageCommands/Resolve.swift b/Sources/Commands/PackageCommands/Resolve.swift index 10c5dff9039..adb0de2984b 100644 --- a/Sources/Commands/PackageCommands/Resolve.swift +++ b/Sources/Commands/PackageCommands/Resolve.swift @@ -46,7 +46,7 @@ extension SwiftPackageCommand { func run(_ swiftCommandState: SwiftCommandState) async throws { // If a package is provided, use that to resolve the dependencies. if let packageName = resolveOptions.packageName { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() try await workspace.resolve( packageName: packageName, root: swiftCommandState.getWorkspaceRoot(), diff --git a/Sources/Commands/PackageCommands/ToolsVersionCommand.swift b/Sources/Commands/PackageCommands/ToolsVersionCommand.swift index 02044f71564..db373421ab5 100644 --- a/Sources/Commands/PackageCommands/ToolsVersionCommand.swift +++ b/Sources/Commands/PackageCommands/ToolsVersionCommand.swift @@ -18,7 +18,7 @@ import Workspace // This is named as `ToolsVersionCommand` instead of `ToolsVersion` to avoid naming conflicts, as the latter already // exists to denote the version itself. -struct ToolsVersionCommand: SwiftCommand { +struct ToolsVersionCommand: AsyncSwiftCommand { static let configuration = CommandConfiguration( commandName: "tools-version", abstract: "Manipulate tools version of the current package.") @@ -49,7 +49,7 @@ struct ToolsVersionCommand: SwiftCommand { } } - func run(_ swiftCommandState: SwiftCommandState) throws { + func run(_ swiftCommandState: SwiftCommandState) async throws { let pkg = try swiftCommandState.getPackageRoot() switch toolsVersionMode { diff --git a/Sources/Commands/PackageCommands/Update.swift b/Sources/Commands/PackageCommands/Update.swift index 2bea09a4500..0b07e303f47 100644 --- a/Sources/Commands/PackageCommands/Update.swift +++ b/Sources/Commands/PackageCommands/Update.swift @@ -34,7 +34,7 @@ extension SwiftPackageCommand { var packages: [String] = [] func run(_ swiftCommandState: SwiftCommandState) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() let changes = try await workspace.updateDependencies( root: swiftCommandState.getWorkspaceRoot(), diff --git a/Sources/Commands/Snippets/Cards/SnippetCard.swift b/Sources/Commands/Snippets/Cards/SnippetCard.swift index e4fbe38b6d7..416261f8e7b 100644 --- a/Sources/Commands/Snippets/Cards/SnippetCard.swift +++ b/Sources/Commands/Snippets/Cards/SnippetCard.swift @@ -114,7 +114,7 @@ struct SnippetCard: Card { print("Building '\(snippet.path)'\n") let buildSystem = try await swiftCommandState.createBuildSystem(explicitProduct: snippet.name) try await buildSystem.build(subset: .product(snippet.name), buildOutputs: []) - let executablePath = try swiftCommandState.productsBuildParameters.buildPath.appending(component: snippet.name) + let executablePath = try await swiftCommandState.productsBuildParameters.buildPath.appending(component: snippet.name) if let exampleTarget = try await buildSystem.getPackageGraph().module(for: snippet.name) { try ProcessEnv.chdir(exampleTarget.sources.paths[0].parentDirectory) } diff --git a/Sources/Commands/SwiftBuildCommand.swift b/Sources/Commands/SwiftBuildCommand.swift index 5c366090224..39884006db6 100644 --- a/Sources/Commands/SwiftBuildCommand.swift +++ b/Sources/Commands/SwiftBuildCommand.swift @@ -133,7 +133,7 @@ public struct SwiftBuildCommand: AsyncSwiftCommand { public func run(_ swiftCommandState: SwiftCommandState) async throws { if options.shouldPrintBinPath { - return try print(swiftCommandState.productsBuildParameters.buildPath.description) + return try print(await swiftCommandState.productsBuildParameters.buildPath.description) } if options.printManifestGraphviz { @@ -156,8 +156,8 @@ public struct SwiftBuildCommand: AsyncSwiftCommand { throw ExitCode.failure } - var productsBuildParameters = try swiftCommandState.productsBuildParameters - var toolsBuildParameters = try swiftCommandState.toolsBuildParameters + var productsBuildParameters = try await swiftCommandState.productsBuildParameters + var toolsBuildParameters = try await swiftCommandState.toolsBuildParameters if self.options.enableCodeCoverage { productsBuildParameters.testingParameters.enableCodeCoverage = true diff --git a/Sources/Commands/SwiftRunCommand.swift b/Sources/Commands/SwiftRunCommand.swift index 1b6d7448214..f40f225da2f 100644 --- a/Sources/Commands/SwiftRunCommand.swift +++ b/Sources/Commands/SwiftRunCommand.swift @@ -146,7 +146,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand { } // Execute the REPL. - let interpreterPath = try swiftCommandState.getTargetToolchain().swiftInterpreterPath + let interpreterPath = try await swiftCommandState.getTargetToolchain().swiftInterpreterPath swiftCommandState.outputStream.send("Launching Swift (interpreter at \(interpreterPath)) REPL with arguments: \(arguments.joined(separator: " "))\n") swiftCommandState.outputStream.flush() try self.run( @@ -168,8 +168,8 @@ public struct SwiftRunCommand: AsyncSwiftCommand { try await buildSystem.build(subset: .product(productName), buildOutputs: []) } - let productRelativePath = try swiftCommandState.productsBuildParameters.executablePath(for: productName) - let productAbsolutePath = try swiftCommandState.productsBuildParameters.buildPath.appending(productRelativePath) + let productRelativePath = try await swiftCommandState.productsBuildParameters.executablePath(for: productName) + let productAbsolutePath = try await swiftCommandState.productsBuildParameters.buildPath.appending(productRelativePath) // Make sure we are running from the original working directory. let cwd: AbsolutePath? = swiftCommandState.fileSystem.currentWorkingDirectory @@ -177,7 +177,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand { try ProcessEnv.chdir(swiftCommandState.originalWorkingDirectory) } - if let debugger = try swiftCommandState.getTargetToolchain().swiftSDK.toolset.knownTools[.debugger], + if let debugger = try await swiftCommandState.getTargetToolchain().swiftSDK.toolset.knownTools[.debugger], let debuggerPath = debugger.path { try self.run( fileSystem: swiftCommandState.fileSystem, @@ -187,7 +187,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand { ) } else { let pathRelativeToWorkingDirectory = productAbsolutePath.relative(to: swiftCommandState.originalWorkingDirectory) - let lldbPath = try swiftCommandState.getTargetToolchain().getLLDB() + let lldbPath = try await swiftCommandState.getTargetToolchain().getLLDB() try exec(path: lldbPath.pathString, args: ["--", pathRelativeToWorkingDirectory.pathString] + options.arguments) } } catch let error as RunError { @@ -200,7 +200,7 @@ public struct SwiftRunCommand: AsyncSwiftCommand { if let executable = options.executable, try isValidSwiftFilePath(fileSystem: swiftCommandState.fileSystem, path: executable) { swiftCommandState.observabilityScope.emit(.runFileDeprecation(filePath: executable)) // Redirect execution to the toolchain's swift executable. - let swiftInterpreterPath = try swiftCommandState.getTargetToolchain().swiftInterpreterPath + let swiftInterpreterPath = try await swiftCommandState.getTargetToolchain().swiftInterpreterPath // Prepend the script to interpret to the arguments. let arguments = [executable] + options.arguments try self.run( @@ -224,15 +224,15 @@ public struct SwiftRunCommand: AsyncSwiftCommand { try await buildSystem.build(subset: .product(productName), buildOutputs: []) } - let executablePath = try swiftCommandState.productsBuildParameters.buildPath.appending(component: productName) + let executablePath = try await swiftCommandState.productsBuildParameters.buildPath.appending(component: productName) - let productRelativePath = try swiftCommandState.productsBuildParameters.executablePath(for: productName) - let productAbsolutePath = try swiftCommandState.productsBuildParameters.buildPath.appending(productRelativePath) + let productRelativePath = try await swiftCommandState.productsBuildParameters.executablePath(for: productName) + let productAbsolutePath = try await swiftCommandState.productsBuildParameters.buildPath.appending(productRelativePath) let runnerPath: AbsolutePath let arguments: [String] - if let debugger = try swiftCommandState.getTargetToolchain().swiftSDK.toolset.knownTools[.debugger], + if let debugger = try await swiftCommandState.getTargetToolchain().swiftSDK.toolset.knownTools[.debugger], let debuggerPath = debugger.path { runnerPath = debuggerPath arguments = debugger.extraCLIOptions + [productAbsolutePath.pathString] + options.arguments diff --git a/Sources/Commands/SwiftTestCommand.swift b/Sources/Commands/SwiftTestCommand.swift index d2eefa5fd97..4aa28694fb6 100644 --- a/Sources/Commands/SwiftTestCommand.swift +++ b/Sources/Commands/SwiftTestCommand.swift @@ -282,12 +282,12 @@ public struct SwiftTestCommand: AsyncSwiftCommand { var results = [TestRunner.Result]() // Run XCTest. - if options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { + if await options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { // Validate XCTest is available on Darwin-based systems. If it's not available and we're hitting this code // path, that means the developer must have explicitly passed --enable-xctest (or the toolchain is // corrupt, I suppose.) - let toolchain = try swiftCommandState.getTargetToolchain() - if case let .unsupported(reason) = try swiftCommandState.getHostToolchain().swiftSDK.xctestSupport { + let toolchain = try await swiftCommandState.getTargetToolchain() + if case let .unsupported(reason) = try await swiftCommandState.getHostToolchain().swiftSDK.xctestSupport { if let reason { throw TestError.xctestNotAvailable(reason: reason) } else { @@ -298,7 +298,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { } if !self.options.shouldRunInParallel { - let (xctestArgs, testCount) = try xctestArgs(for: testProducts, swiftCommandState: swiftCommandState) + let (xctestArgs, testCount) = try await xctestArgs(for: testProducts, swiftCommandState: swiftCommandState) let result = try await runTestProducts( testProducts, additionalArguments: xctestArgs, @@ -312,7 +312,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { results.append(result) } } else { - let testSuites = try TestingSupport.getTestSuites( + let testSuites = try await TestingSupport.getTestSuites( in: testProducts, swiftCommandState: swiftCommandState, enableCodeCoverage: options.enableCodeCoverage, @@ -342,7 +342,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { observabilityScope: swiftCommandState.observabilityScope ) - testResults = try runner.run(tests) + testResults = try await runner.run(tests) result = runner.ranSuccessfully ? .success : .failure } @@ -352,9 +352,9 @@ public struct SwiftTestCommand: AsyncSwiftCommand { } // Run Swift Testing (parallel or not, it has a single entry point.) - if options.testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { + if await options.testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { lazy var testEntryPointPath = testProducts.lazy.compactMap(\.testEntryPointPath).first - if options.testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) || testEntryPointPath == nil { + if await options.testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) || testEntryPointPath == nil { results.append( try await runTestProducts( testProducts, @@ -387,7 +387,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { } } - private func xctestArgs(for testProducts: [BuiltTestProduct], swiftCommandState: SwiftCommandState) throws -> (arguments: [String], testCount: Int?) { + private func xctestArgs(for testProducts: [BuiltTestProduct], swiftCommandState: SwiftCommandState) async throws -> (arguments: [String], testCount: Int?) { switch options.testCaseSpecifier { case .none: if case .skip = options.skippedTests(fileSystem: swiftCommandState.fileSystem) { @@ -403,7 +403,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { } // Find the tests we need to run. - let testSuites = try TestingSupport.getTestSuites( + let testSuites = try await TestingSupport.getTestSuites( in: testProducts, swiftCommandState: swiftCommandState, enableCodeCoverage: options.enableCodeCoverage, @@ -443,7 +443,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { public func run(_ swiftCommandState: SwiftCommandState) async throws { do { // Validate commands arguments - try self.validateArguments(swiftCommandState: swiftCommandState) + try await self.validateArguments(swiftCommandState: swiftCommandState) } catch { swiftCommandState.observabilityScope.emit(error) throw ExitCode.failure @@ -456,7 +456,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { let command = try List.parse() try await command.run(swiftCommandState) } else { - let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(options: self.options) + let (productsBuildParameters, _) = try await swiftCommandState.buildParametersForTest(options: self.options) let testProducts = try await buildTestsIfNeeded(swiftCommandState: swiftCommandState) // Clean out the code coverage directory that may contain stale @@ -498,7 +498,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { additionalArguments += commandLineArguments if var xunitPath = options.xUnitOutput { - if options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { + if await options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { // We are running Swift Testing, XCTest is also running in this session, and an xUnit path // was specified. Make sure we don't stomp on XCTest's XML output by having Swift Testing // write to a different path. @@ -512,8 +512,8 @@ public struct SwiftTestCommand: AsyncSwiftCommand { } } - let toolchain = try swiftCommandState.getTargetToolchain() - let testEnv = try TestingSupport.constructTestEnvironment( + let toolchain = try await swiftCommandState.getTargetToolchain() + let testEnv = try await TestingSupport.constructTestEnvironment( toolchain: toolchain, destinationBuildParameters: productsBuildParameters, sanitizers: globalOptions.build.sanitizers, @@ -581,7 +581,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { _ testProducts: [BuiltTestProduct], swiftCommandState: SwiftCommandState ) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() let root = try swiftCommandState.getWorkspaceRoot() let rootManifests = try await workspace.loadRootManifests( packages: root.packages, @@ -594,7 +594,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { // Merge all the profraw files to produce a single profdata file. try await mergeCodeCovRawDataFiles(swiftCommandState: swiftCommandState) - let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(options: self.options) + let (productsBuildParameters, _) = try await swiftCommandState.buildParametersForTest(options: self.options) for product in testProducts { // Export the codecov data as JSON. let jsonPath = productsBuildParameters.codeCovAsJSONPath(packageName: rootManifest.displayName) @@ -609,10 +609,10 @@ public struct SwiftTestCommand: AsyncSwiftCommand { /// Merges all profraw profiles in codecoverage directory into default.profdata file. private func mergeCodeCovRawDataFiles(swiftCommandState: SwiftCommandState) async throws { // Get the llvm-prof tool. - let llvmProf = try swiftCommandState.getTargetToolchain().getLLVMProf() + let llvmProf = try await swiftCommandState.getTargetToolchain().getLLVMProf() // Get the profraw files. - let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(options: self.options) + let (productsBuildParameters, _) = try await swiftCommandState.buildParametersForTest(options: self.options) let codeCovFiles = try swiftCommandState.fileSystem.getDirectoryContents(productsBuildParameters.codeCovPath) // Construct arguments for invoking the llvm-prof tool. @@ -634,8 +634,8 @@ public struct SwiftTestCommand: AsyncSwiftCommand { swiftCommandState: SwiftCommandState ) async throws { // Export using the llvm-cov tool. - let llvmCov = try swiftCommandState.getTargetToolchain().getLLVMCov() - let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(options: self.options) + let llvmCov = try await swiftCommandState.getTargetToolchain().getLLVMCov() + let (productsBuildParameters, _) = try await swiftCommandState.buildParametersForTest(options: self.options) let archArgs: [String] = if let arch = productsBuildParameters.triple.llvmCovArchArgument { ["--arch", "\(arch)"] } else { @@ -663,7 +663,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { private func buildTestsIfNeeded( swiftCommandState: SwiftCommandState ) async throws -> [BuiltTestProduct] { - let (productsBuildParameters, toolsBuildParameters) = try swiftCommandState.buildParametersForTest(options: self.options) + let (productsBuildParameters, toolsBuildParameters) = try await swiftCommandState.buildParametersForTest(options: self.options) return try await Commands.buildTestsIfNeeded( swiftCommandState: swiftCommandState, productsBuildParameters: productsBuildParameters, @@ -676,7 +676,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { /// Private function that validates the commands arguments /// /// - Throws: if a command argument is invalid - private func validateArguments(swiftCommandState: SwiftCommandState) throws { + private func validateArguments(swiftCommandState: SwiftCommandState) async throws { // Validation for --num-workers. if let workers = options.numberOfWorkers { // The --num-worker option should be called with --parallel. Since @@ -690,7 +690,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { throw StringError("'--num-workers' must be greater than zero") } - guard options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) else { + guard await options.testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) else { throw StringError("'--num-workers' is only supported when testing with XCTest") } } @@ -705,7 +705,7 @@ public struct SwiftTestCommand: AsyncSwiftCommand { extension SwiftTestCommand { func printCodeCovPath(_ swiftCommandState: SwiftCommandState) async throws { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() let root = try swiftCommandState.getWorkspaceRoot() let rootManifests = try await workspace.loadRootManifests( packages: root.packages, @@ -714,7 +714,7 @@ extension SwiftTestCommand { guard let rootManifest = rootManifests.values.first else { throw StringError("invalid manifests at \(root.packages)") } - let (productsBuildParameters, _) = try swiftCommandState.buildParametersForTest(enableCodeCoverage: true) + let (productsBuildParameters, _) = try await swiftCommandState.buildParametersForTest(enableCodeCoverage: true) print(productsBuildParameters.codeCovAsJSONPath(packageName: rootManifest.displayName)) } } @@ -739,9 +739,9 @@ extension SwiftTestCommand { @OptionGroup(visibility: .hidden) var globalOptions: GlobalOptions - func run(_ swiftCommandState: SwiftCommandState) throws { + func run(_ swiftCommandState: SwiftCommandState) async throws { try SwiftTestCommand.handleTestOutput( - productsBuildParameters: try swiftCommandState.productsBuildParameters, + productsBuildParameters: try await swiftCommandState.productsBuildParameters, packagePath: localFileSystem.currentWorkingDirectory ?? .root // by definition runs in the current working directory ) } @@ -788,7 +788,7 @@ extension SwiftTestCommand { } func runCommand(_ swiftCommandState: SwiftCommandState) async throws { - let (productsBuildParameters, toolsBuildParameters) = try swiftCommandState.buildParametersForTest( + let (productsBuildParameters, toolsBuildParameters) = try await swiftCommandState.buildParametersForTest( enableCodeCoverage: false, shouldSkipBuilding: sharedOptions.shouldSkipBuilding ) @@ -798,16 +798,16 @@ extension SwiftTestCommand { toolsBuildParameters: toolsBuildParameters ) - let toolchain = try swiftCommandState.getTargetToolchain() - let testEnv = try TestingSupport.constructTestEnvironment( + let toolchain = try await swiftCommandState.getTargetToolchain() + let testEnv = try await TestingSupport.constructTestEnvironment( toolchain: toolchain, destinationBuildParameters: productsBuildParameters, sanitizers: globalOptions.build.sanitizers, library: .swiftTesting ) - if testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { - let testSuites = try TestingSupport.getTestSuites( + if await testLibraryOptions.isEnabled(.xctest, swiftCommandState: swiftCommandState) { + let testSuites = try await TestingSupport.getTestSuites( in: testProducts, swiftCommandState: swiftCommandState, enableCodeCoverage: false, @@ -822,9 +822,9 @@ extension SwiftTestCommand { } } - if testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { + if await testLibraryOptions.isEnabled(.swiftTesting, swiftCommandState: swiftCommandState) { lazy var testEntryPointPath = testProducts.lazy.compactMap(\.testEntryPointPath).first - if testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) || testEntryPointPath == nil { + if await testLibraryOptions.isExplicitlyEnabled(.swiftTesting, swiftCommandState: swiftCommandState) || testEntryPointPath == nil { let additionalArguments = ["--list-tests"] + CommandLine.arguments.dropFirst() let runner = TestRunner( bundlePaths: testProducts.map(\.binaryPath), @@ -1180,10 +1180,10 @@ final class ParallelTestRunner { } /// Executes the tests spawning parallel workers. Blocks calling thread until all workers are finished. - func run(_ tests: [UnitTest]) throws -> [TestResult] { + func run(_ tests: [UnitTest]) async throws -> [TestResult] { assert(!tests.isEmpty, "There should be at least one test to execute.") - let testEnv = try TestingSupport.constructTestEnvironment( + let testEnv = try await TestingSupport.constructTestEnvironment( toolchain: self.toolchain, destinationBuildParameters: self.productsBuildParameters, sanitizers: self.buildOptions.sanitizers, @@ -1495,8 +1495,8 @@ private func _escapeForXML(_ character: Character) -> String { extension SwiftCommandState { func buildParametersForTest( options: TestCommandOptions - ) throws -> (productsBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters) { - try self.buildParametersForTest( + ) async throws -> (productsBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters) { + try await self.buildParametersForTest( enableCodeCoverage: options.enableCodeCoverage, enableTestability: options.enableTestableImports, shouldSkipBuilding: options.sharedOptions.shouldSkipBuilding, diff --git a/Sources/Commands/Utilities/APIDigester.swift b/Sources/Commands/Utilities/APIDigester.swift index 85f3dab6e03..1cae9abe112 100644 --- a/Sources/Commands/Utilities/APIDigester.swift +++ b/Sources/Commands/Utilities/APIDigester.swift @@ -114,7 +114,7 @@ struct APIDigesterBaselineDumper { try workingCopy.checkout(revision: baselineRevision) // Create the workspace for this package. - let workspace = try Workspace( + let workspace = try await Workspace.create( forRootPackage: baselinePackageRoot, cancellator: swiftCommandState.cancellator ) diff --git a/Sources/Commands/Utilities/PluginDelegate.swift b/Sources/Commands/Utilities/PluginDelegate.swift index e5e82f10126..7902165c742 100644 --- a/Sources/Commands/Utilities/PluginDelegate.swift +++ b/Sources/Commands/Utilities/PluginDelegate.swift @@ -117,7 +117,7 @@ final class PluginDelegate: PluginInvocationDelegate { parameters: PluginInvocationBuildParameters ) async throws -> PluginInvocationBuildResult { // Configure the build parameters. - var buildParameters = try self.swiftCommandState.productsBuildParameters + var buildParameters = try await self.swiftCommandState.productsBuildParameters switch parameters.configuration { case .debug: buildParameters.configuration = .debug @@ -221,8 +221,8 @@ final class PluginDelegate: PluginInvocationDelegate { ) async throws -> PluginInvocationTestResult { // Build the tests. Ideally we should only build those that match the subset, but we don't have a way to know // which ones they are until we've built them and can examine the binaries. - let toolchain = try swiftCommandState.getHostToolchain() - var toolsBuildParameters = try swiftCommandState.toolsBuildParameters + let toolchain = try await swiftCommandState.getHostToolchain() + var toolsBuildParameters = try await swiftCommandState.toolsBuildParameters toolsBuildParameters.testingParameters.explicitlyEnabledTestability = true toolsBuildParameters.testingParameters.enableCodeCoverage = parameters.enableCodeCoverage let buildSystem = try await swiftCommandState.createBuildSystem( @@ -237,7 +237,7 @@ final class PluginDelegate: PluginInvocationDelegate { } // Construct the environment we'll pass down to the tests. - let testEnvironment = try TestingSupport.constructTestEnvironment( + let testEnvironment = try await TestingSupport.constructTestEnvironment( toolchain: toolchain, destinationBuildParameters: toolsBuildParameters, sanitizers: swiftCommandState.options.build.sanitizers, @@ -249,7 +249,7 @@ final class PluginDelegate: PluginInvocationDelegate { var numFailedTests = 0 for testProduct in await buildSystem.builtTestProducts { // Get the test suites in the bundle. Each is just a container for test cases. - let testSuites = try TestingSupport.getTestSuites( + let testSuites = try await TestingSupport.getTestSuites( fromTestAt: testProduct.bundlePath, swiftCommandState: swiftCommandState, enableCodeCoverage: parameters.enableCodeCoverage, @@ -397,8 +397,8 @@ final class PluginDelegate: PluginInvocationDelegate { let buildResult = try await buildSystem.build(subset: .target(targetName), buildOutputs: [.symbolGraph(options), .buildPlan]) if let symbolGraph = buildResult.symbolGraph { - let path = (try swiftCommandState.productsBuildParameters.buildPath) - return PluginInvocationSymbolGraphResult(directoryPath: "\(path)/\(symbolGraph.outputLocationForTarget(targetName, try swiftCommandState.productsBuildParameters).joined(separator:"/"))") + let path = (try await swiftCommandState.productsBuildParameters.buildPath) + return PluginInvocationSymbolGraphResult(directoryPath: "\(path)/\(symbolGraph.outputLocationForTarget(targetName, try await swiftCommandState.productsBuildParameters).joined(separator:"/"))") } else if let buildPlan = buildResult.buildPlan { func lookupDescription( for moduleName: String, @@ -425,7 +425,7 @@ final class PluginDelegate: PluginInvocationDelegate { // Configure the symbol graph extractor. var symbolGraphExtractor = try SymbolGraphExtract( fileSystem: swiftCommandState.fileSystem, - tool: swiftCommandState.getTargetToolchain().getSymbolGraphExtract(), + tool: await swiftCommandState.getTargetToolchain().getSymbolGraphExtract(), observabilityScope: swiftCommandState.observabilityScope ) symbolGraphExtractor.skipSynthesizedMembers = !options.includeSynthesized diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 81b32961376..3f9eba1b9bb 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -76,19 +76,19 @@ enum TestingSupport { shouldSkipBuilding: Bool, experimentalTestOutput: Bool, sanitizers: [Sanitizer] - ) throws -> [AbsolutePath: [TestSuite]] { - let testSuitesByProduct = try testProducts - .map {( - $0.bundlePath, - try Self.getTestSuites( - fromTestAt: $0.bundlePath, - swiftCommandState: swiftCommandState, - enableCodeCoverage: enableCodeCoverage, - shouldSkipBuilding: shouldSkipBuilding, - experimentalTestOutput: experimentalTestOutput, - sanitizers: sanitizers - ) - )} + ) async throws -> [AbsolutePath: [TestSuite]] { + var testSuitesByProduct: [(AbsolutePath, [TestSuite])] = [] + for testProduct in testProducts { + let suites = try await Self.getTestSuites( + fromTestAt: testProduct.bundlePath, + swiftCommandState: swiftCommandState, + enableCodeCoverage: enableCodeCoverage, + shouldSkipBuilding: shouldSkipBuilding, + experimentalTestOutput: experimentalTestOutput, + sanitizers: sanitizers + ) + testSuitesByProduct.append((testProduct.bundlePath, suites)) + } return try Dictionary(throwingUniqueKeysWithValues: testSuitesByProduct) } @@ -109,22 +109,23 @@ enum TestingSupport { shouldSkipBuilding: Bool, experimentalTestOutput: Bool, sanitizers: [Sanitizer] - ) throws -> [TestSuite] { + ) async throws -> [TestSuite] { // Run the correct tool. var args = [String]() #if os(macOS) + let toolchain = try await swiftCommandState.getTargetToolchain() + let env = try await Self.constructTestEnvironment( + toolchain: toolchain, + destinationBuildParameters: swiftCommandState.buildParametersForTest( + enableCodeCoverage: enableCodeCoverage, + shouldSkipBuilding: shouldSkipBuilding, + experimentalTestOutput: experimentalTestOutput + ).productsBuildParameters, + sanitizers: sanitizers, + library: .xctest + ) let data: String = try withTemporaryFile { tempFile in args = [try Self.xctestHelperPath(swiftCommandState: swiftCommandState).pathString, path.pathString, tempFile.path.pathString] - let env = try Self.constructTestEnvironment( - toolchain: try swiftCommandState.getTargetToolchain(), - destinationBuildParameters: swiftCommandState.buildParametersForTest( - enableCodeCoverage: enableCodeCoverage, - shouldSkipBuilding: shouldSkipBuilding, - experimentalTestOutput: experimentalTestOutput - ).productsBuildParameters, - sanitizers: sanitizers, - library: .xctest - ) try Self.runProcessWithExistenceCheck( path: path, fileSystem: swiftCommandState.fileSystem, @@ -136,8 +137,8 @@ enum TestingSupport { return try swiftCommandState.fileSystem.readFileContents(AbsolutePath(tempFile.path)) } #else - let env = try Self.constructTestEnvironment( - toolchain: try swiftCommandState.getTargetToolchain(), + let env = try await Self.constructTestEnvironment( + toolchain: try await swiftCommandState.getTargetToolchain(), destinationBuildParameters: swiftCommandState.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, shouldSkipBuilding: shouldSkipBuilding @@ -182,7 +183,7 @@ enum TestingSupport { destinationBuildParameters buildParameters: BuildParameters, sanitizers: [Sanitizer], library: TestingLibrary - ) throws -> Environment { + ) async throws -> Environment { var env = Environment.current // If the standard output or error stream is NOT a TTY, set the NO_COLOR @@ -240,7 +241,7 @@ enum TestingSupport { // Add the sdk platform path if we have it. // Since XCTestHelper targets macOS, we need the macOS platform paths here. - if let sdkPlatformPaths = try? SwiftSDK.sdkPlatformPaths(for: .macOS) { + if let sdkPlatformPaths = try? await SwiftSDK.sdkPlatformPaths(for: .macOS) { // appending since we prefer the user setting (if set) to the one we inject for frameworkPath in sdkPlatformPaths.frameworks { env.appendPath(key: "DYLD_FRAMEWORK_PATH", value: frameworkPath.pathString) @@ -282,16 +283,16 @@ extension SwiftCommandState { enableTestability: Bool? = nil, shouldSkipBuilding: Bool = false, experimentalTestOutput: Bool = false - ) throws -> (productsBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters) { + ) async throws -> (productsBuildParameters: BuildParameters, toolsBuildParameters: BuildParameters) { let productsBuildParameters = buildParametersForTest( - modifying: try productsBuildParameters, + modifying: try await productsBuildParameters, enableCodeCoverage: enableCodeCoverage, enableTestability: enableTestability, shouldSkipBuilding: shouldSkipBuilding, experimentalTestOutput: experimentalTestOutput ) let toolsBuildParameters = buildParametersForTest( - modifying: try toolsBuildParameters, + modifying: try await toolsBuildParameters, enableCodeCoverage: enableCodeCoverage, enableTestability: enableTestability, shouldSkipBuilding: shouldSkipBuilding, diff --git a/Sources/CoreCommands/BuildSystemSupport.swift b/Sources/CoreCommands/BuildSystemSupport.swift index b579d11c3fe..16427c8ea13 100644 --- a/Sources/CoreCommands/BuildSystemSupport.swift +++ b/Sources/CoreCommands/BuildSystemSupport.swift @@ -46,9 +46,21 @@ private struct NativeBuildSystemFactory: BuildSystemFactory { } else { false } + let finalProductsBuildParameters: BuildParameters + if let productsBuildParameters { + finalProductsBuildParameters = productsBuildParameters + } else { + finalProductsBuildParameters = try await self.swiftCommandState.productsBuildParameters + } + let finalToolsBuildParameters: BuildParameters + if let toolsBuildParameters { + finalToolsBuildParameters = toolsBuildParameters + } else { + finalToolsBuildParameters = try await self.swiftCommandState.toolsBuildParameters + } return try BuildOperation( - productsBuildParameters: try productsBuildParameters ?? self.swiftCommandState.productsBuildParameters, - toolsBuildParameters: try toolsBuildParameters ?? self.swiftCommandState.toolsBuildParameters, + productsBuildParameters: finalProductsBuildParameters, + toolsBuildParameters: finalToolsBuildParameters, cacheBuildManifest: cacheBuildManifest, packageGraphLoader: packageGraphLoader ?? { try await self.swiftCommandState.loadPackageGraph( @@ -58,8 +70,8 @@ private struct NativeBuildSystemFactory: BuildSystemFactory { ) }, pluginConfiguration: .init( - scriptRunner: self.swiftCommandState.getPluginScriptRunner(), - workDirectory: try self.swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory, + scriptRunner: try await self.swiftCommandState.getPluginScriptRunner(), + workDirectory: try await self.swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory, disableSandbox: self.swiftCommandState.shouldDisableSandbox ), scratchDirectory: self.swiftCommandState.scratchDirectory, @@ -88,9 +100,15 @@ private struct XcodeBuildSystemFactory: BuildSystemFactory { logLevel: Diagnostic.Severity?, observabilityScope: ObservabilityScope?, delegate: BuildSystemDelegate? - ) throws -> any BuildSystem { + ) async throws -> any BuildSystem { + let finalProductsBuildParameters: BuildParameters + if let productsBuildParameters { + finalProductsBuildParameters = productsBuildParameters + } else { + finalProductsBuildParameters = try await self.swiftCommandState.productsBuildParameters + } return try XcodeBuildSystem( - buildParameters: productsBuildParameters ?? self.swiftCommandState.productsBuildParameters, + buildParameters: finalProductsBuildParameters, packageGraphLoader: packageGraphLoader ?? { try await self.swiftCommandState.loadPackageGraph( explicitProduct: explicitProduct, @@ -120,9 +138,15 @@ private struct SwiftBuildSystemFactory: BuildSystemFactory { logLevel: Diagnostic.Severity?, observabilityScope: ObservabilityScope?, delegate: BuildSystemDelegate? - ) throws -> any BuildSystem { + ) async throws -> any BuildSystem { + let finalProductsBuildParameters: BuildParameters + if let productsBuildParameters { + finalProductsBuildParameters = productsBuildParameters + } else { + finalProductsBuildParameters = try await self.swiftCommandState.productsBuildParameters + } return try SwiftBuildSystem( - buildParameters: productsBuildParameters ?? self.swiftCommandState.productsBuildParameters, + buildParameters: finalProductsBuildParameters, packageGraphLoader: packageGraphLoader ?? { try await self.swiftCommandState.loadPackageGraph( explicitProduct: explicitProduct, @@ -136,8 +160,8 @@ private struct SwiftBuildSystemFactory: BuildSystemFactory { fileSystem: self.swiftCommandState.fileSystem, observabilityScope: observabilityScope ?? self.swiftCommandState.observabilityScope, pluginConfiguration: .init( - scriptRunner: self.swiftCommandState.getPluginScriptRunner(), - workDirectory: try self.swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory, + scriptRunner: try await self.swiftCommandState.getPluginScriptRunner(), + workDirectory: try await self.swiftCommandState.getActiveWorkspace().location.pluginWorkingDirectory, disableSandbox: self.swiftCommandState.shouldDisableSandbox ), delegate: delegate diff --git a/Sources/CoreCommands/Options.swift b/Sources/CoreCommands/Options.swift index 649c2b0d44d..43495eb90dd 100644 --- a/Sources/CoreCommands/Options.swift +++ b/Sources/CoreCommands/Options.swift @@ -664,13 +664,13 @@ public struct TestLibraryOptions: ParsableArguments { /// It is intentional that `isEnabled()` is not simply this function with a /// default value for the `default` argument. There's no "true" default /// value to use; it depends on the semantics the caller is interested in. - private func isEnabled(_ library: TestingLibrary, `default`: Bool, swiftCommandState: SwiftCommandState) -> Bool { + private func isEnabled(_ library: TestingLibrary, `default`: Bool, swiftCommandState: SwiftCommandState) async -> Bool { switch library { case .xctest: if let explicitlyEnableXCTestSupport { return explicitlyEnableXCTestSupport } - if let toolchain = try? swiftCommandState.getHostToolchain(), + if let toolchain = try? await swiftCommandState.getHostToolchain(), toolchain.swiftSDK.xctestSupport == .supported { return `default` } @@ -681,13 +681,13 @@ public struct TestLibraryOptions: ParsableArguments { } /// Test whether or not a given library is enabled. - public func isEnabled(_ library: TestingLibrary, swiftCommandState: SwiftCommandState) -> Bool { - isEnabled(library, default: true, swiftCommandState: swiftCommandState) + public func isEnabled(_ library: TestingLibrary, swiftCommandState: SwiftCommandState) async -> Bool { + await isEnabled(library, default: true, swiftCommandState: swiftCommandState) } /// Test whether or not a given library was explicitly enabled by the developer. - public func isExplicitlyEnabled(_ library: TestingLibrary, swiftCommandState: SwiftCommandState) -> Bool { - isEnabled(library, default: false, swiftCommandState: swiftCommandState) + public func isExplicitlyEnabled(_ library: TestingLibrary, swiftCommandState: SwiftCommandState) async -> Bool { + await isEnabled(library, default: false, swiftCommandState: swiftCommandState) } } diff --git a/Sources/CoreCommands/SwiftCommandState.swift b/Sources/CoreCommands/SwiftCommandState.swift index 58e6db5b227..d35472d7f5f 100644 --- a/Sources/CoreCommands/SwiftCommandState.swift +++ b/Sources/CoreCommands/SwiftCommandState.swift @@ -114,13 +114,13 @@ extension _SwiftCommand { } public protocol SwiftCommand: ParsableCommand, _SwiftCommand { - func run(_ swiftCommandState: SwiftCommandState) throws + func run(_ swiftCommandState: SwiftCommandState) async throws } extension SwiftCommand { public static var _errorLabel: String { "error" } - public func run() throws { + public func run() async throws { let swiftCommandState = try SwiftCommandState( options: globalOptions, toolWorkspaceConfiguration: self.toolWorkspaceConfiguration, @@ -135,7 +135,7 @@ extension SwiftCommand { swiftCommandState.buildSystemProvider = try buildSystemProvider(swiftCommandState) var toolError: Error? = .none do { - try self.run(swiftCommandState) + try await self.run(swiftCommandState) if swiftCommandState.observabilityScope.errorsReported || swiftCommandState.executionStatus == .failure { throw ExitCode.failure } @@ -467,7 +467,7 @@ public final class SwiftCommandState { } /// Returns the currently active workspace. - public func getActiveWorkspace(emitDeprecatedConfigurationWarning: Bool = false, enableAllTraits: Bool = false) throws -> Workspace { + public func getActiveWorkspace(emitDeprecatedConfigurationWarning: Bool = false, enableAllTraits: Bool = false) async throws -> Workspace { if var workspace = _workspace { // if we decide to override the trait configuration, we can resolve accordingly for // calls like createSymbolGraphForPlugin. @@ -491,7 +491,7 @@ public final class SwiftCommandState { self.observabilityHandler.progress, self.observabilityHandler.prompt ) - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: self.fileSystem, location: .init( scratchDirectory: self.scratchDirectory, @@ -554,7 +554,7 @@ public final class SwiftCommandState { // Create manifest loader for manifest cache let manifestLoader = ManifestLoader( - toolchain: try self.getHostToolchain(), + toolchain: try await self.getHostToolchain(), cacheDir: Workspace.DefaultLocations.manifestsDirectory(at: self.sharedCacheDirectory), importRestrictions: nil, delegate: nil, @@ -589,7 +589,7 @@ public final class SwiftCommandState { } public func getRootPackageInformation(_ enableAllTraits: Bool = false) async throws -> (dependencies: [PackageIdentity: [PackageIdentity]], targets: [PackageIdentity: [String]]) { - let workspace = try self.getActiveWorkspace(enableAllTraits: enableAllTraits) + let workspace = try await self.getActiveWorkspace(enableAllTraits: enableAllTraits) let root = try self.getWorkspaceRoot() let rootManifests = try await workspace.loadRootManifests( packages: root.packages, @@ -714,7 +714,7 @@ public final class SwiftCommandState { /// Resolve the dependencies. public func resolve() async throws { - let workspace = try getActiveWorkspace() + let workspace = try await getActiveWorkspace() let root = try getWorkspaceRoot() try await workspace.resolve( @@ -760,7 +760,7 @@ public final class SwiftCommandState { testEntryPointPath: AbsolutePath? = nil ) async throws -> ModulesGraph { do { - let workspace = try getActiveWorkspace(enableAllTraits: enableAllTraits) + let workspace = try await getActiveWorkspace(enableAllTraits: enableAllTraits) // Fetch and load the package graph. let graph = try await workspace.loadPackageGraph( @@ -782,13 +782,19 @@ public final class SwiftCommandState { } } - public func getPluginScriptRunner(customPluginsDir: AbsolutePath? = .none) throws -> PluginScriptRunner { - let pluginsDir = try customPluginsDir ?? self.getActiveWorkspace().location.pluginWorkingDirectory + public func getPluginScriptRunner(customPluginsDir: AbsolutePath? = .none) async throws -> PluginScriptRunner { + let pluginsDir: AbsolutePath + if let customPluginsDir { + pluginsDir = customPluginsDir + } else { + pluginsDir = try await self.getActiveWorkspace().location.pluginWorkingDirectory + } let cacheDir = pluginsDir.appending("cache") + let hostToolchain = try await self.getHostToolchain() let pluginScriptRunner = try DefaultPluginScriptRunner( fileSystem: self.fileSystem, cacheDir: cacheDir, - toolchain: self.getHostToolchain(), + toolchain: hostToolchain, extraPluginSwiftCFlags: self.options.build.pluginSwiftCFlags, enableSandbox: !self.shouldDisableSandbox, verboseOutput: self.logLevel <= .info @@ -800,15 +806,99 @@ public final class SwiftCommandState { /// Returns the user toolchain to compile the actual product. public func getTargetToolchain() throws -> UserToolchain { - try self._targetToolchain.get() + fatalError("getTargetToolchain() is deprecated, use async version instead") } - public func getHostToolchain() throws -> UserToolchain { - try self._hostToolchain.get() + /// Returns the user toolchain to compile the actual product (async version). + public func getTargetToolchain() async throws -> UserToolchain { + let swiftSDK: SwiftSDK + let hostSwiftSDK: SwiftSDK + + let hostToolchain = try await getHostToolchain() + hostSwiftSDK = hostToolchain.swiftSDK + + if self.options.build.deprecatedSwiftSDKSelector != nil { + self.observabilityScope.emit( + warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead." + ) + } + + let store = SwiftSDKBundleStore( + swiftSDKsDirectory: self.sharedSwiftSDKsDirectory, + hostToolchainBinDir: hostToolchain.swiftCompilerPath.parentDirectory, + fileSystem: self.fileSystem, + observabilityScope: self.observabilityScope, + outputHandler: { print($0.description) } + ) + + swiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( + hostSwiftSDK: hostSwiftSDK, + hostTriple: hostToolchain.targetTriple, + customToolsets: self.options.locations.toolsetPaths, + customCompileDestination: self.options.locations.customCompileDestination, + customCompileTriple: self.options.build.customCompileTriple, + customCompileToolchain: self.options.build.customCompileToolchain, + customCompileSDK: self.options.build.customCompileSDK, + swiftSDKSelector: self.options.build.swiftSDKSelector ?? self.options.build.deprecatedSwiftSDKSelector, + architectures: self.options.build.architectures, + store: store, + observabilityScope: self.observabilityScope, + fileSystem: self.fileSystem + ) + + // Check if we ended up with the host toolchain. + if hostSwiftSDK == swiftSDK { + return hostToolchain + } + + return try await UserToolchain.create(swiftSDK: swiftSDK, environment: self.environment, fileSystem: self.fileSystem) } - func getManifestLoader() throws -> ManifestLoader { - try self._manifestLoader.get() + public func getHostToolchain() async throws -> UserToolchain { + var hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync( + environment: self.environment, + observabilityScope: self.observabilityScope + ) + hostSwiftSDK.targetTriple = self.hostTriple + + return try await UserToolchain.create( + swiftSDK: hostSwiftSDK, + environment: self.environment, + customTargetInfo: targetInfo, + fileSystem: self.fileSystem + ) + } + + func getManifestLoader() async throws -> ManifestLoader { + let cachePath: AbsolutePath? = switch ( + self.options.caching.shouldDisableManifestCaching, + self.options.caching.manifestCachingMode + ) { + case (true, _): + // backwards compatibility + .none + case (false, .none): + .none + case (false, .local): + self.scratchDirectory + case (false, .shared): + Workspace.DefaultLocations.manifestsDirectory(at: self.sharedCacheDirectory) + } + + var extraManifestFlags = self.options.build.manifestFlags + if self.logLevel <= .info { + extraManifestFlags.append("-v") + } + + return try ManifestLoader( + // Always use the host toolchain's resources for parsing manifest. + toolchain: await self.getHostToolchain(), + isManifestSandboxEnabled: !self.shouldDisableSandbox, + cacheDir: cachePath, + extraManifestFlags: extraManifestFlags, + importRestrictions: .none, + pruneDependencies: self.options.resolver.pruneDependencies + ) } public func canUseCachedBuildManifest(_ traitConfiguration: TraitConfiguration = .default) async throws -> Bool { @@ -816,7 +906,7 @@ public final class SwiftCommandState { return false } - let buildParameters = try self.productsBuildParameters + let buildParameters = try await self.productsBuildParameters let haveBuildManifestAndDescription = self.fileSystem.exists(buildParameters.llbuildManifest) && self.fileSystem.exists(buildParameters.buildDescriptionPath) @@ -857,7 +947,12 @@ public final class SwiftCommandState { guard let buildSystemProvider else { fatalError("build system provider not initialized") } - var productsParameters = try productsBuildParameters ?? self.productsBuildParameters + var productsParameters: BuildParameters + if let productsBuildParameters { + productsParameters = productsBuildParameters + } else { + productsParameters = try await self.productsBuildParameters + } productsParameters.linkingParameters.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib let buildSystem = try await buildSystemProvider.createBuildSystem( kind: explicitBuildSystem ?? self.options.build.buildSystem, @@ -962,130 +1057,21 @@ public final class SwiftCommandState { /// Return the build parameters for the host toolchain. public var toolsBuildParameters: BuildParameters { - get throws { - try self._toolsBuildParameters.get() + get async throws { + // Tools need to do a full build + try self._buildParams(toolchain: await self.getHostToolchain(), destination: .host, prepareForIndexing: false) } } - private lazy var _toolsBuildParameters: Result = Result(catching: { - // Tools need to do a full build - try self._buildParams(toolchain: self.getHostToolchain(), destination: .host, prepareForIndexing: false) - }) - public var productsBuildParameters: BuildParameters { - get throws { - try self._productsBuildParameters.get() - } - } - - private lazy var _productsBuildParameters: Result = Result(catching: { - try self._buildParams( - toolchain: self.getTargetToolchain(), - destination: .target, - prepareForIndexing: self.options.build.prepareForIndexing - ) - }) - - /// Lazily compute the target toolchain. - private lazy var _targetToolchain: Result = { - let swiftSDK: SwiftSDK - let hostSwiftSDK: SwiftSDK - do { - let hostToolchain = try _hostToolchain.get() - hostSwiftSDK = hostToolchain.swiftSDK - - if self.options.build.deprecatedSwiftSDKSelector != nil { - self.observabilityScope.emit( - warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead." - ) - } - - let store = SwiftSDKBundleStore( - swiftSDKsDirectory: self.sharedSwiftSDKsDirectory, - hostToolchainBinDir: hostToolchain.swiftCompilerPath.parentDirectory, - fileSystem: self.fileSystem, - observabilityScope: self.observabilityScope, - outputHandler: { print($0.description) } + get async throws { + try self._buildParams( + toolchain: await self.getTargetToolchain(), + destination: .target, + prepareForIndexing: self.options.build.prepareForIndexing ) - - swiftSDK = try SwiftSDK.deriveTargetSwiftSDK( - hostSwiftSDK: hostSwiftSDK, - hostTriple: hostToolchain.targetTriple, - customToolsets: self.options.locations.toolsetPaths, - customCompileDestination: self.options.locations.customCompileDestination, - customCompileTriple: self.options.build.customCompileTriple, - customCompileToolchain: self.options.build.customCompileToolchain, - customCompileSDK: self.options.build.customCompileSDK, - swiftSDKSelector: self.options.build.swiftSDKSelector ?? self.options.build.deprecatedSwiftSDKSelector, - architectures: self.options.build.architectures, - store: store, - observabilityScope: self.observabilityScope, - fileSystem: self.fileSystem - ) - } catch { - return .failure(error) - } - // Check if we ended up with the host toolchain. - if hostSwiftSDK == swiftSDK { - return self._hostToolchain - } - - return Result(catching: { - try UserToolchain( - swiftSDK: swiftSDK, - environment: self.environment, - customTargetInfo: targetInfo, - fileSystem: self.fileSystem) - }) - }() - - /// Lazily compute the host toolchain used to compile the package description. - private lazy var _hostToolchain: Result = Result(catching: { - var hostSwiftSDK = try SwiftSDK.hostSwiftSDK( - environment: self.environment, - observabilityScope: self.observabilityScope - ) - hostSwiftSDK.targetTriple = self.hostTriple - - return try UserToolchain( - swiftSDK: hostSwiftSDK, - environment: self.environment, - customTargetInfo: targetInfo, - fileSystem: self.fileSystem - ) - }) - - private lazy var _manifestLoader: Result = Result(catching: { - let cachePath: AbsolutePath? = switch ( - self.options.caching.shouldDisableManifestCaching, - self.options.caching.manifestCachingMode - ) { - case (true, _): - // backwards compatibility - .none - case (false, .none): - .none - case (false, .local): - self.scratchDirectory - case (false, .shared): - Workspace.DefaultLocations.manifestsDirectory(at: self.sharedCacheDirectory) } - - var extraManifestFlags = self.options.build.manifestFlags - if self.logLevel <= .info { - extraManifestFlags.append("-v") - } - - return try ManifestLoader( - // Always use the host toolchain's resources for parsing manifest. - toolchain: self.getHostToolchain(), - isManifestSandboxEnabled: !self.shouldDisableSandbox, - cacheDir: cachePath, - extraManifestFlags: extraManifestFlags, - importRestrictions: .none, - pruneDependencies: self.options.resolver.pruneDependencies - ) - }) + } /// An enum indicating the execution status of run commands. public enum ExecutionStatus { diff --git a/Sources/PackageCollectionsCommand/PackageCollectionsCommand.swift b/Sources/PackageCollectionsCommand/PackageCollectionsCommand.swift index e054d54a71b..657c0b29b33 100644 --- a/Sources/PackageCollectionsCommand/PackageCollectionsCommand.swift +++ b/Sources/PackageCollectionsCommand/PackageCollectionsCommand.swift @@ -385,7 +385,7 @@ private extension ParsableCommand { _ swiftCommandState: SwiftCommandState, handler: (_ collections: PackageCollectionsProtocol) async throws -> T ) async throws -> T { - _ = try? swiftCommandState.getActiveWorkspace(emitDeprecatedConfigurationWarning: true) + _ = try? await swiftCommandState.getActiveWorkspace(emitDeprecatedConfigurationWarning: true) let collections = PackageCollections( configuration: .init( configurationDirectory: swiftCommandState.sharedConfigurationDirectory, diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index bef655063af..8964566afe7 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -16,6 +16,7 @@ import TSCBasic import class Basics.AsyncProcess + import struct TSCUtility.Version /// Errors related to Swift SDKs. @@ -520,16 +521,16 @@ public struct SwiftSDK: Equatable { } /// The Swift SDK describing the host platform. - @available(*, deprecated, renamed: "hostSwiftSDK") + @available(*, deprecated, renamed: "hostSwiftSDKAsync") public static func hostDestination( _ binDir: Basics.AbsolutePath? = nil, originalWorkingDirectory: Basics.AbsolutePath? = nil, environment: Environment - ) throws -> SwiftSDK { - try self.hostSwiftSDK(binDir, environment: environment) + ) async throws -> SwiftSDK { + try await self.hostSwiftSDKAsync(binDir, environment: environment) } - /// The Swift SDK for the host platform. + /// The Swift SDK for the host platform (synchronous version). public static func hostSwiftSDK( _ binDir: Basics.AbsolutePath? = nil, environment: Environment = .current, @@ -544,6 +545,21 @@ public struct SwiftSDK: Equatable { ) } + /// The Swift SDK for the host platform (asynchronous version). + public static func hostSwiftSDKAsync( + _ binDir: Basics.AbsolutePath? = nil, + environment: Environment = .current, + observabilityScope: ObservabilityScope? = nil, + fileSystem: any FileSystem = Basics.localFileSystem + ) async throws -> SwiftSDK { + try await self.systemSwiftSDK( + binDir, + environment: environment, + observabilityScope: observabilityScope, + fileSystem: fileSystem + ) + } + /// A default Swift SDK on the host. /// /// Equivalent to `hostSwiftSDK`, except on macOS, where passing a non-nil `darwinPlatformOverride` @@ -555,24 +571,69 @@ public struct SwiftSDK: Equatable { fileSystem: any FileSystem = Basics.localFileSystem, darwinPlatformOverride: DarwinPlatform? = nil ) throws -> SwiftSDK { - // Select the correct binDir. - if environment["SWIFTPM_CUSTOM_BINDIR"] != nil { - print("SWIFTPM_CUSTOM_BINDIR was deprecated in favor of SWIFTPM_CUSTOM_BIN_DIR") - } - let customBinDir = (environment["SWIFTPM_CUSTOM_BIN_DIR"] ?? environment["SWIFTPM_CUSTOM_BINDIR"]) - .flatMap { try? Basics.AbsolutePath(validating: $0) } - let binDir = try customBinDir ?? binDir ?? SwiftSDK.hostBinDir(fileSystem: fileSystem) + #if os(macOS) + let darwinPlatform = darwinPlatformOverride ?? .macOS + let sdkPath = try Self.getSDKPath( + for: darwinPlatform, + environment: environment + ) + let sdkPaths = try? SwiftSDK.sdkPlatformPaths(for: darwinPlatform, environment: environment) + #else + let sdkPath: Basics.AbsolutePath? = nil + let sdkPaths: PlatformPaths? = nil + #endif - let sdkPath: Basics.AbsolutePath? + return try Self.buildSwiftSDK( + binDir: binDir, + sdkPath: sdkPath, + sdkPaths: sdkPaths, + environment: environment, + fileSystem: fileSystem + ) + } + + /// A default Swift SDK on the host. + /// + /// Equivalent to `hostSwiftSDK`, except on macOS, where passing a non-nil `darwinPlatformOverride` + /// will result in the SDK for the corresponding Darwin platform. + private static func systemSwiftSDK( + _ binDir: Basics.AbsolutePath? = nil, + environment: Environment = .current, + observabilityScope: ObservabilityScope? = nil, + fileSystem: any FileSystem = Basics.localFileSystem, + darwinPlatformOverride: DarwinPlatform? = nil + ) async throws -> SwiftSDK { #if os(macOS) let darwinPlatform = darwinPlatformOverride ?? .macOS - // Get the SDK. + let sdkPath = try await Self.getSDKPath( + for: darwinPlatform, + environment: environment + ) + let sdkPaths = try? await SwiftSDK.sdkPlatformPaths(for: darwinPlatform, environment: environment) + #else + let sdkPath: Basics.AbsolutePath? = nil + let sdkPaths: PlatformPaths? = nil + #endif + + return try Self.buildSwiftSDK( + binDir: binDir, + sdkPath: sdkPath, + sdkPaths: sdkPaths, + environment: environment, + fileSystem: fileSystem + ) + } + + /// Helper to get the SDK path for a Darwin platform (sync version). + private static func getSDKPath( + for darwinPlatform: DarwinPlatform, + environment: Environment + ) throws -> Basics.AbsolutePath { if let value = environment["SDKROOT"] { - sdkPath = try AbsolutePath(validating: value) + return try AbsolutePath(validating: value) } else if let value = environment[EnvironmentKey("SWIFTPM_SDKROOT_\(darwinPlatform.xcrunName)")] { - sdkPath = try AbsolutePath(validating: value) + return try AbsolutePath(validating: value) } else { - // No value in env, so search for it. let sdkPathStr = try AsyncProcess.checkNonZeroExit( arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-path"], environment: environment @@ -580,30 +641,61 @@ public struct SwiftSDK: Equatable { guard !sdkPathStr.isEmpty else { throw SwiftSDKError.invalidInstallation("default SDK not found") } - sdkPath = try AbsolutePath(validating: sdkPathStr) + return try AbsolutePath(validating: sdkPathStr) } - #else - sdkPath = nil - #endif + } + + /// Helper to get the SDK path for a Darwin platform (async version). + private static func getSDKPath( + for darwinPlatform: DarwinPlatform, + environment: Environment + ) async throws -> Basics.AbsolutePath { + if let value = environment["SDKROOT"] { + return try AbsolutePath(validating: value) + } else if let value = environment[EnvironmentKey("SWIFTPM_SDKROOT_\(darwinPlatform.xcrunName)")] { + return try AbsolutePath(validating: value) + } else { + let sdkPathStr = try await AsyncProcess.checkNonZeroExit( + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-path"], + environment: environment + ).spm_chomp() + guard !sdkPathStr.isEmpty else { + throw SwiftSDKError.invalidInstallation("default SDK not found") + } + return try AbsolutePath(validating: sdkPathStr) + } + } + + /// Helper to build a SwiftSDK from resolved paths. + private static func buildSwiftSDK( + binDir: Basics.AbsolutePath?, + sdkPath: Basics.AbsolutePath?, + sdkPaths: PlatformPaths?, + environment: Environment, + fileSystem: any FileSystem + ) throws -> SwiftSDK { + // Select the correct binDir. + if environment["SWIFTPM_CUSTOM_BINDIR"] != nil { + print("SWIFTPM_CUSTOM_BINDIR was deprecated in favor of SWIFTPM_CUSTOM_BIN_DIR") + } + let customBinDir = (environment["SWIFTPM_CUSTOM_BIN_DIR"] ?? environment["SWIFTPM_CUSTOM_BINDIR"]) + .flatMap { try? Basics.AbsolutePath(validating: $0) } + let binDir = try customBinDir ?? binDir ?? SwiftSDK.hostBinDir(fileSystem: fileSystem) // Compute common arguments for clang and swift. let xctestSupport: XCTestSupport var extraCCFlags: [String] = [] var extraSwiftCFlags: [String] = [] - #if os(macOS) - do { - let sdkPaths = try SwiftSDK.sdkPlatformPaths(for: darwinPlatform, environment: environment) + + if let sdkPaths { extraCCFlags.append(contentsOf: sdkPaths.frameworks.flatMap { ["-F", $0.pathString] }) extraSwiftCFlags.append(contentsOf: sdkPaths.frameworks.flatMap { ["-F", $0.pathString] }) extraSwiftCFlags.append(contentsOf: sdkPaths.libraries.flatMap { ["-I", $0.pathString] }) extraSwiftCFlags.append(contentsOf: sdkPaths.libraries.flatMap { ["-L", $0.pathString] }) xctestSupport = .supported - } catch { - xctestSupport = .unsupported(reason: String(describing: error)) + } else { + xctestSupport = .supported } - #else - xctestSupport = .supported - #endif #if !os(Windows) extraCCFlags += ["-fPIC"] @@ -639,8 +731,8 @@ public struct SwiftSDK: Equatable { @available(*, deprecated, message: "use sdkPlatformPaths(for:) instead") public static func sdkPlatformFrameworkPaths( environment: Environment = .current - ) throws -> (fwk: Basics.AbsolutePath, lib: Basics.AbsolutePath) { - let paths = try sdkPlatformPaths(for: .macOS, environment: environment) + ) async throws -> (fwk: Basics.AbsolutePath, lib: Basics.AbsolutePath) { + let paths = try await sdkPlatformPaths(for: .macOS, environment: environment) guard let frameworkPath = paths.frameworks.first else { throw StringError("could not determine SDK platform framework path") } @@ -658,12 +750,15 @@ public struct SwiftSDK: Equatable { if let path = _sdkPlatformFrameworkPath[darwinPlatform] { return path } - let platformPath = try environment[ - EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.xcrunName)") - ] ?? AsyncProcess.checkNonZeroExit( - arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-platform-path"], - environment: environment - ).spm_chomp() + let platformPath: String + if let envValue = environment[EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.xcrunName)")] { + platformPath = envValue + } else { + platformPath = try AsyncProcess.checkNonZeroExit( + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-platform-path"], + environment: environment + ).spm_chomp() + } guard !platformPath.isEmpty else { throw StringError("could not determine SDK platform path") @@ -687,25 +782,59 @@ public struct SwiftSDK: Equatable { return sdkPlatformFrameworkPath } - /// Cache storage for sdk platform paths. - private static var _sdkPlatformFrameworkPath: [DarwinPlatform: PlatformPaths] = [:] + /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform. + public static func sdkPlatformPaths( + for darwinPlatform: DarwinPlatform, + environment: Environment = .current + ) async throws -> PlatformPaths { + if let path = _sdkPlatformFrameworkPath[darwinPlatform] { + return path + } + let platformPath: String + if let envValue = environment[EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.xcrunName)")] { + platformPath = envValue + } else { + platformPath = try await AsyncProcess.checkNonZeroExit( + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-platform-path"], + environment: environment + ).spm_chomp() + } + + guard !platformPath.isEmpty else { + throw StringError("could not determine SDK platform path") + } + + // For testing frameworks. + let frameworksPath = try Basics.AbsolutePath(validating: platformPath).appending( + components: "Developer", "Library", "Frameworks" + ) + let privateFrameworksPath = try Basics.AbsolutePath(validating: platformPath).appending( + components: "Developer", "Library", "PrivateFrameworks" + ) + + // For testing libraries. + let librariesPath = try Basics.AbsolutePath(validating: platformPath).appending( + components: "Developer", "usr", "lib" + ) - /// Returns a default Swift SDK for a given target environment - @available(*, deprecated, renamed: "defaultSwiftSDK") - public static func defaultDestination(for triple: Triple, host: SwiftSDK) -> SwiftSDK? { - defaultSwiftSDK(for: triple, hostSDK: host) + let sdkPlatformFrameworkPath = PlatformPaths(frameworks: [frameworksPath, privateFrameworksPath], libraries: [librariesPath]) + _sdkPlatformFrameworkPath[darwinPlatform] = sdkPlatformFrameworkPath + return sdkPlatformFrameworkPath } - /// Returns a default Swift SDK of a given target environment. + /// Cache storage for sdk platform paths. + private static var _sdkPlatformFrameworkPath: [DarwinPlatform: PlatformPaths] = [:] + + /// Returns a default Swift SDK of a given target environment (async version). public static func defaultSwiftSDK( for targetTriple: Triple, hostSDK: SwiftSDK, environment: Environment = .current - ) -> SwiftSDK? { + ) async -> SwiftSDK? { #if os(macOS) if let darwinPlatform = targetTriple.darwinPlatform { // the Darwin SDKs are trivially available on macOS - var sdk = try? self.systemSwiftSDK( + var sdk = try? await self.systemSwiftSDK( hostSDK.toolset.rootPaths.first, environment: environment, darwinPlatformOverride: darwinPlatform @@ -718,7 +847,7 @@ public struct SwiftSDK: Equatable { return nil } - /// Computes the target Swift SDK for the given options. + /// Computes the target Swift SDK for the given options (synchronous version). public static func deriveTargetSwiftSDK( hostSwiftSDK: SwiftSDK, hostTriple: Triple, @@ -733,6 +862,51 @@ public struct SwiftSDK: Equatable { observabilityScope: ObservabilityScope, fileSystem: FileSystem ) throws -> SwiftSDK { + let semaphore = DispatchSemaphore(value: 0) + var result: Result! + + Task { + do { + let sdk = try await deriveTargetSwiftSDKAsync( + hostSwiftSDK: hostSwiftSDK, + hostTriple: hostTriple, + customToolsets: customToolsets, + customCompileDestination: customCompileDestination, + customCompileTriple: customCompileTriple, + customCompileToolchain: customCompileToolchain, + customCompileSDK: customCompileSDK, + swiftSDKSelector: swiftSDKSelector, + architectures: architectures, + store: store, + observabilityScope: observabilityScope, + fileSystem: fileSystem + ) + result = .success(sdk) + } catch { + result = .failure(error) + } + semaphore.signal() + } + + semaphore.wait() + return try result.get() + } + + /// Computes the target Swift SDK for the given options (async version). + public static func deriveTargetSwiftSDKAsync( + hostSwiftSDK: SwiftSDK, + hostTriple: Triple, + customToolsets: [Basics.AbsolutePath] = [], + customCompileDestination: Basics.AbsolutePath? = nil, + customCompileTriple: Triple? = nil, + customCompileToolchain: Basics.AbsolutePath? = nil, + customCompileSDK: Basics.AbsolutePath? = nil, + swiftSDKSelector: String? = nil, + architectures: [String] = [], + store: SwiftSDKBundleStore, + observabilityScope: ObservabilityScope, + fileSystem: FileSystem + ) async throws -> SwiftSDK { var swiftSDK: SwiftSDK var isBasedOnHostSDK: Bool = false @@ -755,7 +929,7 @@ public struct SwiftSDK: Equatable { throw SwiftSDKError.noSwiftSDKDecoded(customDestination) } } else if let targetTriple = customCompileTriple, - let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) + let targetSwiftSDK = await SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { swiftSDK = targetSwiftSDK } else if let swiftSDKSelector { @@ -765,7 +939,7 @@ public struct SwiftSDK: Equatable { // If a user-installed bundle for the selector doesn't exist, check if the // selector is recognized as a default SDK. if let targetTriple = try? Triple(swiftSDKSelector), - let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { + let defaultSDK = await SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { swiftSDK = defaultSDK } else { throw error diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 86149e2d997..0c89cd0ee34 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -81,11 +81,7 @@ public final class UserToolchain: Toolchain { public let targetTriple: Basics.Triple - private let _targetInfo: JSON? - private lazy var targetInfo: JSON? = { - // Only call out to the swift compiler to fetch the target info when necessary - try? _targetInfo ?? Self.getTargetInfo(swiftCompiler: swiftCompilerPath) - }() + private let targetInfo: JSON? // A version string that can be used to identify the swift compiler version public lazy var swiftCompilerVersion: String? = { @@ -200,6 +196,27 @@ public final class UserToolchain: Toolchain { } } + private static func getTargetInfo(swiftCompiler: AbsolutePath) async throws -> JSON { + // Call the compiler to get the target info JSON. + let compilerOutput: String + do { + let result = try await AsyncProcess.popen(args: swiftCompiler.pathString, "-print-target-info") + compilerOutput = try result.utf8Output().spm_chomp() + } catch { + throw InternalError( + "Failed to load target info (\(error.interpolationDescription))" + ) + } + // Parse the compiler's JSON output. + do { + return try JSON(string: compilerOutput) + } catch { + throw InternalError( + "Failed to parse target info (\(error.interpolationDescription)).\nRaw compiler output: \(compilerOutput)" + ) + } + } + private static func getHostTriple(targetInfo: JSON, versioned: Bool) throws -> Basics.Triple { // Get the triple string from the target info. let tripleString: String @@ -670,22 +687,6 @@ public final class UserToolchain: Toolchain { case custom(searchPaths: [AbsolutePath], useXcrun: Bool = true) } - @available(*, deprecated, message: "use init(swiftSDK:environment:searchStrategy:customLibrariesLocation) instead") - public convenience init( - destination: SwiftSDK, - environment: Environment = .current, - searchStrategy: SearchStrategy = .default, - customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil - ) throws { - try self.init( - swiftSDK: destination, - environment: environment, - searchStrategy: searchStrategy, - customLibrariesLocation: customLibrariesLocation, - fileSystem: localFileSystem - ) - } - public init( swiftSDK: SwiftSDK, environment: Environment = .current, @@ -735,12 +736,17 @@ public final class UserToolchain: Toolchain { var triple: Basics.Triple if let targetTriple = swiftSDK.targetTriple { - self._targetInfo = nil + self.targetInfo = nil triple = targetTriple } else { // targetInfo from the compiler - let targetInfo = try customTargetInfo ?? Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) - self._targetInfo = targetInfo + let targetInfo: JSON + if let customTargetInfo { + targetInfo = customTargetInfo + } else { + targetInfo = try Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) + } + self.targetInfo = targetInfo triple = try swiftSDK.targetTriple ?? Self.getHostTriple(targetInfo: targetInfo, versioned: false) } @@ -892,6 +898,275 @@ public final class UserToolchain: Toolchain { self.fileSystem = fileSystem } + /// Creates a new UserToolchain asynchronously. + /// + /// This is the async variant of the UserToolchain initializer that properly awaits + /// async operations instead of blocking the calling thread. + public static func create( + swiftSDK: SwiftSDK, + environment: Environment = .current, + searchStrategy: SearchStrategy = .default, + customTargetInfo: JSON? = nil, + customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil, + customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil, + fileSystem: any FileSystem = localFileSystem + ) async throws -> UserToolchain { + let envSearchPaths: [AbsolutePath] + let useXcrun: Bool + + switch searchStrategy { + case .default: + // Get the search paths from PATH. + envSearchPaths = getEnvSearchPaths( + pathString: environment[.path], + currentWorkingDirectory: fileSystem.currentWorkingDirectory + ) + useXcrun = !(fileSystem is InMemoryFileSystem) + case .custom(let searchPaths, let useXcrunFlag): + envSearchPaths = searchPaths + useXcrun = useXcrunFlag + } + + let swiftCompilers = try UserToolchain.determineSwiftCompilers( + binDirectories: swiftSDK.toolset.rootPaths, + useXcrun: useXcrun, + environment: environment, + searchPaths: envSearchPaths, + fileSystem: fileSystem + ) + let swiftCompilerPath = swiftCompilers.compile + let architectures = swiftSDK.architectures + + let installedSwiftPMConfiguration: InstalledSwiftPMConfiguration + if let customInstalledSwiftPMConfiguration { + installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration + } else { + let path = swiftCompilerPath.parentDirectory.parentDirectory.appending(components: [ + "share", "pm", "config.json", + ]) + installedSwiftPMConfiguration = try Self.loadJSONResource( + config: path, + type: InstalledSwiftPMConfiguration.self, + default: InstalledSwiftPMConfiguration.default) + } + + var triple: Basics.Triple + let targetInfo: JSON? + if let targetTriple = swiftSDK.targetTriple { + targetInfo = nil + triple = targetTriple + } else { + // targetInfo from the compiler + let computedTargetInfo: JSON + if let customTargetInfo { + computedTargetInfo = customTargetInfo + } else { + computedTargetInfo = try await Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) + } + targetInfo = computedTargetInfo + triple = try swiftSDK.targetTriple ?? Self.getHostTriple(targetInfo: computedTargetInfo, versioned: false) + } + + // Change the triple to the specified arch if there's exactly one of them. + // The Triple property is only looked at by the native build system currently. + if let architectures = architectures, architectures.count == 1 { + let components = triple.tripleString.drop(while: { $0 != "-" }) + triple = try Triple(architectures[0] + components) + } + + let targetTriple = triple + + var swiftCompilerFlags: [String] = [] + var extraLinkerFlags: [String] = [] + + let swiftTestingPath: AbsolutePath? = try Self.deriveSwiftTestingPath( + derivedSwiftCompiler: swiftCompilers.compile, + swiftSDK: swiftSDK, + triple: triple, + environment: environment, + fileSystem: fileSystem + ) + + if triple.isMacOSX, let swiftTestingPath { + // Swift Testing is a framework (e.g. from CommandLineTools) so use -F. + if swiftTestingPath.extension == "framework" { + swiftCompilerFlags += ["-F", swiftTestingPath.pathString] + + // Otherwise Swift Testing is assumed to be a swiftmodule + library, so use -I and -L. + } else { + swiftCompilerFlags += [ + "-I", swiftTestingPath.pathString, + "-L", swiftTestingPath.pathString, + ] + } + } + + // Specify the plugin path for Swift Testing's macro plugin if such a + // path exists in this toolchain. + if let swiftTestingPluginPath = Self.deriveSwiftTestingPluginPath( + derivedSwiftCompiler: swiftCompilers.compile, + fileSystem: fileSystem + ) { + swiftCompilerFlags += ["-plugin-path", swiftTestingPluginPath.pathString] + } + + swiftCompilerFlags += try Self.deriveSwiftCFlags( + triple: triple, + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem + ) + + extraLinkerFlags += swiftSDK.toolset.knownTools[.linker]?.extraCLIOptions ?? [] + + let extraFlags = BuildFlags( + cCompilerFlags: swiftSDK.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [], + cxxCompilerFlags: swiftSDK.toolset.knownTools[.cxxCompiler]?.extraCLIOptions ?? [], + swiftCompilerFlags: swiftCompilerFlags, + linkerFlags: extraLinkerFlags, + xcbuildFlags: swiftSDK.toolset.knownTools[.xcbuild]?.extraCLIOptions ?? []) + + let includeSearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + let librarySearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + + let librarianPath = try swiftSDK.toolset.knownTools[.librarian]?.path ?? UserToolchain.determineLibrarian( + triple: triple, + binDirectories: swiftSDK.toolset.rootPaths, + useXcrun: useXcrun, + environment: environment, + searchPaths: envSearchPaths, + extraSwiftFlags: extraFlags.swiftCompilerFlags, + fileSystem: fileSystem + ) + + var modifiedExtraFlags = extraFlags + + if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { + let sysrootFlags = [triple.isDarwin() ? "-isysroot" : "--sysroot", sdkDir.pathString] + modifiedExtraFlags.cCompilerFlags.insert(contentsOf: sysrootFlags, at: 0) + } + + if triple.isWindows() { + if let root = environment.windowsSDKRoot { + if let settings = WindowsSDKSettings( + reading: root.appending("SDKSettings.plist"), + observabilityScope: nil, + filesystem: fileSystem + ) { + switch settings.defaults.runtime { + case .multithreadedDebugDLL: + // Defines _DEBUG, _MT, and _DLL + // Linker uses MSVCRTD.lib + modifiedExtraFlags.cCompilerFlags += [ + "-D_DEBUG", + "-D_MT", + "-D_DLL", + "-Xclang", + "--dependent-lib=msvcrtd", + ] + + case .multithreadedDLL: + // Defines _MT, and _DLL + // Linker uses MSVCRT.lib + modifiedExtraFlags.cCompilerFlags += ["-D_MT", "-D_DLL", "-Xclang", "--dependent-lib=msvcrt"] + + case .multithreadedDebug: + // Defines _DEBUG, and _MT + // Linker uses LIBCMTD.lib + modifiedExtraFlags.cCompilerFlags += ["-D_DEBUG", "-D_MT", "-Xclang", "--dependent-lib=libcmtd"] + + case .multithreaded: + // Defines _MT + // Linker uses LIBCMT.lib + modifiedExtraFlags.cCompilerFlags += ["-D_MT", "-Xclang", "--dependent-lib=libcmt"] + } + } + } + } + + let swiftPMLibrariesLocation = try customLibrariesLocation ?? Self.deriveSwiftPMLibrariesLocation( + swiftCompilerPath: swiftCompilerPath, + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem + ) + + let xctestPath: AbsolutePath? + if case .custom(_, let useXcrunFlag) = searchStrategy, !useXcrunFlag { + xctestPath = nil + } else { + xctestPath = try Self.deriveXCTestPath( + swiftSDK: swiftSDK, + triple: triple, + environment: environment, + fileSystem: fileSystem + ) + } + + let configuration = ToolchainConfiguration( + librarianPath: librarianPath, + swiftCompilerPath: swiftCompilers.manifest, + swiftCompilerFlags: modifiedExtraFlags.swiftCompilerFlags, + swiftCompilerEnvironment: environment, + swiftPMLibrariesLocation: swiftPMLibrariesLocation, + sdkRootPath: swiftSDK.pathsConfiguration.sdkRootPath, + xctestPath: xctestPath, + swiftTestingPath: swiftTestingPath + ) + + return UserToolchain( + swiftSDK: swiftSDK, + environment: environment, + envSearchPaths: envSearchPaths, + useXcrun: useXcrun, + swiftCompilerPath: swiftCompilerPath, + architectures: architectures, + installedSwiftPMConfiguration: installedSwiftPMConfiguration, + targetInfo: targetInfo, + targetTriple: targetTriple, + extraFlags: modifiedExtraFlags, + includeSearchPaths: includeSearchPaths, + librarySearchPaths: librarySearchPaths, + librarianPath: librarianPath, + configuration: configuration, + fileSystem: fileSystem + ) + } + + private init( + swiftSDK: SwiftSDK, + environment: Environment, + envSearchPaths: [AbsolutePath], + useXcrun: Bool, + swiftCompilerPath: AbsolutePath, + architectures: [String]?, + installedSwiftPMConfiguration: InstalledSwiftPMConfiguration, + targetInfo: JSON?, + targetTriple: Basics.Triple, + extraFlags: BuildFlags, + includeSearchPaths: [AbsolutePath], + librarySearchPaths: [AbsolutePath], + librarianPath: AbsolutePath, + configuration: ToolchainConfiguration, + fileSystem: any FileSystem + ) { + self.swiftSDK = swiftSDK + self.environment = environment + self.envSearchPaths = envSearchPaths + self.useXcrun = useXcrun + self.swiftCompilerPath = swiftCompilerPath + self.architectures = architectures + self.installedSwiftPMConfiguration = installedSwiftPMConfiguration + self.targetInfo = targetInfo + self.targetTriple = targetTriple + self.extraFlags = extraFlags + self.includeSearchPaths = includeSearchPaths + self.librarySearchPaths = librarySearchPaths + self.librarianPath = librarianPath + self.configuration = configuration + self.fileSystem = fileSystem + } + private static func deriveSwiftPMLibrariesLocation( swiftCompilerPath: AbsolutePath, swiftSDK: SwiftSDK, diff --git a/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift b/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift index a7a5cb35521..96cf9838f22 100644 --- a/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift +++ b/Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift @@ -167,7 +167,7 @@ extension PackageRegistryCommand { } // Auth config is in user-level registries config only - let configuration = try getRegistriesConfig(swiftCommandState, global: true) + let configuration = try await getRegistriesConfig(swiftCommandState, global: true) // compute and validate registry URL guard let registryURL = self.registryURL ?? configuration.configuration.defaultRegistry?.url else { @@ -339,7 +339,7 @@ extension PackageRegistryCommand { func run(_ swiftCommandState: SwiftCommandState) async throws { // Auth config is in user-level registries config only - let configuration = try getRegistriesConfig(swiftCommandState, global: true) + let configuration = try await getRegistriesConfig(swiftCommandState, global: true) // compute and validate registry URL guard let registryURL = self.registryURL ?? configuration.configuration.defaultRegistry?.url else { diff --git a/Sources/PackageRegistryCommand/PackageRegistryCommand+Publish.swift b/Sources/PackageRegistryCommand/PackageRegistryCommand+Publish.swift index abac4d8628a..e42601a4972 100644 --- a/Sources/PackageRegistryCommand/PackageRegistryCommand+Publish.swift +++ b/Sources/PackageRegistryCommand/PackageRegistryCommand+Publish.swift @@ -91,7 +91,7 @@ extension PackageRegistryCommand { func run(_ swiftCommandState: SwiftCommandState) async throws { // Require both local and user-level registries config - let configuration = try getRegistriesConfig(swiftCommandState, global: false).configuration + let configuration = try await getRegistriesConfig(swiftCommandState, global: false).configuration // validate package location let packageDirectory = try self.globalOptions.locations.packageDirectory ?? swiftCommandState.getPackageRoot() diff --git a/Sources/PackageRegistryCommand/PackageRegistryCommand.swift b/Sources/PackageRegistryCommand/PackageRegistryCommand.swift index f41004fcd8e..c88a3b5ea93 100644 --- a/Sources/PackageRegistryCommand/PackageRegistryCommand.swift +++ b/Sources/PackageRegistryCommand/PackageRegistryCommand.swift @@ -79,7 +79,7 @@ public struct PackageRegistryCommand: AsyncParsableCommand { } } - let configuration = try getRegistriesConfig(swiftCommandState, global: self.global) + let configuration = try await getRegistriesConfig(swiftCommandState, global: self.global) if self.global { try configuration.updateShared(with: set) } else { @@ -119,7 +119,7 @@ public struct PackageRegistryCommand: AsyncParsableCommand { } } - let configuration = try getRegistriesConfig(swiftCommandState, global: self.global) + let configuration = try await getRegistriesConfig(swiftCommandState, global: self.global) if self.global { try configuration.updateShared(with: unset) } else { @@ -143,7 +143,7 @@ public struct PackageRegistryCommand: AsyncParsableCommand { case credentialLengthLimitExceeded(Int) } - static func getRegistriesConfig(_ swiftCommandState: SwiftCommandState, global: Bool) throws -> Workspace.Configuration.Registries { + static func getRegistriesConfig(_ swiftCommandState: SwiftCommandState, global: Bool) async throws -> Workspace.Configuration.Registries { if global { let sharedRegistriesFile = Workspace.DefaultLocations.registriesConfigurationFile( at: swiftCommandState.sharedConfigurationDirectory @@ -155,7 +155,7 @@ public struct PackageRegistryCommand: AsyncParsableCommand { sharedRegistriesFile: sharedRegistriesFile ) } else { - let workspace = try swiftCommandState.getActiveWorkspace() + let workspace = try await swiftCommandState.getActiveWorkspace() return try .init( fileSystem: swiftCommandState.fileSystem, localRegistriesFile: workspace.location.localRegistriesConfigurationFile, diff --git a/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift b/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift index 7000b52b166..fcf5b25bd97 100644 --- a/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift +++ b/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift @@ -116,7 +116,8 @@ struct ConfigureSwiftSDK: AsyncParsableCommand { let observabilityScope = observabilitySystem.topScope let swiftSDKsDirectory = try self.getOrCreateSwiftSDKsDirectory() - let hostToolchain = try UserToolchain(swiftSDK: SwiftSDK.hostSwiftSDK()) + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync() + let hostToolchain = try await UserToolchain.create(swiftSDK: hostSwiftSDK) let triple = try Triple.getVersionedHostTriple(usingSwiftCompiler: hostToolchain.swiftCompilerPath) var commandError: Error? = nil diff --git a/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift b/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift index 00ee520cc06..821ea2fc1db 100644 --- a/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift +++ b/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift @@ -62,10 +62,9 @@ extension SwiftSDKSubcommand { let swiftSDKsDirectory = try self.getOrCreateSwiftSDKsDirectory() let environment = Environment.current - let hostToolchain = try UserToolchain( - swiftSDK: SwiftSDK.hostSwiftSDK( - environment: environment - ), + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: environment) + let hostToolchain = try await UserToolchain.create( + swiftSDK: hostSwiftSDK, environment: environment ) let triple = try Triple.getVersionedHostTriple(usingSwiftCompiler: hostToolchain.swiftCompilerPath) diff --git a/Sources/Workspace/Workspace.swift b/Sources/Workspace/Workspace.swift index b5243e1a170..b51e067c0a2 100644 --- a/Sources/Workspace/Workspace.swift +++ b/Sources/Workspace/Workspace.swift @@ -237,6 +237,144 @@ public class Workspace { ) } + /// Create a new package workspace. + /// + /// This initializer is designed for use cases when the workspace needs to be highly customized such as testing. + /// In other cases, use the other, more straight forward, initializers + /// + /// This will automatically load the persisted state for the package, if + /// present. If the state isn't present then a default state will be + /// constructed. + /// + /// - Parameters: + /// - fileSystem: The file system to use. + /// - location: Workspace location configuration. + /// - authorizationProvider: Provider of authentication information for outbound network requests. + /// - registryAuthorizationProvider: Provider of authentication information for registry requests. + /// - configuration: Configuration to fine tune the dependency resolution behavior. + /// - cancellator: Cancellation handler + /// - initializationWarningHandler: Initialization warnings handler + /// - customHostToolchain: Custom host toolchain. Used to create a customized ManifestLoader, customizing how + /// manifest are loaded. + /// - customManifestLoader: Custom manifest loader. Used to customize how manifest are loaded. + /// - customPackageContainerProvider: Custom package container provider. Used to provide specialized package + /// providers. + /// - customRepositoryProvider: Custom repository provider. Used to customize source control access. + /// - delegate: Delegate for workspace events + public static func create( + fileSystem: any FileSystem, + environment: Environment = .current, + location: Location, + authorizationProvider: (any AuthorizationProvider)? = .none, + registryAuthorizationProvider: (any AuthorizationProvider)? = .none, + configuration: WorkspaceConfiguration? = .none, + cancellator: Cancellator? = .none, + initializationWarningHandler: ((String) -> Void)? = .none, + // optional customization used for advanced integration situations + customHostToolchain: UserToolchain? = .none, + customManifestLoader: (any ManifestLoaderProtocol)? = .none, + customPackageContainerProvider: (any PackageContainerProvider)? = .none, + customRepositoryProvider: (any RepositoryProvider)? = .none, + // delegate + delegate: Delegate? = .none + ) async throws -> Workspace { + try await Workspace( + fileSystem: fileSystem, + environment: environment, + location: location, + authorizationProvider: authorizationProvider, + registryAuthorizationProvider: registryAuthorizationProvider, + configuration: configuration, + cancellator: cancellator, + initializationWarningHandler: initializationWarningHandler, + customRegistriesConfiguration: .none, + customFingerprints: .none, + customSigningEntities: .none, + skipSignatureValidation: false, + customMirrors: .none, + customToolsVersion: .none, + customHostToolchain: customHostToolchain, + customManifestLoader: customManifestLoader, + customPackageContainerProvider: customPackageContainerProvider, + customRepositoryManager: .none, + customRepositoryProvider: customRepositoryProvider, + customRegistryClient: .none, + customBinaryArtifactsManager: .none, + customPrebuiltsManager: .none, + customIdentityResolver: .none, + customDependencyMapper: .none, + customChecksumAlgorithm: .none, + delegate: delegate + ) + } + /// A convenience method for creating a workspace for the given root + /// package path. + /// + /// The root package path is used to compute the build directory and other + /// default paths. + /// + /// - Parameters: + /// - fileSystem: The file system to use, defaults to local file system. + /// - forRootPackage: The path for the root package. + /// - authorizationProvider: Provider of authentication information for outbound network requests. + /// - registryAuthorizationProvider: Provider of authentication information for registry requests. + /// - configuration: Configuration to fine tune the dependency resolution behavior. + /// - cancellator: Cancellation handler + /// - initializationWarningHandler: Initialization warnings handler + /// - customManifestLoader: Custom manifest loader. Used to customize how manifest are loaded. + /// - customPackageContainerProvider: Custom package container provider. Used to provide specialized package + /// providers. + /// - customRepositoryProvider: Custom repository provider. Used to customize source control access. + /// - delegate: Delegate for workspace events + public static func create( + fileSystem: FileSystem? = .none, + environment: Environment = .current, + forRootPackage packagePath: AbsolutePath, + authorizationProvider: AuthorizationProvider? = .none, + registryAuthorizationProvider: AuthorizationProvider? = .none, + configuration: WorkspaceConfiguration? = .none, + cancellator: Cancellator? = .none, + initializationWarningHandler: ((String) -> Void)? = .none, + // optional customization used for advanced integration situations + customHostToolchain: UserToolchain? = .none, + customManifestLoader: ManifestLoaderProtocol? = .none, + customPackageContainerProvider: PackageContainerProvider? = .none, + customRepositoryProvider: RepositoryProvider? = .none, + // delegate + delegate: Delegate? = .none + ) async throws -> Workspace { + let fileSystem = fileSystem ?? localFileSystem + let location = try Location(forRootPackage: packagePath, fileSystem: fileSystem) + return try await Workspace( + fileSystem: fileSystem, + environment: environment, + location: location, + authorizationProvider: authorizationProvider, + registryAuthorizationProvider: registryAuthorizationProvider, + configuration: configuration, + cancellator: cancellator, + initializationWarningHandler: initializationWarningHandler, + customRegistriesConfiguration: .none, + customFingerprints: .none, + customSigningEntities: .none, + skipSignatureValidation: false, + customMirrors: .none, + customToolsVersion: .none, + customHostToolchain: customHostToolchain, + customManifestLoader: customManifestLoader, + customPackageContainerProvider: customPackageContainerProvider, + customRepositoryManager: .none, + customRepositoryProvider: customRepositoryProvider, + customRegistryClient: .none, + customBinaryArtifactsManager: .none, + customPrebuiltsManager: .none, + customIdentityResolver: .none, + customDependencyMapper: .none, + customChecksumAlgorithm: .none, + delegate: delegate + ) + } + /// A convenience method for creating a workspace for the given root /// package path. /// @@ -645,6 +783,239 @@ public class Workspace { ) } + private convenience init( + // core + fileSystem: FileSystem, + environment: Environment, + location: Location, + authorizationProvider: AuthorizationProvider?, + registryAuthorizationProvider: AuthorizationProvider?, + configuration: WorkspaceConfiguration?, + cancellator: Cancellator?, + initializationWarningHandler: ((String) -> Void)?, + // optional customization, primarily designed for testing but also used in some cases by libSwiftPM consumers + customRegistriesConfiguration: RegistryConfiguration?, + customFingerprints: PackageFingerprintStorage?, + customSigningEntities: PackageSigningEntityStorage?, + skipSignatureValidation: Bool, + customMirrors: DependencyMirrors?, + customToolsVersion: ToolsVersion?, + customHostToolchain: UserToolchain?, + customManifestLoader: ManifestLoaderProtocol?, + customPackageContainerProvider: PackageContainerProvider?, + customRepositoryManager: RepositoryManager?, + customRepositoryProvider: RepositoryProvider?, + customRegistryClient: RegistryClient?, + customBinaryArtifactsManager: CustomBinaryArtifactsManager?, + customPrebuiltsManager: CustomPrebuiltsManager?, + customIdentityResolver: IdentityResolver?, + customDependencyMapper: DependencyMapper?, + customChecksumAlgorithm: HashAlgorithm?, + // delegate + delegate: Delegate? + ) async throws { + // we do not store an observabilityScope in the workspace initializer as the workspace is designed to be long + // lived. + // instead, observabilityScope is passed into the individual workspace methods which are short lived. + let initializationWarningHandler = initializationWarningHandler ?? warnToStderr + // validate locations, returning a potentially modified one to deal with non-accessible or non-writable shared + // locations + let location = try location.validatingSharedLocations( + fileSystem: fileSystem, + warningHandler: initializationWarningHandler + ) + + let currentToolsVersion = customToolsVersion ?? ToolsVersion.current + let hostToolchain: UserToolchain + if let customHostToolchain { + hostToolchain = customHostToolchain + } else { + let swiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: environment) + hostToolchain = try await UserToolchain.create( + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem + ) + } + var manifestLoader = customManifestLoader ?? ManifestLoader( + toolchain: hostToolchain, + cacheDir: location.sharedManifestsCacheDirectory, + importRestrictions: configuration?.manifestImportRestrictions, + pruneDependencies: configuration?.pruneDependencies ?? false + ) + // set delegate if not set + if let manifestLoader = manifestLoader as? ManifestLoader, manifestLoader.delegate == nil { + manifestLoader.delegate = delegate.map(WorkspaceManifestLoaderDelegate.init(workspaceDelegate:)) + } + + let configuration = configuration ?? .default + + let mirrors = try customMirrors ?? Workspace.Configuration.Mirrors( + fileSystem: fileSystem, + localMirrorsFile: location.localMirrorsConfigurationFile, + sharedMirrorsFile: location.sharedMirrorsConfigurationFile + ).mirrors + + let identityResolver = customIdentityResolver ?? DefaultIdentityResolver( + locationMapper: mirrors.effective(for:), + identityMapper: mirrors.effectiveIdentity(for:) + ) + let dependencyMapper = customDependencyMapper ?? DefaultDependencyMapper(identityResolver: identityResolver) + let checksumAlgorithm = customChecksumAlgorithm ?? SHA256() + + let repositoryProvider = customRepositoryProvider ?? GitRepositoryProvider() + let repositoryManager = customRepositoryManager ?? RepositoryManager( + fileSystem: fileSystem, + path: location.repositoriesDirectory, + provider: repositoryProvider, + cachePath: configuration.sharedDependenciesCacheEnabled ? location.sharedRepositoriesCacheDirectory : .none, + initializationWarningHandler: initializationWarningHandler, + delegate: delegate.map(WorkspaceRepositoryManagerDelegate.init(workspaceDelegate:)) + ) + // register the source control dependencies fetcher with the cancellation handler + cancellator?.register(name: "repository fetching", handler: repositoryManager) + + let fingerprints = customFingerprints ?? location.sharedFingerprintsDirectory.map { + FilePackageFingerprintStorage( + fileSystem: fileSystem, + directoryPath: $0 + ) + } + + let signingEntities = customSigningEntities ?? location.sharedSigningEntitiesDirectory.map { + FilePackageSigningEntityStorage( + fileSystem: fileSystem, + directoryPath: $0 + ) + } + + let registriesConfiguration = try customRegistriesConfiguration ?? Workspace.Configuration.Registries( + fileSystem: fileSystem, + localRegistriesFile: location.localRegistriesConfigurationFile, + sharedRegistriesFile: location.sharedRegistriesConfigurationFile + ).configuration + + let registryClient = customRegistryClient ?? RegistryClient( + configuration: registriesConfiguration, + fingerprintStorage: fingerprints, + fingerprintCheckingMode: FingerprintCheckingMode.map(configuration.fingerprintCheckingMode), + skipSignatureValidation: skipSignatureValidation, + signingEntityStorage: signingEntities, + signingEntityCheckingMode: SigningEntityCheckingMode.map(configuration.signingEntityCheckingMode), + authorizationProvider: registryAuthorizationProvider, + delegate: WorkspaceRegistryClientDelegate(workspaceDelegate: delegate), + checksumAlgorithm: checksumAlgorithm + ) + + // set default registry if not already set by configuration + if registryClient.defaultRegistry == nil, let defaultRegistry = configuration.defaultRegistry { + registryClient.defaultRegistry = defaultRegistry + } + + let registryDownloadsManager = RegistryDownloadsManager( + fileSystem: fileSystem, + path: location.registryDownloadDirectory, + cachePath: configuration.sharedDependenciesCacheEnabled ? location + .sharedRegistryDownloadsCacheDirectory : .none, + registryClient: registryClient, + delegate: delegate.map(WorkspaceRegistryDownloadsManagerDelegate.init(workspaceDelegate:)) + ) + // register the registry dependencies downloader with the cancellation handler + cancellator?.register(name: "registry downloads", handler: registryDownloadsManager) + + if let transformationMode = RegistryAwareManifestLoader + .TransformationMode(configuration.sourceControlToRegistryDependencyTransformation) + { + manifestLoader = RegistryAwareManifestLoader( + underlying: manifestLoader, + registryClient: registryClient, + transformationMode: transformationMode + ) + } + + let binaryArtifactsManager = BinaryArtifactsManager( + fileSystem: fileSystem, + authorizationProvider: authorizationProvider, + hostToolchain: hostToolchain, + checksumAlgorithm: checksumAlgorithm, + cachePath: customBinaryArtifactsManager?.useCache == false || !configuration + .sharedDependenciesCacheEnabled ? .none : location.sharedBinaryArtifactsCacheDirectory, + customHTTPClient: customBinaryArtifactsManager?.httpClient, + customArchiver: customBinaryArtifactsManager?.archiver, + delegate: delegate.map(WorkspaceBinaryArtifactsManagerDelegate.init(workspaceDelegate:)) + ) + // register the binary artifacts downloader with the cancellation handler + cancellator?.register(name: "binary artifacts downloads", handler: binaryArtifactsManager) + + var prebuiltsManager: PrebuiltsManager? + if configuration.usePrebuilts, + let hostPlatform = customPrebuiltsManager?.hostPlatform ?? PrebuiltsManifest.Platform.hostPlatform + { + let rootCertPath: AbsolutePath? + if let path = configuration.prebuiltsRootCertPath { + rootCertPath = try AbsolutePath(validating: path) + } else { + rootCertPath = nil + } + + let prebuiltsManagerObj = PrebuiltsManager( + fileSystem: fileSystem, + hostPlatform: hostPlatform, + authorizationProvider: authorizationProvider, + scratchPath: location.prebuiltsDirectory, + cachePath: customPrebuiltsManager?.useCache == false || !configuration.sharedDependenciesCacheEnabled ? .none : location.sharedPrebuiltsCacheDirectory, + customSwiftCompilerVersion: customPrebuiltsManager?.swiftVersion, + customHTTPClient: customPrebuiltsManager?.httpClient, + customArchiver: customPrebuiltsManager?.archiver, + delegate: delegate.map(WorkspacePrebuiltsManagerDelegate.init(workspaceDelegate:)), + prebuiltsDownloadURL: configuration.prebuiltsDownloadURL, + rootCertPath: customPrebuiltsManager?.rootCertPath ?? rootCertPath + ) + cancellator?.register(name: "package prebuilts downloads", handler: prebuiltsManagerObj) + prebuiltsManager = prebuiltsManagerObj + } else { + prebuiltsManager = nil + } + + // initialize + let resolvedPackagesStore = LoadableResult { + try ResolvedPackagesStore( + packageResolvedFile: location.resolvedVersionsFile, + workingDirectory: location.scratchDirectory, + fileSystem: fileSystem, + mirrors: mirrors + ) + } + + let state = WorkspaceState( + fileSystem: fileSystem, + storageDirectory: location.scratchDirectory, + initializationWarningHandler: initializationWarningHandler + ) + + self.init( + fileSystem: fileSystem, + configuration: configuration, + location: location, + delegate: delegate, + mirrors: mirrors, + hostToolchain: hostToolchain, + manifestLoader: manifestLoader, + currentToolsVersion: currentToolsVersion, + customPackageContainerProvider: customPackageContainerProvider, + repositoryManager: repositoryManager, + registryClient: registryClient, + registryDownloadsManager: registryDownloadsManager, + binaryArtifactsManager: binaryArtifactsManager, + identityResolver: identityResolver, + dependencyMapper: dependencyMapper, + fingerprints: fingerprints, + resolvedPackagesStore: resolvedPackagesStore, + prebuiltsManager: prebuiltsManager, + state: state + ) + } + private init( fileSystem: any FileSystem, configuration: WorkspaceConfiguration, diff --git a/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift b/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift index af0bfac2369..9d70233f367 100644 --- a/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift +++ b/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift @@ -89,7 +89,11 @@ public func mockBuildPlan( fatalError("unsupported platform in tests") } } else { - inferredTriple = triple ?? hostTriple + inferredTriple = if let triple = triple { + triple + } else { + try await hostTriple() + } } let commonDebuggingParameters = BuildParameters.Debugging( @@ -98,7 +102,7 @@ public func mockBuildPlan( omitFramePointers: omitFramePointers ) - var destinationParameters = mockBuildParameters( + var destinationParameters = try await mockBuildParameters( destination: .target, buildPath: buildPath, config: config, @@ -112,7 +116,7 @@ public func mockBuildPlan( destinationParameters.linkingParameters = linkingParameters destinationParameters.sanitizers = targetSanitizers - var hostParameters = mockBuildParameters( + var hostParameters = try await mockBuildParameters( destination: .host, buildPath: buildPath, config: config, diff --git a/Sources/_InternalTestSupport/BuildSystemProvider+Configuration.swift b/Sources/_InternalTestSupport/BuildSystemProvider+Configuration.swift index 30b3db4b2c7..91716e305a9 100644 --- a/Sources/_InternalTestSupport/BuildSystemProvider+Configuration.swift +++ b/Sources/_InternalTestSupport/BuildSystemProvider+Configuration.swift @@ -41,7 +41,7 @@ extension BuildSystemProvider.Kind { for config: BuildConfiguration, scratchPath: [String] = [".build"], triple: String? = nil, - ) throws -> [String] { + ) async throws -> [String] { let suffix: String #if os(Linux) @@ -57,7 +57,7 @@ extension BuildSystemProvider.Kind { tripleString = triple } else { do { - tripleString = try UserToolchain.default.targetTriple.platformBuildPathComponent + tripleString = try await UserToolchain.default().targetTriple.platformBuildPathComponent } catch { tripleString = "" } diff --git a/Sources/_InternalTestSupport/MockBuildTestHelper.swift b/Sources/_InternalTestSupport/MockBuildTestHelper.swift index 78820551777..08eddef6024 100644 --- a/Sources/_InternalTestSupport/MockBuildTestHelper.swift +++ b/Sources/_InternalTestSupport/MockBuildTestHelper.swift @@ -69,12 +69,18 @@ extension Basics.Triple { public static let arm64iOS = try! Self("arm64-apple-ios") } -public let hostTriple = try! UserToolchain.default.targetTriple +public func hostTriple() async throws -> Basics.Triple { + return try await UserToolchain.default().targetTriple +} + +public func defaultTargetTriple() async throws -> String { + let triple = try await hostTriple() #if os(macOS) -public let defaultTargetTriple: String = hostTriple.tripleString(forPlatformVersion: "10.13") + return triple.tripleString(forPlatformVersion: "10.13") #else -public let defaultTargetTriple: String = hostTriple.tripleString + return triple.tripleString #endif +} public func mockBuildParameters( destination: BuildParameters.Destination, @@ -86,14 +92,19 @@ public func mockBuildParameters( shouldLinkStaticSwiftStdlib: Bool = false, shouldDisableLocalRpath: Bool = false, canRenameEntrypointFunctionName: Bool = false, - triple: Basics.Triple = hostTriple, + triple: Basics.Triple? = nil, indexStoreMode: BuildParameters.IndexStoreMode = .off, linkerDeadStrip: Bool = true, linkTimeOptimizationMode: BuildParameters.LinkTimeOptimizationMode? = nil, omitFramePointers: Bool? = nil, prepareForIndexing: BuildParameters.PrepareForIndexingMode = .off -) -> BuildParameters { - try! BuildParameters( +) async throws -> BuildParameters { + let triple = if let triple = triple { + triple + } else { + try await UserToolchain.default().targetTriple + } + return try BuildParameters( destination: destination, dataPath: buildPath ?? AbsolutePath("/path/to/build").appending(triple.tripleString), configuration: config, @@ -125,7 +136,7 @@ public func mockBuildParameters( public func mockBuildParameters( destination: BuildParameters.Destination, environment: BuildEnvironment -) -> BuildParameters { +) async throws -> BuildParameters { let triple: Basics.Triple switch environment.platform { case .macOS: @@ -140,7 +151,7 @@ public func mockBuildParameters( fatalError("unsupported platform in tests") } - return mockBuildParameters( + return try await mockBuildParameters( destination: destination, config: environment.configuration ?? .debug, triple: triple diff --git a/Sources/_InternalTestSupport/MockWorkspace.swift b/Sources/_InternalTestSupport/MockWorkspace.swift index 4e8b202654f..a0262446d6b 100644 --- a/Sources/_InternalTestSupport/MockWorkspace.swift +++ b/Sources/_InternalTestSupport/MockWorkspace.swift @@ -32,14 +32,18 @@ extension UserToolchain { package static func mockHostToolchain( _ fileSystem: InMemoryFileSystem, - hostTriple: Triple = hostTriple - ) throws -> UserToolchain { - var hostSwiftSDK = try SwiftSDK.hostSwiftSDK(environment: .mockEnvironment, fileSystem: fileSystem) - hostSwiftSDK.targetTriple = hostTriple + hostTriple: Triple? = nil + ) async throws -> UserToolchain { + var hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: .mockEnvironment, fileSystem: fileSystem) + if let hostTriple = hostTriple { + hostSwiftSDK.targetTriple = hostTriple + } else { + hostSwiftSDK.targetTriple = try await UserToolchain.default().targetTriple + } let env = Environment.mockEnvironment - return try UserToolchain( + return try await UserToolchain.create( swiftSDK: hostSwiftSDK, environment: env, searchStrategy: .custom( @@ -124,7 +128,7 @@ public final class MockWorkspace { sourceControlToRegistryDependencyTransformation: WorkspaceConfiguration .SourceControlToRegistryDependencyTransformation = .disabled, defaultRegistry: Registry? = .none, - customHostTriple: Triple = hostTriple, + customHostTriple: Triple? = nil, traitConfiguration: TraitConfiguration = .default, pruneDependencies: Bool = false, enabledTraitsMap: EnabledTraitsMap = .init() @@ -163,7 +167,7 @@ public final class MockWorkspace { archiver: MockArchiver() ) self.customPrebuiltsManager = customPrebuiltsManager - self.customHostToolchain = try UserToolchain.mockHostToolchain(fileSystem, hostTriple: customHostTriple) + self.customHostToolchain = try await UserToolchain.mockHostToolchain(fileSystem, hostTriple: customHostTriple) self.traitConfiguration = traitConfiguration self.pruneDependencies = pruneDependencies self.enabledTraitsMap = enabledTraitsMap @@ -376,12 +380,12 @@ public final class MockWorkspace { self.manifestLoader = MockManifestLoader(manifests: manifests) } - public func getOrCreateWorkspace() throws -> Workspace { + public func getOrCreateWorkspace() async throws -> Workspace { if let workspace = self._workspace { return workspace } - let workspace = try Workspace._init( + let workspace = try await Workspace._init( fileSystem: self.fileSystem, environment: .mockEnvironment, location: .init( @@ -460,7 +464,7 @@ public final class MockWorkspace { ) async { let observability = ObservabilitySystem.makeForTesting() await observability.topScope.trap { - let ws = try self.getOrCreateWorkspace() + let ws = try await self.getOrCreateWorkspace() await ws.edit( packageIdentity: packageIdentity, path: path, @@ -484,7 +488,7 @@ public final class MockWorkspace { packages: rootPaths(for: roots), traitConfiguration: traitConfiguration ) - let ws = try self.getOrCreateWorkspace() + let ws = try await self.getOrCreateWorkspace() try await ws.unedit( packageIdentity: packageIdentity, forceRemove: forceRemove, @@ -507,7 +511,7 @@ public final class MockWorkspace { packages: rootPaths(for: roots), traitConfiguration: traitConfiguration ) - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await workspace.resolve( packageName: pkg, root: rootInput, @@ -520,10 +524,10 @@ public final class MockWorkspace { result(observability.diagnostics) } - public func checkClean(_ result: ([Basics.Diagnostic]) -> Void) { + public func checkClean(_ result: ([Basics.Diagnostic]) -> Void) async { let observability = ObservabilitySystem.makeForTesting() - observability.topScope.trap { - let workspace = try self.getOrCreateWorkspace() + await observability.topScope.trap { + let workspace = try await self.getOrCreateWorkspace() workspace.clean(observabilityScope: observability.topScope) } result(observability.diagnostics) @@ -532,7 +536,7 @@ public final class MockWorkspace { public func checkReset(_ result: ([Basics.Diagnostic]) -> Void) async { let observability = ObservabilitySystem.makeForTesting() await observability.topScope.trap { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() await workspace.reset(observabilityScope: observability.topScope) } result(observability.diagnostics) @@ -556,7 +560,7 @@ public final class MockWorkspace { dependencies: dependencies, traitConfiguration: traitConfiguration ) - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await workspace.updateDependencies( root: rootInput, packages: packages, @@ -583,7 +587,7 @@ public final class MockWorkspace { let observability = ObservabilitySystem.makeForTesting() let changes = await observability.topScope.trap { () -> [(PackageReference, Workspace.PackageStateChange)]? in - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() return try await workspace.updateDependencies( root: rootInput, dryRun: true, @@ -616,7 +620,7 @@ public final class MockWorkspace { let rootInput = try PackageGraphRootInput( packages: rootPaths(for: roots), dependencies: dependencies, traitConfiguration: traitConfiguration ) - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() do { let graph = try await workspace.loadPackageGraph( rootInput: rootInput, @@ -659,7 +663,7 @@ public final class MockWorkspace { dependencies: dependencies, traitConfiguration: traitConfiguration ) - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await workspace.loadPackageGraph( rootInput: rootInput, forceResolvedVersions: forceResolvedVersions, @@ -676,7 +680,7 @@ public final class MockWorkspace { public func checkPrecomputeResolution() async throws -> ResolutionPrecomputationResult { let observability = ObservabilitySystem.makeForTesting() - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() let resolvedPackagesStore = try workspace.resolvedPackagesStore.load() let rootInput = try PackageGraphRootInput( @@ -738,7 +742,7 @@ public final class MockWorkspace { managedDependencies: [AbsolutePath: Workspace.ManagedDependency] = [:], managedArtifacts: [Workspace.ManagedArtifact] = [] ) async throws { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() let resolvedPackagesStore = try workspace.resolvedPackagesStore.load() for (ref, state) in resolvedPackages { @@ -767,7 +771,7 @@ public final class MockWorkspace { } public func resetState() async throws { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await workspace.resetState() } @@ -948,7 +952,7 @@ public final class MockWorkspace { baseURL: self.packagesDir, identityResolver: self.identityResolver ) } - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() let rootInput = try PackageGraphRootInput( packages: rootPaths(for: roots), dependencies: dependencies, traitConfiguration: traitConfiguration ) @@ -975,7 +979,7 @@ public final class MockWorkspace { _ result: (ManagedDependencyResult) throws -> Void ) async { do { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await result(ManagedDependencyResult(workspace.state.dependencies)) } catch { XCTFail("Failed with error \(error.interpolationDescription)", file: file, line: line) @@ -988,7 +992,7 @@ public final class MockWorkspace { _ result: (ManagedArtifactResult) throws -> Void ) async { do { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try await result(ManagedArtifactResult(workspace.state.artifacts)) } catch { XCTFail("Failed with error \(error.interpolationDescription)", file: file, line: line) @@ -1052,9 +1056,9 @@ public final class MockWorkspace { file: StaticString = #file, line: UInt = #line, _ result: (ResolvedResult) throws -> Void - ) { + ) async { do { - let workspace = try self.getOrCreateWorkspace() + let workspace = try await self.getOrCreateWorkspace() try result(ResolvedResult(workspace.resolvedPackagesStore.load())) } catch { XCTFail("Failed with error \(error.interpolationDescription)", file: file, line: line) diff --git a/Sources/_InternalTestSupport/SwiftTesting+TraitConditional.swift b/Sources/_InternalTestSupport/SwiftTesting+TraitConditional.swift index a46dfafe162..27b927584e3 100644 --- a/Sources/_InternalTestSupport/SwiftTesting+TraitConditional.swift +++ b/Sources/_InternalTestSupport/SwiftTesting+TraitConditional.swift @@ -34,28 +34,28 @@ extension Trait where Self == Testing.ConditionTrait { /// Enabled only if toolchain support swift concurrency public static var requiresSwiftConcurrencySupport: Self { enabled("skipping because test environment doesn't support concurrency") { - (try? UserToolchain.default)?.supportsSwiftConcurrency() != nil + (try? await UserToolchain.default())?.supportsSwiftConcurrency() != nil } } /// Enabled only if 'llvm-profdata' is available public static var requiresLLVMProfData: Self { disabled("skipping test because the `llvm-profdata` tool isn't available") { - try (try? UserToolchain.default)?.getLLVMProf() == nil + try (try? await UserToolchain.default())?.getLLVMProf() == nil } } /// Enabled only if 'llvm-cov' is available public static var requiresLLVMCov: Self { disabled("skipping test because the `llvm-cov` tool isn't available") { - try (try? UserToolchain.default)?.getLLVMCov() == nil + try (try? await UserToolchain.default())?.getLLVMCov() == nil } } /// Enabled only if 'swift-symbolgraph-extract' is available public static var requiresSymbolgraphExtract: Self { disabled("skipping test because the `swift-symbolgraph-extract` tools isn't available") { - try (try? UserToolchain.default)?.getSymbolGraphExtract() == nil + try (try? await UserToolchain.default())?.getSymbolGraphExtract() == nil } } @@ -63,7 +63,7 @@ extension Trait where Self == Testing.ConditionTrait { public static var requiresStdlibSupport: Self { enabled("skipping because static stdlib is not supported by the toolchain") { let args = try [ - UserToolchain.default.swiftCompilerPath.pathString, + (try await UserToolchain.default()).swiftCompilerPath.pathString, "-static-stdlib", "-emit-executable", "-o", "/dev/null", "-", ] let process = AsyncProcess(arguments: args) @@ -79,14 +79,14 @@ extension Trait where Self == Testing.ConditionTrait { /// Enabled if toolsupm suported SDK Dependent Tests public static var requiresSDKDependentTestsSupport: Self { enabled("skipping because test environment doesn't support this test") { - (try? UserToolchain.default)!.supportsSDKDependentTests() + (try? await UserToolchain.default())!.supportsSDKDependentTests() } } // Enabled if the toolchain has supported features public static var supportsSupportedFeatures: Self { enabled("skipping because test environment compiler doesn't support `-print-supported-features`") { - (try? UserToolchain.default)!.supportsSupportedFeatures + (try? await UserToolchain.default())!.supportsSupportedFeatures } } @@ -122,13 +122,13 @@ extension Trait where Self == Testing.ConditionTrait { /// Check for required compiler support public static func requiresFrontEndFlags(flags: Set) -> Self { enabled("test requires \(flags.joined(separator: ", "))") { - try DriverSupport.checkSupportedFrontendFlags(flags: flags, toolchain: UserToolchain.default, fileSystem: localFileSystem) + try DriverSupport.checkSupportedFrontendFlags(flags: flags, toolchain: await UserToolchain.default(), fileSystem: localFileSystem) } } private static func requiresHostLibrary(lib: String) -> Self { enabled("test requires `\(lib)` to exist in the host toolchain") { - let libSwiftSyntaxMacrosPath = try UserToolchain.default.hostLibDir.appending("libSwiftSyntaxMacros.dylib") + let libSwiftSyntaxMacrosPath = try (await UserToolchain.default()).hostLibDir.appending("libSwiftSyntaxMacros.dylib") return localFileSystem.exists(libSwiftSyntaxMacrosPath) } } diff --git a/Sources/_InternalTestSupport/Toolchain.swift b/Sources/_InternalTestSupport/Toolchain.swift index 3bbb62cb620..14b246a384a 100644 --- a/Sources/_InternalTestSupport/Toolchain.swift +++ b/Sources/_InternalTestSupport/Toolchain.swift @@ -42,19 +42,15 @@ package func resolveBinDir() throws -> AbsolutePath { } extension SwiftSDK { - public static var `default`: Self { - get throws { - let binDir = try resolveBinDir() - return try! SwiftSDK.hostSwiftSDK(binDir, environment: .current) - } + public static func `default`() async throws -> Self { + let binDir = try resolveBinDir() + return try await SwiftSDK.hostSwiftSDKAsync(binDir, environment: .current) } } extension UserToolchain { - public static var `default`: Self { - get throws { - return try .init(swiftSDK: SwiftSDK.default, environment: .current, fileSystem: localFileSystem) - } + public static func `default`() async throws -> Self { + return try await .init(swiftSDK: await SwiftSDK.default(), environment: .current, fileSystem: localFileSystem) } } diff --git a/Sources/swift-bootstrap/main.swift b/Sources/swift-bootstrap/main.swift index e93f246372a..9c5fa412978 100644 --- a/Sources/swift-bootstrap/main.swift +++ b/Sources/swift-bootstrap/main.swift @@ -192,7 +192,7 @@ struct SwiftBootstrapBuildTool: AsyncParsableCommand { self.scratchDirectory ?? packagePath.appending(".build") - let builder = try Builder( + let builder = try await Builder( fileSystem: localFileSystem, observabilityScope: observabilityScope, logLevel: self.logLevel @@ -224,12 +224,12 @@ struct SwiftBootstrapBuildTool: AsyncParsableCommand { let observabilityScope: ObservabilityScope let logLevel: Basics.Diagnostic.Severity - init(fileSystem: FileSystem, observabilityScope: ObservabilityScope, logLevel: Basics.Diagnostic.Severity) throws { + init(fileSystem: FileSystem, observabilityScope: ObservabilityScope, logLevel: Basics.Diagnostic.Severity) async throws { self.identityResolver = DefaultIdentityResolver() self.dependencyMapper = DefaultDependencyMapper(identityResolver: self.identityResolver) let environment = Environment.current - self.hostToolchain = try UserToolchain( - swiftSDK: SwiftSDK.hostSwiftSDK( + self.hostToolchain = try await UserToolchain.create( + swiftSDK: try await SwiftSDK.hostSwiftSDKAsync( environment: environment, fileSystem: fileSystem ), diff --git a/Sources/swift-build-prebuilts/BuildPrebuilts.swift b/Sources/swift-build-prebuilts/BuildPrebuilts.swift index 09e46bb518d..ad062936e2d 100644 --- a/Sources/swift-build-prebuilts/BuildPrebuilts.swift +++ b/Sources/swift-build-prebuilts/BuildPrebuilts.swift @@ -77,15 +77,15 @@ struct BuildPrebuilts: AsyncParsableCommand { } } - func computeSwiftVersion() throws -> String? { + func computeSwiftVersion() async throws -> String? { let fileSystem = localFileSystem - let environment = Environment.current - let hostToolchain = try UserToolchain( - swiftSDK: SwiftSDK.hostSwiftSDK( - environment: environment, - fileSystem: fileSystem - ), + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync( + environment: environment, + fileSystem: fileSystem + ) + let hostToolchain = try await UserToolchain.create( + swiftSDK: hostSwiftSDK, environment: environment ) @@ -107,7 +107,7 @@ struct BuildPrebuilts: AsyncParsableCommand { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted - guard let swiftVersion = try computeSwiftVersion() else { + guard let swiftVersion = try await computeSwiftVersion() else { print("Unable to determine swift compiler version") return } @@ -151,7 +151,7 @@ struct BuildPrebuilts: AsyncParsableCommand { // Update package with the libraries let packageFile = repoDir.appending(component: "Package.swift") - let workspace = try Workspace(fileSystem: fileSystem, location: .init(forRootPackage: repoDir, fileSystem: fileSystem)) + let workspace = try await Workspace.create(fileSystem: fileSystem, location: .init(forRootPackage: repoDir, fileSystem: fileSystem)) let package = try await workspace.loadRootPackage( at: repoDir, observabilityScope: ObservabilitySystem { _, diag in print(diag) }.topScope @@ -249,7 +249,7 @@ struct BuildPrebuilts: AsyncParsableCommand { let httpClient = HTTPClient() - guard let swiftVersion = try computeSwiftVersion() else { + guard let swiftVersion = try await computeSwiftVersion() else { print("Unable to determine swift compiler version") _exit(1) } diff --git a/Tests/BuildTests/BuildOperationTests.swift b/Tests/BuildTests/BuildOperationTests.swift index af243134cb5..5eb751a342d 100644 --- a/Tests/BuildTests/BuildOperationTests.swift +++ b/Tests/BuildTests/BuildOperationTests.swift @@ -76,7 +76,7 @@ final class BuildOperationTests: XCTestCase { // Perform initial builds for each triple for triple in triples { - let targetBuildParameters = mockBuildParameters( + let targetBuildParameters = try await mockBuildParameters( destination: .target, buildPath: scratchDirectory.appending(triple.tripleString), config: .debug, @@ -84,7 +84,7 @@ final class BuildOperationTests: XCTestCase { ) let buildOp = mockBuildOperation( productsBuildParameters: targetBuildParameters, - toolsBuildParameters: mockBuildParameters(destination: .host), + toolsBuildParameters: try await mockBuildParameters(destination: .host), cacheBuildManifest: false, packageGraphLoader: { packageGraph }, scratchDirectory: scratchDirectory, @@ -109,7 +109,7 @@ final class BuildOperationTests: XCTestCase { // Perform incremental build several times and switch triple for each time for _ in 0..<4 { for triple in triples { - let targetBuildParameters = mockBuildParameters( + let targetBuildParameters = try await mockBuildParameters( destination: .target, buildPath: scratchDirectory.appending(triple.tripleString), config: .debug, @@ -117,7 +117,7 @@ final class BuildOperationTests: XCTestCase { ) let buildOp = mockBuildOperation( productsBuildParameters: targetBuildParameters, - toolsBuildParameters: mockBuildParameters(destination: .host), + toolsBuildParameters: try await mockBuildParameters(destination: .host), cacheBuildManifest: true, packageGraphLoader: { packageGraph }, scratchDirectory: scratchDirectory, @@ -138,20 +138,21 @@ final class BuildOperationTests: XCTestCase { func testHostProductsAndTargetsWithoutExplicitDestination() async throws { let mock = try macrosTestsPackageGraph() - let hostParameters = mockBuildParameters(destination: .host) - let targetParameters = mockBuildParameters(destination: .target) + let hostParameters = try await mockBuildParameters(destination: .host) + let targetParameters = try await mockBuildParameters(destination: .target) + let triple = try await hostTriple() let op = mockBuildOperation( productsBuildParameters: targetParameters, toolsBuildParameters: hostParameters, packageGraphLoader: { mock.graph }, - scratchDirectory: AbsolutePath("/.build/\(hostTriple)"), + scratchDirectory: AbsolutePath("/.build/\(triple)"), fs: mock.fileSystem, observabilityScope: mock.observabilityScope ) let mmioMacrosProductName = try await op.computeLLBuildTargetName(for: .product("MMIOMacros")) XCTAssertEqual( - "MMIOMacros-\(hostTriple)-debug-tool.exe", + "MMIOMacros-\(triple)-debug-tool.exe", mmioMacrosProductName ) @@ -159,7 +160,7 @@ final class BuildOperationTests: XCTestCase { for: .product("swift-mmioPackageTests") ) XCTAssertEqual( - "swift-mmioPackageTests-\(hostTriple)-debug-tool.test", + "swift-mmioPackageTests-\(triple)-debug-tool.test", mmioTestsProductName ) @@ -174,7 +175,7 @@ final class BuildOperationTests: XCTestCase { for target in ["MMIOMacros", "MMIOPlugin", "MMIOMacrosTests", "MMIOMacro+PluginTests"] { let targetName = try await op.computeLLBuildTargetName(for: .target(target)) XCTAssertEqual( - "\(target)-\(hostTriple)-debug-tool.module", + "\(target)-\(triple)-debug-tool.module", targetName ) } diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index c0f61204e73..35b18661068 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -624,9 +624,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { func testPackageNameFlag() async throws { try XCTSkipIfPlatformCI() // test is disabled because it isn't stable, see rdar://118239206 try XCTSkipOnWindows(because: "https://github.com/swiftlang/swift-package-manager/issues/8547: 'swift test' was hanging.") - let isFlagSupportedInDriver = try DriverSupport.checkToolchainDriverFlags( + let isFlagSupportedInDriver = try await DriverSupport.checkToolchainDriverFlags( flags: ["package-name"], - toolchain: UserToolchain.default, + toolchain: try await UserToolchain.default(), fileSystem: localFileSystem ) try await fixtureXCTest(name: "Miscellaneous/PackageNameFlag") { fixturePath in @@ -662,9 +662,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { #if os(macOS) func testPackageNameFlagXCBuild() async throws { - let isFlagSupportedInDriver = try DriverSupport.checkToolchainDriverFlags( + let isFlagSupportedInDriver = try await DriverSupport.checkToolchainDriverFlags( flags: ["package-name"], - toolchain: UserToolchain.default, + toolchain: try await UserToolchain.default(), fileSystem: localFileSystem ) try await fixtureXCTest(name: "Miscellaneous/PackageNameFlag") { fixturePath in @@ -693,9 +693,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { #endif func testTargetsWithPackageAccess() async throws { - let isFlagSupportedInDriver = try DriverSupport.checkToolchainDriverFlags( + let isFlagSupportedInDriver = try await DriverSupport.checkToolchainDriverFlags( flags: ["package-name"], - toolchain: UserToolchain.default, + toolchain: try await UserToolchain.default(), fileSystem: localFileSystem ) try await fixtureXCTest(name: "Miscellaneous/TargetPackageAccess") { fixturePath in @@ -836,7 +836,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Modules", "lib.swiftmodule").pathString, "-Xlinker", "-add_ast_path", "-Xlinker", @@ -852,7 +852,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { // "-static-stdlib", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ] #else @@ -865,7 +865,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", ] #endif @@ -1139,6 +1139,8 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] ) + let targetTriple = try await defaultTargetTriple() + #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -1152,7 +1154,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #elseif os(Windows) @@ -1164,7 +1166,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "/OPT:REF", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -1177,7 +1179,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "--gc-sections", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #endif @@ -1235,6 +1237,8 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] ) + let targetTriple = try await defaultTargetTriple() + #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -1247,7 +1251,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #elseif os(Windows) @@ -1258,7 +1262,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "exe", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -1270,7 +1274,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #endif @@ -1340,7 +1344,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { #if os(macOS) args += ["-fobjc-arc"] #endif - args += ["-target", defaultTargetTriple] + args += ["-target", try await defaultTargetTriple()] args += ["-O0", "-DSWIFT_PACKAGE=1", "-DDEBUG=1"] args += ["-fblocks"] #if os(macOS) // FIXME(5473) - support modules on non-Apple platforms @@ -1351,9 +1355,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] #endif args += ["-I", ExtPkg.appending(components: "Sources", "extlib", "include").pathString] - args += [hostTriple.isWindows() ? "-gdwarf" : "-g"] + args += [try await hostTriple().isWindows() ? "-gdwarf" : "-g"] - if hostTriple.isLinux() { + if try await hostTriple().isLinux() { args += ["-fno-omit-frame-pointer"] } @@ -1365,9 +1369,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { args = [] #if os(macOS) - args += ["-fobjc-arc", "-target", defaultTargetTriple] + args += ["-fobjc-arc", "-target", try await defaultTargetTriple()] #else - args += ["-target", defaultTargetTriple] + args += ["-target", try await defaultTargetTriple()] #endif args += ["-O0", "-DSWIFT_PACKAGE=1", "-DDEBUG=1"] @@ -1386,9 +1390,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-I", ExtPkg.appending(components: "Sources", "extlib", "include").pathString, "-fmodule-map-file=\(buildPath.appending(components: "extlib.build", "module.modulemap"))", ] - args += [hostTriple.isWindows() ? "-gdwarf" : "-g"] + args += [try await hostTriple().isWindows() ? "-gdwarf" : "-g"] - if hostTriple.isLinux() { + if try await hostTriple().isLinux() { args += ["-fno-omit-frame-pointer"] } @@ -1396,6 +1400,8 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { XCTAssertEqual(try exe.objects, [buildPath.appending(components: "exe.build", "main.c.o")]) XCTAssertEqual(exe.moduleMap, nil) + let targetTriple = try await defaultTargetTriple() + #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -1407,7 +1413,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #elseif os(Windows) @@ -1419,7 +1425,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -1432,7 +1438,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #endif @@ -1590,6 +1596,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { result.checkTargetsCount(4) let buildPath = plan.productsBuildPath + let targetTriple = try await defaultTargetTriple() #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ @@ -1603,7 +1610,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #elseif os(Windows) @@ -1615,7 +1622,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #elseif os(FreeBSD) @@ -1629,7 +1636,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #else @@ -1643,7 +1650,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #endif @@ -1740,7 +1747,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { #if os(macOS) args += ["-fobjc-arc"] #endif - args += ["-target", defaultTargetTriple] + args += ["-target", try await defaultTargetTriple()] args += ["-O0", "-DSWIFT_PACKAGE=1", "-DDEBUG=1"] args += ["-fblocks"] @@ -1752,9 +1759,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] #endif args += ["-I", Pkg.appending(components: "Sources", "lib", "include").pathString] - args += [hostTriple.isWindows() ? "-gdwarf" : "-g"] + args += [try await hostTriple().isWindows() ? "-gdwarf" : "-g"] - if hostTriple.isLinux() { + if try await hostTriple().isLinux() { args += ["-fno-omit-frame-pointer"] } @@ -1786,6 +1793,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] ) + let targetTriple1807 = try await defaultTargetTriple() #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -1798,7 +1806,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple1807, "-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/\(result.plan.destinationBuildParameters.triple)/debug/exe.build/exe.swiftmodule", "-g", ]) @@ -1810,7 +1818,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "exe", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple1807, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -1822,7 +1830,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple1807, "-g", ]) #endif @@ -2323,6 +2331,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { if let version = try? Version(string: version, lenient: true), version.major < 26 { rpathsForBackdeployment += ["-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx"] } + let hostTripleString = try await hostTriple().tripleString(forPlatformVersion: version) XCTAssertEqual( try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ @@ -2337,7 +2346,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path/../../../", "@\(buildPath.appending(components: "PkgPackageTests.product", "Objects.LinkFileList"))", ] + rpathsForBackdeployment + [ - "-target", "\(hostTriple.tripleString(forPlatformVersion: version))", + "-target", hostTripleString, "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Modules", "Foo.swiftmodule").pathString, "-Xlinker", "-add_ast_path", "-Xlinker", @@ -2348,6 +2357,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ] ) #elseif os(Windows) + let targetTriple = try await defaultTargetTriple() XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, @@ -2355,10 +2365,11 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "PkgPackageTests", "-emit-executable", "@\(buildPath.appending(components: "PkgPackageTests.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else + let targetTriple = try await defaultTargetTriple() XCTAssertEqual(try result.buildProduct(for: "PkgPackageTests").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, @@ -2367,7 +2378,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "PkgPackageTests.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple, "-g", ]) #endif @@ -2429,6 +2440,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) #if os(macOS) + let hostTripleString2493 = try await hostTriple().tripleString(forPlatformVersion: "12.0") XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, "-L", buildPath.pathString, @@ -2440,7 +2452,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", hostTriple.tripleString(forPlatformVersion: "12.0"), + "-target", hostTripleString2493, "-g", ]) #endif @@ -2800,6 +2812,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { assertionText ) + let targetTriple2866 = try await defaultTargetTriple() #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -2812,7 +2825,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple2866, "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "exe.build", "exe.swiftmodule").pathString, "-g", @@ -2825,7 +2838,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "exe", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple2866, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -2837,7 +2850,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple2866, "-g", ]) #endif @@ -2946,6 +2959,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { let fooLinkArgs = try result.buildProduct(for: "Foo").linkArguments() let barLinkArgs = try result.buildProduct(for: "Bar-Baz").linkArguments() + let targetTriple3014 = try await defaultTargetTriple() #if os(macOS) XCTAssertEqual(fooLinkArgs, [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -2959,7 +2973,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "Foo.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Foo.build", "Foo.swiftmodule").pathString, "-g", @@ -2977,7 +2991,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "Bar-Baz.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Modules", "Bar.swiftmodule").pathString, "-g", @@ -2991,7 +3005,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-lBar-Baz", "-emit-executable", "@\(buildPath.appending(components: "Foo.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) @@ -3002,7 +3016,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "Bar_Baz", "-emit-library", "@\(buildPath.appending(components: "Bar-Baz.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -3015,7 +3029,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "Foo.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-g", ]) @@ -3027,7 +3041,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-library", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "Bar-Baz.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", targetTriple3014, "-g", ]) #endif @@ -3134,7 +3148,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Modules", "lib.swiftmodule").pathString, "-g", @@ -3147,7 +3161,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "lib", "-emit-library", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ] @@ -3160,7 +3174,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-library", "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", ] #endif @@ -3212,8 +3226,9 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { let exe = try result.moduleBuildDescription(for: "exe").clang() + let defaultTargetTripleValue = try await defaultTargetTriple() var expectedExeBasicArgs = triple.isDarwin() ? ["-fobjc-arc"] : [] - expectedExeBasicArgs += ["-target", defaultTargetTriple] + expectedExeBasicArgs += ["-target", defaultTargetTripleValue] expectedExeBasicArgs += ["-O0", "-DSWIFT_PACKAGE=1", "-DDEBUG=1", "-fblocks"] #if os(macOS) // FIXME(5473) - support modules on non-Apple platforms expectedExeBasicArgs += [ @@ -3237,7 +3252,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { let lib = try result.moduleBuildDescription(for: "lib").clang() var expectedLibBasicArgs = triple.isDarwin() ? ["-fobjc-arc"] : [] - expectedLibBasicArgs += ["-target", defaultTargetTriple] + expectedLibBasicArgs += ["-target", defaultTargetTripleValue] expectedLibBasicArgs += ["-O0", "-DSWIFT_PACKAGE=1", "-DDEBUG=1", "-fblocks"] // let shouldHaveModules = false // FIXME(5473) - support modules on non-Apple platforms, and also for C++ on any platform // if shouldHaveModules { @@ -3261,6 +3276,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { XCTAssertEqual(try lib.objects, [buildPath.appending(components: "lib.build", "lib.cpp.o")]) XCTAssertEqual(lib.moduleMap, buildPath.appending(components: "lib.build", "module.modulemap")) + let targetTriple3331 = try await defaultTargetTriple() #if os(macOS) XCTAssertEqual(try result.buildProduct(for: "lib").linkArguments(), [ result.plan.destinationBuildParameters.toolchain.swiftCompilerPath.pathString, @@ -3274,7 +3290,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", ]) @@ -3288,7 +3304,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath", "-Xlinker", "@loader_path", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", ]) #elseif os(Windows) @@ -3300,7 +3316,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-library", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) @@ -3312,7 +3328,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ]) #else @@ -3327,7 +3343,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", ]) #else @@ -3341,7 +3357,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "lib.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", ]) #endif @@ -3355,7 +3371,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-Xlinker", "-rpath=$ORIGIN", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-runtime-compatibility-version", "none", - "-target", defaultTargetTriple, + "-target", targetTriple3331, "-g", ]) #endif @@ -3857,9 +3873,10 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { XCTAssertNoDiagnostics(observability.diagnostics) func check(for mode: BuildParameters.IndexStoreMode, config: BuildConfiguration) async throws { + let defaultToolchain = try await UserToolchain.default() let result = try await BuildPlanResult(plan: mockBuildPlan( config: config, - toolchain: try UserToolchain.default, + toolchain: defaultToolchain, graph: graph, indexStoreMode: mode, fileSystem: fs, @@ -3935,22 +3952,24 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { let aTarget = try result.moduleBuildDescription(for: "ATarget").swift().compileArguments() #if os(macOS) + let hostTripleString = try await hostTriple().tripleString(forPlatformVersion: "10.13") XCTAssertMatch( aTarget, - [.equal("-target"), .equal(hostTriple.tripleString(forPlatformVersion: "10.13")), .anySequence] + [.equal("-target"), .equal(hostTripleString), .anySequence] ) #else - XCTAssertMatch(aTarget, [.equal("-target"), .equal(defaultTargetTriple), .anySequence]) + let defaultTriple = try await defaultTargetTriple() + XCTAssertMatch(aTarget, [.equal("-target"), .equal(defaultTriple), .anySequence]) #endif let bTarget = try result.moduleBuildDescription(for: "BTarget").swift().compileArguments() #if os(macOS) XCTAssertMatch( bTarget, - [.equal("-target"), .equal(hostTriple.tripleString(forPlatformVersion: "10.13")), .anySequence] + [.equal("-target"), .equal(hostTripleString), .anySequence] ) #else - XCTAssertMatch(bTarget, [.equal("-target"), .equal(defaultTargetTriple), .anySequence]) + XCTAssertMatch(bTarget, [.equal("-target"), .equal(defaultTriple), .anySequence]) #endif } @@ -5226,7 +5245,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let userSwiftSDK = try SwiftSDK( + let userSwiftSDK = try await SwiftSDK( hostTriple: .arm64Linux, targetTriple: .wasi, toolset: .init( @@ -5244,7 +5263,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5371,7 +5390,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5490,7 +5509,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5604,7 +5623,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { func cliFlag(tool: Toolset.KnownTool) -> String { "-\(tool)-flag-from-cli" } func cliFlag(tool: Toolset.KnownTool) -> StringPattern { .equal(cliFlag(tool: tool)) } - let toolset = try Toolset( + let toolset = try await Toolset( knownTools: [ .cCompiler: .init(extraCLIOptions: [jsonFlag(tool: .cCompiler)]), .cxxCompiler: .init(extraCLIOptions: [jsonFlag(tool: .cxxCompiler)]), @@ -5624,7 +5643,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { swiftStaticResourcesPath: "/usr/lib/swift_static/none" ) ) - let toolchain = try UserToolchain( + let toolchain = try await UserToolchain.create( swiftSDK: swiftSDK, environment: .mockEnvironment, customTargetInfo: UserToolchain.mockTargetInfo, @@ -5769,7 +5788,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let targetTriple = try UserToolchain.default.targetTriple + let targetTriple = try await UserToolchain.default().targetTriple let sdkIncludeSearchPath = AbsolutePath("/usr/lib/swift_static/none/include") let sdkLibrarySearchPath = AbsolutePath("/usr/lib/swift_static/none/lib") let swiftSDK = try SwiftSDK( @@ -5785,7 +5804,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let toolchain = try UserToolchain( + let toolchain = try await UserToolchain.create( swiftSDK: swiftSDK, environment: env, searchStrategy: .custom( @@ -7080,7 +7099,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let toolchain = try UserToolchain.default + let toolchain = try await UserToolchain.default() let result = try await BuildPlanResult(plan: mockBuildPlan( toolchain: toolchain, graph: graph, @@ -7137,7 +7156,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let toolchain = try UserToolchain.default + let toolchain = try await UserToolchain.default() let result = try await BuildPlanResult(plan: mockBuildPlan( triple: Triple("arm64-unknown-none"), toolchain: toolchain, @@ -7265,7 +7284,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-5.5/macosx", "-Xlinker", "-rpath", "-Xlinker", "/fake/path/lib/swift-6.2/macosx", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-Xlinker", "-add_ast_path", "-Xlinker", buildPath.appending(components: "Modules", "lib.swiftmodule").pathString, "-Xlinker", "-add_ast_path", @@ -7280,7 +7299,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "exe", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", "-use-ld=lld", "-Xlinker", "-debug:dwarf", ] #else @@ -7291,7 +7310,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { "-module-name", "exe", "-emit-executable", "@\(buildPath.appending(components: "exe.product", "Objects.LinkFileList"))", - "-target", defaultTargetTriple, + "-target", try await defaultTargetTriple(), "-g", ] #endif diff --git a/Tests/BuildTests/BuildSystemDelegateTests.swift b/Tests/BuildTests/BuildSystemDelegateTests.swift index a975f2db9b0..f2a2842f283 100644 --- a/Tests/BuildTests/BuildSystemDelegateTests.swift +++ b/Tests/BuildTests/BuildSystemDelegateTests.swift @@ -76,7 +76,7 @@ struct BuildSystemDelegateTests { configuration: data.config, buildSystem: data.buildSystem, ) - let execPath = try fixturePath.appending( + let execPath = try await fixturePath.appending( components: data.buildSystem.binPath(for: data.config) + [executableName("TestableExe1")] ) expectFileExists(at: execPath) diff --git a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift index 493f3db64df..a1e1892139a 100644 --- a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift +++ b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift @@ -19,35 +19,35 @@ import _InternalTestSupport import XCTest final class ClangTargetBuildDescriptionTests: XCTestCase { - func testClangIndexStorePath() throws { - let targetDescription = try makeTargetBuildDescription("test") + func testClangIndexStorePath() async throws { + let targetDescription = try await makeTargetBuildDescription("test") XCTAssertTrue(try targetDescription.basicArguments().contains("-index-store-path")) XCTAssertFalse(try targetDescription.basicArguments().contains("-w")) } - func testSwiftCorelibsFoundationIncludeWorkaround() throws { + func testSwiftCorelibsFoundationIncludeWorkaround() async throws { let toolchain = MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift")) - let macosParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .macOS) - let linuxParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Linux) - let androidParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Android) + let macosParameters = try await mockBuildParameters(destination: .target, toolchain: toolchain, triple: .macOS) + let linuxParameters = try await mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Linux) + let androidParameters = try await mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Android) - let macDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + let macDescription = try await makeTargetBuildDescription("swift-corelibs-foundation", buildParameters: macosParameters) XCTAssertFalse(try macDescription.basicArguments().contains("\(macosParameters.toolchain.swiftResourcesPath!)")) - let linuxDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + let linuxDescription = try await makeTargetBuildDescription("swift-corelibs-foundation", buildParameters: linuxParameters) print(try linuxDescription.basicArguments()) XCTAssertTrue(try linuxDescription.basicArguments().contains("\(linuxParameters.toolchain.swiftResourcesPath!)")) - let androidDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + let androidDescription = try await makeTargetBuildDescription("swift-corelibs-foundation", buildParameters: androidParameters) XCTAssertTrue(try androidDescription.basicArguments().contains("\(androidParameters.toolchain.swiftResourcesPath!)")) } - func testWarningSuppressionForRemotePackages() throws { - let targetDescription = try makeTargetBuildDescription("test-warning-supression", usesSourceControl: true) + func testWarningSuppressionForRemotePackages() async throws { + let targetDescription = try await makeTargetBuildDescription("test-warning-supression", usesSourceControl: true) XCTAssertTrue(try targetDescription.basicArguments().contains("-w")) } @@ -78,7 +78,7 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { private func makeTargetBuildDescription(_ packageName: String, buildParameters: BuildParameters? = nil, - usesSourceControl: Bool = false) throws -> ClangModuleBuildDescription { + usesSourceControl: Bool = false) async throws -> ClangModuleBuildDescription { let observability = ObservabilitySystem.makeForTesting(verbose: false) let manifest: Manifest @@ -102,6 +102,17 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { targetSearchPath: .root, testTargetSearchPath: .root) + let finalBuildParameters: BuildParameters + if let buildParameters = buildParameters { + finalBuildParameters = buildParameters + } else { + finalBuildParameters = try await mockBuildParameters( + destination: .target, + toolchain: try await UserToolchain.default(), + indexStoreMode: .on + ) + } + return try ClangModuleBuildDescription( package: .init(underlying: package, defaultLocalization: nil, @@ -114,11 +125,7 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { platformVersionProvider: .init(implementation: .minimumDeploymentTargetDefault)), target: target, toolsVersion: .current, - buildParameters: buildParameters ?? mockBuildParameters( - destination: .target, - toolchain: try UserToolchain.default, - indexStoreMode: .on - ), + buildParameters: finalBuildParameters, fileSystem: localFileSystem, observabilityScope: observability.topScope ) diff --git a/Tests/BuildTests/IncrementalBuildTests.swift b/Tests/BuildTests/IncrementalBuildTests.swift index 0e495269ff2..6cb08cee067 100644 --- a/Tests/BuildTests/IncrementalBuildTests.swift +++ b/Tests/BuildTests/IncrementalBuildTests.swift @@ -39,7 +39,8 @@ import typealias TSCBasic.ProcessEnvironmentBlock final class IncrementalBuildTests: XCTestCase { func testIncrementalSingleModuleCLibraryInSources() async throws { - try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test") + let supportsSDKTests = try (try await UserToolchain.default()).supportsSDKDependentTests() + try XCTSkipIf(!supportsSDKTests, "skipping because test environment doesn't support this test") try await fixtureXCTest(name: "CFamilyTargets/CLibrarySources") { fixturePath in // Build it once and capture the log (this will be a full build). let (fullLog, _) = try await executeSwiftBuild(fixturePath, buildSystem: .native) @@ -97,7 +98,8 @@ final class IncrementalBuildTests: XCTestCase { } func testBuildManifestCaching() async throws { - try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test") + let supportsSDKTests = try (try await UserToolchain.default()).supportsSDKDependentTests() + try XCTSkipIf(!supportsSDKTests, "skipping because test environment doesn't support this test") try await fixtureXCTest(name: "ValidLayouts/SingleModule/Library") { fixturePath in @discardableResult func build() async throws -> String { @@ -131,7 +133,8 @@ final class IncrementalBuildTests: XCTestCase { } func testDisableBuildManifestCaching() async throws { - try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test") + let supportsSDKTests = try (try await UserToolchain.default()).supportsSDKDependentTests() + try XCTSkipIf(!supportsSDKTests, "skipping because test environment doesn't support this test") try await fixtureXCTest(name: "ValidLayouts/SingleModule/Library") { fixturePath in @discardableResult func build() async throws -> String { @@ -154,11 +157,12 @@ final class IncrementalBuildTests: XCTestCase { // testing the fix for tracking SDK dependencies to avoid triggering rebuilds when the SDK changes (rdar://115777026) func testSDKTracking() async throws { #if os(macOS) - try XCTSkipIf(!UserToolchain.default.supportsSDKDependentTests(), "skipping because test environment doesn't support this test") + let supportsSDKTests = try (try await UserToolchain.default()).supportsSDKDependentTests() + try XCTSkipIf(!supportsSDKTests, "skipping because test environment doesn't support this test") try await fixtureXCTest(name: "ValidLayouts/SingleModule/Library") { fixturePath in let dummySwiftcPath = SwiftPM.xctestBinaryPath(for: "dummy-swiftc") - let swiftCompilerPath = try UserToolchain.default.swiftCompilerPath + let swiftCompilerPath = try (try await UserToolchain.default()).swiftCompilerPath let environment: Environment = [ "SWIFT_EXEC": dummySwiftcPath.pathString, "SWIFT_ORIGINAL_PATH": swiftCompilerPath.pathString diff --git a/Tests/BuildTests/PluginInvocationTests.swift b/Tests/BuildTests/PluginInvocationTests.swift index 7569ed86851..3731f244cad 100644 --- a/Tests/BuildTests/PluginInvocationTests.swift +++ b/Tests/BuildTests/PluginInvocationTests.swift @@ -130,9 +130,15 @@ final class PluginInvocationTests: XCTestCase { // A fake PluginScriptRunner that just checks the input conditions and returns canned output. struct MockPluginScriptRunner: PluginScriptRunner { + let _hostTriple: Triple + + init(hostTriple: Triple) { + self._hostTriple = hostTriple + } + var hostTriple: Triple { get throws { - return try UserToolchain.default.targetTriple + return _hostTriple } } @@ -230,8 +236,9 @@ final class PluginInvocationTests: XCTestCase { // Construct a canned input and run plugins using our MockPluginScriptRunner(). let outputDir = AbsolutePath("/Foo/.build") - let pluginRunner = MockPluginScriptRunner() - let buildParameters = mockBuildParameters( + let hostTriple = try (try await UserToolchain.default()).targetTriple + let pluginRunner = MockPluginScriptRunner(hostTriple: hostTriple) + let buildParameters = try await mockBuildParameters( destination: .host, environment: BuildEnvironment(platform: .macOS, configuration: .debug) ) @@ -321,10 +328,10 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -354,7 +361,7 @@ final class PluginInvocationTests: XCTestCase { let pluginScriptRunner = DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: pluginCacheDir, - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ) // Define a plugin compilation delegate that just captures the passed information. @@ -455,7 +462,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertEqual(delegate.compiledResult, result) XCTAssertNil(delegate.cachedResult) - if try UserToolchain.default.supportsSerializedDiagnostics() { + if try (try await UserToolchain.default()).supportsSerializedDiagnostics() { // Check the serialized diagnostics. We should no longer have an error but now have a warning. let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile) let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents) @@ -505,7 +512,7 @@ final class PluginInvocationTests: XCTestCase { XCTAssertNil(delegate.compiledResult) XCTAssertEqual(delegate.cachedResult, result) - if try UserToolchain.default.supportsSerializedDiagnostics() { + if try (try await UserToolchain.default()).supportsSerializedDiagnostics() { // Check that the diagnostics still have the same warning as before. let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile) let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents) @@ -635,7 +642,8 @@ final class PluginInvocationTests: XCTestCase { func testUnsupportedDependencyProduct() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library product and a plugin. @@ -701,10 +709,10 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -733,7 +741,8 @@ final class PluginInvocationTests: XCTestCase { func testUnsupportedDependencyTarget() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -780,10 +789,10 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -812,7 +821,8 @@ final class PluginInvocationTests: XCTestCase { func testPrebuildPluginShouldUseBinaryTarget() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -889,7 +899,7 @@ final class PluginInvocationTests: XCTestCase { } """) - let artifactVariants = [try UserToolchain.default.targetTriple].map { + let artifactVariants = [try (try await UserToolchain.default()).targetTriple].map { """ { "path": "Y", "supportedTriples": ["\($0.tripleString)"] } """ @@ -919,10 +929,10 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -952,13 +962,13 @@ final class PluginInvocationTests: XCTestCase { let pluginScriptRunner = DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: pluginCacheDir, - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ) // Invoke build tool plugin do { let outputDir = packageDir.appending(".build") - let buildParameters = mockBuildParameters( + let buildParameters = try await mockBuildParameters( destination: .host, environment: BuildEnvironment(platform: .macOS, configuration: .debug) ) @@ -983,7 +993,8 @@ final class PluginInvocationTests: XCTestCase { func testPrebuildPluginShouldNotUseExecTarget() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -1061,10 +1072,10 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -1094,13 +1105,13 @@ final class PluginInvocationTests: XCTestCase { let pluginScriptRunner = DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: pluginCacheDir, - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ) // Invoke build tool plugin do { let outputDir = packageDir.appending(".build") - let buildParameters = mockBuildParameters( + let buildParameters = try await mockBuildParameters( destination: .host, environment: BuildEnvironment(platform: .macOS, configuration: .debug) ) @@ -1125,7 +1136,8 @@ final class PluginInvocationTests: XCTestCase { func testScanImportsInPluginTargets() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -1249,17 +1261,17 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() let environment = Environment.current - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, location: try Workspace.Location(forRootPackage: packageDir, fileSystem: localFileSystem), - customHostToolchain: UserToolchain( - swiftSDK: .hostSwiftSDK( + customHostToolchain: await UserToolchain( + swiftSDK: await SwiftSDK.hostSwiftSDK( environment: environment ), environment: environment, customLibrariesLocation: .init(manifestLibraryPath: fakeExtraModulesDir, pluginLibraryPath: fakeExtraModulesDir) ), - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -1311,7 +1323,8 @@ final class PluginInvocationTests: XCTestCase { hostTriple: Triple ) async throws -> [ResolvedModule.ID: [BuildToolPluginInvocationResult]] { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let supportsConcurrency = try (try await UserToolchain.default()).supportsSwiftConcurrency() + try XCTSkipIf(!supportsConcurrency, "skipping because test environment doesn't support concurrency") return try await testWithTemporaryDirectory { tmpPath in // Create a sample package with a library target and a plugin. @@ -1402,10 +1415,10 @@ final class PluginInvocationTests: XCTestCase { ) // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -1433,8 +1446,8 @@ final class PluginInvocationTests: XCTestCase { XCTAssertEqual(buildToolPlugin.capability, .buildTool) // Construct a toolchain with a made-up host/target triple - let swiftSDK = try SwiftSDK.default - let toolchain = try UserToolchain( + let swiftSDK = try await SwiftSDK.default() + let toolchain = try await UserToolchain.create( swiftSDK: SwiftSDK( hostTriple: hostTriple, targetTriple: hostTriple, @@ -1454,7 +1467,7 @@ final class PluginInvocationTests: XCTestCase { // Invoke build tool plugin let outputDir = packageDir.appending(".build") - let buildParameters = mockBuildParameters( + let buildParameters = try await mockBuildParameters( destination: .host, environment: BuildEnvironment(platform: .macOS, configuration: .debug) ) @@ -1471,7 +1484,7 @@ final class PluginInvocationTests: XCTestCase { } func testParseArtifactNotSupportedOnTargetPlatform() async throws { - let hostTriple = try UserToolchain.default.targetTriple + let hostTriple = try (try await UserToolchain.default()).targetTriple let artifactSupportedTriples = try [Triple("riscv64-apple-windows-android")] var checked = false @@ -1488,7 +1501,7 @@ final class PluginInvocationTests: XCTestCase { #if !os(macOS) throw XCTSkip("platform versions are only available if the host is macOS") #else - let hostTriple = try UserToolchain.default.targetTriple + let hostTriple = try (try await UserToolchain.default()).targetTriple let artifactSupportedTriples = try [Triple("\(hostTriple.withoutVersion().tripleString)20.0")] let result = try await checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: artifactSupportedTriples, hostTriple: hostTriple) @@ -1502,7 +1515,7 @@ final class PluginInvocationTests: XCTestCase { } func testParseArtifactsConsidersAllSupportedTriples() async throws { - let hostTriple = try UserToolchain.default.targetTriple + let hostTriple = try (try await UserToolchain.default()).targetTriple let artifactSupportedTriples = [hostTriple, try Triple("riscv64-apple-windows-android")] let result = try await checkParseArtifactsPlatformCompatibility(artifactSupportedTriples: artifactSupportedTriples, hostTriple: hostTriple) @@ -1542,6 +1555,8 @@ final class PluginInvocationTests: XCTestCase { disableSandbox: false ) + let hostTriple = try await hostTriple() + for (moduleID, _) in pluginsPerModule { let module = graph.allModules[moduleID]! diff --git a/Tests/BuildTests/PluginsBuildPlanTests.swift b/Tests/BuildTests/PluginsBuildPlanTests.swift index 60e04740d1e..928853e68e3 100644 --- a/Tests/BuildTests/PluginsBuildPlanTests.swift +++ b/Tests/BuildTests/PluginsBuildPlanTests.swift @@ -62,17 +62,17 @@ struct PluginsBuildPlanTests { func commandPluginDependenciesWhenNotCrossCompiling( buildData: BuildData, ) async throws { - let hostToolchain = try UserToolchain( - swiftSDK: .hostSwiftSDK(environment: [:]), + let hostToolchain = try await UserToolchain.create( + swiftSDK: try await SwiftSDK.hostSwiftSDKAsync(environment: [:]), environment: [:] ) let hostTriple = try! hostToolchain.targetTriple.withoutVersion().tripleString - let hostBinPathSegments = try buildData.buildSystem.binPath( + let hostBinPathSegments = try await buildData.buildSystem.binPath( for: buildData.config, triple: hostTriple, ) - let hostDebugBinPathSegments = try buildData.buildSystem.binPath( + let hostDebugBinPathSegments = try await buildData.buildSystem.binPath( for: .debug, triple: hostTriple, ) @@ -116,8 +116,8 @@ struct PluginsBuildPlanTests { func commandPluginDependenciesWhenCrossCompiling( buildData: BuildData, ) async throws { - let hostToolchain = try UserToolchain( - swiftSDK: .hostSwiftSDK(environment: [:]), + let hostToolchain = try await UserToolchain.create( + swiftSDK: try await SwiftSDK.hostSwiftSDKAsync(environment: [:]), environment: [:] ) // let hostTriple = try! hostToolchain.targetTriple.withoutVersion().tripleString @@ -126,10 +126,10 @@ struct PluginsBuildPlanTests { let armTriple = "arm64-apple-macosx" let targetTriple = hostToolchain.targetTriple.arch == .aarch64 ? x86Triple : armTriple - let hostBinPathSegments = try buildData.buildSystem.binPath( + let hostBinPathSegments = try await buildData.buildSystem.binPath( for: buildData.config, ) - let targetDebugBinPathSegments = try buildData.buildSystem.binPath( + let targetDebugBinPathSegments = try await buildData.buildSystem.binPath( for: .debug, triple: targetTriple, ) @@ -139,12 +139,12 @@ struct PluginsBuildPlanTests { // let hostBinPath: AbsolutePath = fixturePath.appending(components: hostBinPathSegments) let targetDebugBinPath: AbsolutePath = fixturePath.appending(components: targetDebugBinPathSegments) let hostBinPath = try fixturePath.appending( - components: buildData.buildSystem.binPath( + components: try await buildData.buildSystem.binPath( for: buildData.config, ) ) let targetBinPath = try fixturePath.appending( - components: buildData.buildSystem.binPath( + components: try await buildData.buildSystem.binPath( for: buildData.config, triple: targetTriple, ) diff --git a/Tests/BuildTests/PrepareForIndexTests.swift b/Tests/BuildTests/PrepareForIndexTests.swift index f49e09cc851..9aa870a0932 100644 --- a/Tests/BuildTests/PrepareForIndexTests.swift +++ b/Tests/BuildTests/PrepareForIndexTests.swift @@ -210,7 +210,7 @@ class PrepareForIndexTests: XCTestCase { XCTAssertTrue(coreSwiftc.otherArguments.contains("-experimental-allow-module-with-compiler-errors")) } - func testToolsDontPrepare() throws { + func testToolsDontPrepare() async throws { let options = try GlobalOptions.parse(["--experimental-prepare-for-indexing"]) let state = try SwiftCommandState( outputStream: stderrStream, @@ -236,9 +236,11 @@ class PrepareForIndexTests: XCTestCase { environment: .current ) - XCTAssertEqual(try state.productsBuildParameters.prepareForIndexing, .on) + let productsPrepareForIndexing = try await state.productsBuildParameters.prepareForIndexing + XCTAssertEqual(productsPrepareForIndexing, .on) // Tools builds should never do prepare for indexing since they're needed // for the prepare builds. - XCTAssertEqual(try state.toolsBuildParameters.prepareForIndexing, .off) + let toolsPrepareForIndexing = try await state.toolsBuildParameters.prepareForIndexing + XCTAssertEqual(toolsPrepareForIndexing, .off) } } diff --git a/Tests/BuildTests/ProductBuildDescriptionTests.swift b/Tests/BuildTests/ProductBuildDescriptionTests.swift index 5674142e10d..099600f4dc1 100644 --- a/Tests/BuildTests/ProductBuildDescriptionTests.swift +++ b/Tests/BuildTests/ProductBuildDescriptionTests.swift @@ -30,7 +30,7 @@ import func _InternalTestSupport.XCTAssertNoDiagnostics import XCTest final class ProductBuildDescriptionTests: XCTestCase { - func testEmbeddedProducts() throws { + func testEmbeddedProducts() async throws { let fs = InMemoryFileSystem( emptyFiles: "/Pkg/Sources/exe/main.swift" @@ -63,7 +63,7 @@ final class ProductBuildDescriptionTests: XCTestCase { package: package, product: product, toolsVersion: .v5_9, - buildParameters: mockBuildParameters(destination: .target, environment: .init(platform: .macOS)), + buildParameters: try await mockBuildParameters(destination: .target, environment: .init(platform: .macOS)), fileSystem: fs, observabilityScope: observability.topScope ) diff --git a/Tests/CommandsTests/APIDiffTests.swift b/Tests/CommandsTests/APIDiffTests.swift index 27306499256..afc6d5688f2 100644 --- a/Tests/CommandsTests/APIDiffTests.swift +++ b/Tests/CommandsTests/APIDiffTests.swift @@ -28,7 +28,7 @@ import Testing extension Trait where Self == Testing.ConditionTrait { public static var requiresAPIDigester: Self { enabled("This test requires a toolchain with swift-api-digester") { - (try? UserToolchain.default.getSwiftAPIDigester()) != nil && ProcessInfo.hostOperatingSystem != .windows + (try? await UserToolchain.default().getSwiftAPIDigester()) != nil && ProcessInfo.hostOperatingSystem != .windows } } } diff --git a/Tests/CommandsTests/BuildCommandTests.swift b/Tests/CommandsTests/BuildCommandTests.swift index af41478061a..53ad12f4032 100644 --- a/Tests/CommandsTests/BuildCommandTests.swift +++ b/Tests/CommandsTests/BuildCommandTests.swift @@ -150,7 +150,7 @@ struct BuildCommandTestCases { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in let fullPath = try resolveSymlinks(fixturePath) - let targetPath = try fullPath.appending(components: buildSystem.binPath(for: configuration)) + let targetPath = try await fullPath.appending(components: buildSystem.binPath(for: configuration)) let path = try await execute( ["--show-bin-path"], packagePath: fullPath, @@ -317,8 +317,8 @@ struct BuildCommandTestCases { let fullPath = try resolveSymlinks(fixturePath) // Test symlink. try await execute(packagePath: fullPath, configuration: configuration, buildSystem: buildSystem) - let actualDebug = try resolveSymlinks(fullPath.appending(components: buildSystem.binPath(for: configuration))) - let expectedDebug = try fullPath.appending(components: buildSystem.binPath(for: configuration)) + let actualDebug = try resolveSymlinks(fullPath.appending(components: await buildSystem.binPath(for: configuration))) + let expectedDebug = try await fullPath.appending(components: buildSystem.binPath(for: configuration)) #expect(actualDebug == expectedDebug) } } when: { @@ -858,7 +858,7 @@ struct BuildCommandTestCases { // In the case of the native build system check for the cross-compile target, only for macOS #if os(macOS) if buildSystem == .native { - let targetTripleString = try UserToolchain.default.targetTriple.tripleString(forPlatformVersion: "") + let targetTripleString = try await UserToolchain.default().targetTriple.tripleString(forPlatformVersion: "") #expect(output.stdout.contains("-target \(targetTripleString)")) } #endif @@ -916,7 +916,7 @@ struct BuildCommandTestCases { let config = data.config try await withKnownIssue(isIntermittent: true) { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in - let swiftCompilerPath = try UserToolchain.default.swiftCompilerPath + let swiftCompilerPath = try await UserToolchain.default().swiftCompilerPath // try await building without specifying overrides. This should succeed, and should use the default // compiler path. let defaultOutput = try await execute( @@ -1026,7 +1026,7 @@ struct BuildCommandTestCases { return buildArenaPath.appending(component: filename) } let dummySwiftcPath = SwiftPM.xctestBinaryPath(for: "dummy-swiftc") - let swiftCompilerPath = try UserToolchain.default.swiftCompilerPath + let swiftCompilerPath = try await UserToolchain.default().swiftCompilerPath var environment: Environment = [ "SWIFT_EXEC": dummySwiftcPath.pathString, @@ -1260,10 +1260,10 @@ struct BuildCommandTestCases { func buildSystemAndOutputLocation( buildSystem: BuildSystemProvider.Kind, configuration: BuildConfiguration, - ) throws -> Basics.RelativePath { - let triple = try UserToolchain.default.targetTriple.withoutVersion() + ) async throws -> Basics.RelativePath { + let triple = try await UserToolchain.default().targetTriple.withoutVersion() let base = try RelativePath(validating: ".build") - let path = try base.appending(components: buildSystem.binPath(for: configuration, scratchPath: [])) + let path = try await base.appending(components: buildSystem.binPath(for: configuration, scratchPath: [])) switch buildSystem { case .xcode: return triple.platformName() == "macosx" ? path.appending("ExecutableNew") : path @@ -1290,7 +1290,7 @@ struct BuildCommandTestCases { cleanAfterward: false, buildSystem: data.buildSystem, ) - let mainOFile = try fixturePath.appending(buildSystemAndOutputLocation(buildSystem: data.buildSystem, configuration: data.config)) + let mainOFile = try await fixturePath.appending(buildSystemAndOutputLocation(buildSystem: data.buildSystem, configuration: data.config)) let initialMainOMtime = try FileManager.default.attributesOfItem(atPath: mainOFile.pathString)[.modificationDate] as? Date _ = try await build( diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 03834d1f389..988ee4216e9 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -1070,7 +1070,7 @@ struct PackageCommandTests { let tool = try SwiftCommandState.makeMockState( options: GlobalOptions.parse(["--package-path", fixturePath.pathString]) ) - let symbolGraphExtractorPath = try tool.getTargetToolchain().getSymbolGraphExtract() + let symbolGraphExtractorPath = try await tool.getTargetToolchain().getSymbolGraphExtract() let arguments = withPrettyPrinting ? ["dump-symbol-graph", "--pretty-print"] : ["dump-symbol-graph"] @@ -2724,7 +2724,7 @@ struct PackageCommandTests { ) // Path to the executable. - let binPath = try fooPath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fooPath.appending(components: data.buildSystem.binPath(for: data.config)) let exec = [ binPath.appending("foo").pathString ] @@ -2854,7 +2854,7 @@ struct PackageCommandTests { buildSystem: data.buildSystem, ) let buildPath = packageRoot.appending(".build") - let binPath = try buildPath.appending(components: data.buildSystem.binPath(for: data.config, scratchPath: [])) + let binPath = try await buildPath.appending(components: data.buildSystem.binPath(for: data.config, scratchPath: [])) let binFile = binPath.appending(executableName("Bar")) expectFileExists(at: binFile) #expect(localFileSystem.isDirectory(buildPath)) @@ -2899,7 +2899,7 @@ struct PackageCommandTests { buildSystem: data.buildSystem ) let buildPath = packageRoot.appending(".build") - let binPath = try buildPath.appending(components: data.buildSystem.binPath(for: data.config, scratchPath: [], )) + let binPath = try await buildPath.appending(components: data.buildSystem.binPath(for: data.config, scratchPath: [], )) let binFile = binPath.appending(executableName("Bar")) expectFileExists(at: binFile) #expect(localFileSystem.isDirectory(buildPath)) @@ -3108,7 +3108,7 @@ struct PackageCommandTests { ) async throws { try await fixture(name: "Miscellaneous/PackageEdit") { fixturePath in let fooPath = fixturePath.appending("foo") - let binPath = try fooPath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fooPath.appending(components: data.buildSystem.binPath(for: data.config)) let exec = [ binPath.appending("foo").pathString ] @@ -4691,8 +4691,8 @@ struct PackageCommandTests { """ ) let environment = Environment.current - let hostTriple = try UserToolchain( - swiftSDK: .hostSwiftSDK(environment: environment), + let hostTriple = try await UserToolchain.create( + swiftSDK: try await .hostSwiftSDKAsync(environment: environment), environment: environment ).targetTriple let hostTripleString = @@ -4927,8 +4927,8 @@ struct PackageCommandTests { """ ) let environment = Environment.current - let hostTriple = try UserToolchain( - swiftSDK: .hostSwiftSDK(environment: environment), + let hostTriple = try await UserToolchain.create( + swiftSDK: try await .hostSwiftSDKAsync(environment: environment), environment: environment ).targetTriple let hostTripleString = @@ -5329,8 +5329,8 @@ struct PackageCommandTests { func commandPluginTargetBuilds_BinaryIsBuildinDebugByDefault( buildData: BuildData, ) async throws { - let debugTarget = try buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] - let releaseTarget = try buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] + let debugTarget = try await buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] + let releaseTarget = try await buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] try await withKnownIssue { // By default, a plugin-requested build produces a debug binary try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in @@ -5360,8 +5360,8 @@ struct PackageCommandTests { func commandPluginTargetBuilds_BinaryWillBeBuiltInDebugIfPluginSpecifiesDebugBuild( buildData: BuildData, ) async throws { - let debugTarget = try buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] - let releaseTarget = try buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] + let debugTarget = try await buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] + let releaseTarget = try await buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] try await withKnownIssue { // If the plugin specifies a debug binary, that is what will be built, regardless of overall configuration try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in @@ -5395,8 +5395,8 @@ struct PackageCommandTests { func commandPluginTargetBuilds_BinaryWillBeBuiltInReleaseIfPluginSpecifiesReleaseBuild( buildData: BuildData, ) async throws { - let debugTarget = try buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] - let releaseTarget = try buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] + let debugTarget = try await buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] + let releaseTarget = try await buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] try await withKnownIssue { // If the plugin requests a release binary, that is what will be built, regardless of overall configuration try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in @@ -5429,8 +5429,8 @@ struct PackageCommandTests { func commandPluginTargetBuilds_BinaryWillBeBuiltCorrectlyIfPluginSpecifiesInheritBuild( buildData: BuildData, ) async throws { - let debugTarget = try buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] - let releaseTarget = try buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] + let debugTarget = try await buildData.buildSystem.binPath(for: .debug) + [executableName("placeholder")] + let releaseTarget = try await buildData.buildSystem.binPath(for: .release) + [executableName("placeholder")] try await withKnownIssue { // If the plugin inherits the overall build configuration, that is what will be built try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in @@ -7275,10 +7275,10 @@ struct PackageCommandTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) diff --git a/Tests/CommandsTests/SwiftCommandStateTests.swift b/Tests/CommandsTests/SwiftCommandStateTests.swift index 17b0a8f2e91..38cb636639f 100644 --- a/Tests/CommandsTests/SwiftCommandStateTests.swift +++ b/Tests/CommandsTests/SwiftCommandStateTests.swift @@ -330,8 +330,13 @@ final class SwiftCommandStateTests: XCTestCase { let unsupportedCodeViewOptions = try GlobalOptions.parse(["--triple", "x86_64-unknown-linux-gnu", "-debug-info-format", "codeview"]) let unsupportedCodeView = try SwiftCommandState.makeMockState(options: unsupportedCodeViewOptions) - XCTAssertThrowsError(try unsupportedCodeView.productsBuildParameters) { - XCTAssertEqual($0 as? StringError, StringError("CodeView debug information is currently not supported on linux")) + do { + _ = try await unsupportedCodeView.productsBuildParameters + XCTFail("Expected error to be thrown") + } catch let error as StringError { + XCTAssertEqual(error, StringError("CodeView debug information is currently not supported on linux")) + } catch { + XCTFail("Unexpected error: \(error)") } /* <> */ @@ -405,12 +410,13 @@ final class SwiftCommandStateTests: XCTestCase { ) XCTAssertEqual(swiftCommandState.originalWorkingDirectory, fs.currentWorkingDirectory) + let targetToolchain = try await swiftCommandState.getTargetToolchain() XCTAssertEqual( - try swiftCommandState.getTargetToolchain().swiftCompilerPath, + targetToolchain.swiftCompilerPath, targetSwiftcPath ) XCTAssertEqual( - try swiftCommandState.getTargetToolchain().swiftSDK.toolset.knownTools[.swiftCompiler]?.path, + targetToolchain.swiftSDK.toolset.knownTools[.swiftCompiler]?.path, nil ) @@ -427,7 +433,7 @@ final class SwiftCommandStateTests: XCTestCase { XCTAssertMatch(arguments, [.contains("/path/to/toolchain")]) } - func testToolsetOption() throws { + func testToolsetOption() async throws { try XCTSkipOnWindows(because: #"https://github.com/swiftlang/swift-package-manager/issues/8660. threw error \"toolchain is invalid: could not find CLI tool `swiftc` at any of these directories: []\", needs investigation"#) let targetToolchainPath = "/path/to/toolchain" let customTargetToolchain = AbsolutePath(targetToolchainPath) @@ -461,8 +467,8 @@ final class SwiftCommandStateTests: XCTestCase { environment: ["PATH": "/usr/bin"] ) - let hostToolchain = try swiftCommandState.getHostToolchain() - let targetToolchain = try swiftCommandState.getTargetToolchain() + let hostToolchain = try await swiftCommandState.getHostToolchain() + let targetToolchain = try await swiftCommandState.getTargetToolchain() XCTAssertEqual( targetToolchain.swiftSDK.toolset.rootPaths, @@ -472,7 +478,7 @@ final class SwiftCommandStateTests: XCTestCase { XCTAssertEqual(targetToolchain.librarianPath, targetArPath) } - func testMultipleToolsets() throws { + func testMultipleToolsets() async throws { try XCTSkipOnWindows(because: #"https://github.com/swiftlang/swift-package-manager/issues/8660, threw error \"toolchain is invalid: could not find CLI tool `swiftc` at any of these directories: []\", needs investigation"#) let targetToolchainPath1 = "/path/to/toolchain1" let customTargetToolchain1 = AbsolutePath(targetToolchainPath1) @@ -519,8 +525,8 @@ final class SwiftCommandStateTests: XCTestCase { environment: ["PATH": "/usr/bin"] ) - let hostToolchain = try swiftCommandState.getHostToolchain() - let targetToolchain = try swiftCommandState.getTargetToolchain() + let hostToolchain = try await swiftCommandState.getHostToolchain() + let targetToolchain = try await swiftCommandState.getTargetToolchain() XCTAssertEqual( targetToolchain.swiftSDK.toolset.rootPaths, diff --git a/Tests/CommandsTests/TestCommandTests.swift b/Tests/CommandsTests/TestCommandTests.swift index 10dce1188a8..73aef85c84b 100644 --- a/Tests/CommandsTests/TestCommandTests.swift +++ b/Tests/CommandsTests/TestCommandTests.swift @@ -1075,7 +1075,7 @@ struct TestCommandTests { try await withKnownIssue("produces a filepath that is too long, needs investigation", isIntermittent: true) { try await fixture(name: "Miscellaneous/CheckTestLibraryEnvironmentVariable") { fixturePath in var extraEnv = Environment() - if try UserToolchain.default.swiftTestingPath != nil { + if try await UserToolchain.default().swiftTestingPath != nil { extraEnv["CONTAINS_SWIFT_TESTING"] = "1" } await #expect(throws: Never.self) { diff --git a/Tests/FunctionalTests/CFamilyTargetTests.swift b/Tests/FunctionalTests/CFamilyTargetTests.swift index ff4d024be97..29814b391a8 100644 --- a/Tests/FunctionalTests/CFamilyTargetTests.swift +++ b/Tests/FunctionalTests/CFamilyTargetTests.swift @@ -64,7 +64,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "Bar.c.o") expectDirectoryContainsFile(dir: binPath, filename: "Foo.c.o") } @@ -96,7 +96,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try packageRoot.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await packageRoot.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "Sea.c.o") expectDirectoryContainsFile(dir: binPath, filename: "Foo.c.o") } @@ -130,7 +130,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "Jaz.c.o") expectDirectoryContainsFile(dir: binPath, filename: "main.swift.o") expectDirectoryContainsFile(dir: binPath, filename: "FlatInclude.c.o") @@ -188,7 +188,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "Foo.c.o") } } @@ -218,7 +218,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "HelloWorldExample.m.o") expectDirectoryContainsFile(dir: binPath, filename: "HelloWorldExample.m.o") } @@ -254,7 +254,7 @@ struct CFamilyTargetTestCase { buildSystem: data.buildSystem, ) if data.buildSystem == .native { - let binPath = try fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) + let binPath = try await fixturePath.appending(components: data.buildSystem.binPath(for: data.config)) expectDirectoryContainsFile(dir: binPath, filename: "HeaderInclude.swiftmodule") } } diff --git a/Tests/FunctionalTests/DependencyResolutionTests.swift b/Tests/FunctionalTests/DependencyResolutionTests.swift index e71c08b46eb..52a9a0fd80e 100644 --- a/Tests/FunctionalTests/DependencyResolutionTests.swift +++ b/Tests/FunctionalTests/DependencyResolutionTests.swift @@ -50,7 +50,7 @@ struct DependencyResolutionTests { buildSystem: buildSystem, ) - let binPath = try fixturePath.appending(components: buildSystem.binPath(for: configuration)) + let binPath = try await fixturePath.appending(components: buildSystem.binPath(for: configuration)) let executablePath = binPath.appending(components: "Foo") let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString).withSwiftLineEnding #expect(output == "Foo\nBar\n") @@ -108,7 +108,7 @@ struct DependencyResolutionTests { buildSystem: buildSystem, ) - let binPath = try fixturePath.appending(components: buildSystem.binPath(for: configuration)) + let binPath = try await fixturePath.appending(components: buildSystem.binPath(for: configuration)) let executablePath = binPath.appending(components: "Foo") let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString) .withSwiftLineEnding @@ -146,7 +146,7 @@ struct DependencyResolutionTests { configuration: configuration, buildSystem: buildSystem, ) - let binPath = try packageRoot.appending(components: buildSystem.binPath(for: configuration)) + let binPath = try await packageRoot.appending(components: buildSystem.binPath(for: configuration)) let executablePath = binPath.appending(components: executableName("Bar")) #expect( localFileSystem.exists(executablePath), @@ -181,7 +181,7 @@ struct DependencyResolutionTests { configuration: configuration, buildSystem: buildSystem, ) - let binPath = try packageRoot.appending(components: buildSystem.binPath(for: configuration)) + let binPath = try await packageRoot.appending(components: buildSystem.binPath(for: configuration)) let executablePath = binPath.appending(components: "Dealer") expectFileExists(at: executablePath) let output = try await AsyncProcess.checkNonZeroExit(args: executablePath.pathString) diff --git a/Tests/FunctionalTests/MiscellaneousTests.swift b/Tests/FunctionalTests/MiscellaneousTests.swift index f10c6b65872..4c614567d6b 100644 --- a/Tests/FunctionalTests/MiscellaneousTests.swift +++ b/Tests/FunctionalTests/MiscellaneousTests.swift @@ -55,7 +55,7 @@ final class MiscellaneousTestCase: XCTestCase { fixturePath.appending("app"), buildSystem: .native, ) - let buildDir = fixturePath.appending(components: "app", ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug") + let buildDir = fixturePath.appending(components: "app", ".build", try await UserToolchain.default().targetTriple.platformBuildPathComponent, "debug") XCTAssertFileExists(buildDir.appending(executableName("FooExec"))) XCTAssertFileExists(buildDir.appending(components: "Modules", "FooLib1.swiftmodule")) XCTAssertFileExists(buildDir.appending(components: "Modules", "FooLib2.swiftmodule")) @@ -137,7 +137,7 @@ final class MiscellaneousTestCase: XCTestCase { */ func testInternalDependencyEdges() async throws { try await fixtureXCTest(name: "Miscellaneous/DependencyEdges/Internal") { fixturePath in - let execpath = fixturePath.appending(components: ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", "Foo").pathString + let execpath = fixturePath.appending(components: ".build", try await UserToolchain.default().targetTriple.platformBuildPathComponent, "debug", "Foo").pathString await XCTAssertBuilds( fixturePath, @@ -167,7 +167,7 @@ final class MiscellaneousTestCase: XCTestCase { */ func testExternalDependencyEdges1() async throws { try await fixtureXCTest(name: "DependencyResolution/External/Complex") { fixturePath in - let execpath = fixturePath.appending(components: "app", ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", "Dealer").pathString + let execpath = fixturePath.appending(components: "app", ".build", try await UserToolchain.default().targetTriple.platformBuildPathComponent, "debug", "Dealer").pathString let packageRoot = fixturePath.appending("app") await XCTAssertBuilds( @@ -200,7 +200,7 @@ final class MiscellaneousTestCase: XCTestCase { */ func testExternalDependencyEdges2() async throws { try await fixtureXCTest(name: "Miscellaneous/DependencyEdges/External") { fixturePath in - let execpath = [fixturePath.appending(components: "root", ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", "dep2").pathString] + let execpath = [fixturePath.appending(components: "root", ".build", try await UserToolchain.default().targetTriple.platformBuildPathComponent, "debug", "dep2").pathString] let packageRoot = fixturePath.appending("root") await XCTAssertBuilds( @@ -233,7 +233,7 @@ final class MiscellaneousTestCase: XCTestCase { fixturePath, buildSystem: .native, ) - XCTAssertFileExists(fixturePath.appending(components: ".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "debug", "Module_Name_1.build", "Foo.swift.o")) + XCTAssertFileExists(fixturePath.appending(components: ".build", try await UserToolchain.default().targetTriple.platformBuildPathComponent, "debug", "Module_Name_1.build", "Foo.swift.o")) } } @@ -261,7 +261,7 @@ final class MiscellaneousTestCase: XCTestCase { try XCTSkipIf(true, "test is only supported on macOS") #endif try await fixtureXCTest(name: "Miscellaneous/DistantFutureDeploymentTarget") { fixturePath in - let hostTriple = try UserToolchain.default.targetTriple + let hostTriple = try await UserToolchain.default().targetTriple try await executeSwiftBuild( fixturePath, Xswiftc: ["-target", "\(hostTriple.archName)-apple-macosx41.0"], @@ -276,7 +276,7 @@ final class MiscellaneousTestCase: XCTestCase { let systemModule = fixturePath.appending("SystemModule") // Create a shared library. let input = systemModule.appending(components: "Sources", "SystemModule.c") - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple let output = systemModule.appending("libSystemModule\(triple.dynamicLibraryExtension)") try await AsyncProcess.checkNonZeroExit(args: executableName("clang"), "-shared", input.pathString, "-o", output.pathString) @@ -764,7 +764,8 @@ final class MiscellaneousTestCase: XCTestCase { func testPluginGeneratedResources() async throws { // Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require). - try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") + let defaultToolchain = try await UserToolchain.default() + try XCTSkipIf(!defaultToolchain.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency") try XCTSkipOnWindows( because: """ Invalid path. Possibly related to https://github.com/swiftlang/swift-package-manager/issues/8511 or https://github.com/swiftlang/swift-package-manager/issues/8602 diff --git a/Tests/FunctionalTests/ModuleAliasingFixtureTests.swift b/Tests/FunctionalTests/ModuleAliasingFixtureTests.swift index db0b9d251e3..c1b141d05a7 100644 --- a/Tests/FunctionalTests/ModuleAliasingFixtureTests.swift +++ b/Tests/FunctionalTests/ModuleAliasingFixtureTests.swift @@ -42,7 +42,7 @@ struct ModuleAliasingFixtureTests { try await withKnownIssue(isIntermittent: true) { try await fixture(name: "ModuleAliasing/DirectDeps1") { fixturePath in let pkgPath = fixturePath.appending(components: "AppPkg") - let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration)) + let buildPath = try await pkgPath.appending(components: buildSystem.binPath(for: configuration)) let expectedModules = [ "GameUtils.swiftmodule", "Utils.swiftmodule", @@ -94,7 +94,7 @@ struct ModuleAliasingFixtureTests { try await withKnownIssue(isIntermittent: true) { try await fixture(name: "ModuleAliasing/DirectDeps2") { fixturePath in let pkgPath = fixturePath.appending(components: "AppPkg") - let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration)) + let buildPath = try await pkgPath.appending(components: buildSystem.binPath(for: configuration)) let expectedModules = [ "AUtils.swiftmodule", "BUtils.swiftmodule", @@ -145,7 +145,7 @@ struct ModuleAliasingFixtureTests { try await withKnownIssue(isIntermittent: true) { try await fixture(name: "ModuleAliasing/NestedDeps1") { fixturePath in let pkgPath = fixturePath.appending(components: "AppPkg") - let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration)) + let buildPath = try await pkgPath.appending(components: buildSystem.binPath(for: configuration)) let expectedModules = [ "A.swiftmodule", "AFooUtils.swiftmodule", @@ -201,7 +201,7 @@ struct ModuleAliasingFixtureTests { try await withKnownIssue(isIntermittent: true) { try await fixture(name: "ModuleAliasing/NestedDeps2") { fixturePath in let pkgPath = fixturePath.appending(components: "AppPkg") - let buildPath = try pkgPath.appending(components: buildSystem.binPath(for: configuration)) + let buildPath = try await pkgPath.appending(components: buildSystem.binPath(for: configuration)) try await executeSwiftBuild( pkgPath, configuration: configuration, diff --git a/Tests/FunctionalTests/ModuleMapTests.swift b/Tests/FunctionalTests/ModuleMapTests.swift index 94d72a6ac3a..846ad1a879d 100644 --- a/Tests/FunctionalTests/ModuleMapTests.swift +++ b/Tests/FunctionalTests/ModuleMapTests.swift @@ -26,7 +26,7 @@ final class ModuleMapsTestCase: XCTestCase { ) async throws { try await _InternalTestSupport.fixtureXCTest(name: name) { fixturePath in let input = fixturePath.appending(components: cModuleName, "C", "foo.c") - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple let outdir = fixturePath.appending(components: rootpkg, ".build", triple.platformBuildPathComponent, "debug") try makeDirectories(outdir) let output = outdir.appending("libfoo\(triple.dynamicLibraryExtension)") @@ -50,7 +50,7 @@ final class ModuleMapsTestCase: XCTestCase { buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple let targetPath = fixturePath.appending(components: "App", ".build", triple.platformBuildPathComponent) let debugout = try await AsyncProcess.checkNonZeroExit( args: targetPath.appending(components: "debug", "App").pathString @@ -73,7 +73,7 @@ final class ModuleMapsTestCase: XCTestCase { ) func verify(_ conf: String) async throws { - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple let out = try await AsyncProcess.checkNonZeroExit( args: fixturePath.appending(components: "packageA", ".build", triple.platformBuildPathComponent, conf, "packageA").pathString ) diff --git a/Tests/FunctionalTests/PluginTests.swift b/Tests/FunctionalTests/PluginTests.swift index b4eafeea5db..efc4e2d26e1 100644 --- a/Tests/FunctionalTests/PluginTests.swift +++ b/Tests/FunctionalTests/PluginTests.swift @@ -706,10 +706,11 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let defaultToolchain = try await UserToolchain.default() + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: defaultToolchain), delegate: MockWorkspaceDelegate() ) @@ -804,10 +805,10 @@ final class PluginTests { let scriptRunner = DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: pluginDir.appending("cache"), - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ) - let toolSearchDirectories = [try UserToolchain.default.swiftCompilerPath.parentDirectory] + let toolSearchDirectories = [try await UserToolchain.default().swiftCompilerPath.parentDirectory] let success = try await withCheckedThrowingContinuation { continuation in plugin.invoke( action: .performCommand(package: package, arguments: arguments), @@ -907,10 +908,11 @@ final class PluginTests { try await fixture(name: "Miscellaneous/Plugins/MySourceGenPlugin") { packageDir in // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let defaultToolchain = try await UserToolchain.default() + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: defaultToolchain), delegate: MockWorkspaceDelegate() ) @@ -1006,10 +1008,11 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let defaultToolchain = try await UserToolchain.default() + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: defaultToolchain), delegate: MockWorkspaceDelegate() ) @@ -1098,7 +1101,7 @@ final class PluginTests { let scriptRunner = DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: pluginDir.appending("cache"), - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ) let delegate = PluginDelegate(delegateQueue: delegateQueue) // Use a task with timeout to test cancellation @@ -1110,13 +1113,13 @@ final class PluginTests { scriptRunner: scriptRunner, workingDirectory: package.path, outputDirectory: pluginDir.appending("output"), - toolSearchDirectories: [try UserToolchain.default.swiftCompilerPath.parentDirectory], + toolSearchDirectories: [try await UserToolchain.default().swiftCompilerPath.parentDirectory], accessibleTools: [:], writableDirectories: [pluginDir.appending("output")], readOnlyDirectories: [package.path], allowNetworkConnections: [], pkgConfigDirectories: [], - sdkRootPath: try UserToolchain.default.sdkRootPath, + sdkRootPath: try await UserToolchain.default().sdkRootPath, fileSystem: localFileSystem, modulesGraph: packageGraph, observabilityScope: observability.topScope, @@ -1327,10 +1330,10 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, location: .init(forRootPackage: packageDir, fileSystem: localFileSystem), - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) @@ -1412,7 +1415,7 @@ final class PluginTests { ).stdout.split(whereSeparator: \.isNewline) for snippet in snippets { - try expectFileExists( + try await expectFileExists( at: fixturePath.appending(components: data.buildSystem.binPath(for: data.config) + ["\(snippet)"]) ) } diff --git a/Tests/FunctionalTests/ToolsVersionTests.swift b/Tests/FunctionalTests/ToolsVersionTests.swift index 7adb72851b5..109bb0b3a52 100644 --- a/Tests/FunctionalTests/ToolsVersionTests.swift +++ b/Tests/FunctionalTests/ToolsVersionTests.swift @@ -124,7 +124,7 @@ struct ToolsVersionTests { configuration: configuration, buildSystem: buildSystem, ) - let binPath = try primaryPath.appending(components: buildSystem.binPath(for: configuration)) + let binPath = try await primaryPath.appending(components: buildSystem.binPath(for: configuration)) let exe: String = binPath.appending(components: "Primary").pathString // v1 should get selected because v1.0.1 depends on a (way) higher set of tools. let executableActualOutput = try await AsyncProcess.checkNonZeroExit(args: exe).spm_chomp() diff --git a/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift b/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift index b6f46beab36..04c2bdd2e47 100644 --- a/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift +++ b/Tests/PackageLoadingTests/ManifestLoaderCacheTests.swift @@ -44,7 +44,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), useInMemoryCache: false, cacheDir: path, delegate: delegate @@ -96,7 +96,7 @@ final class ManifestLoaderCacheTests: XCTestCase { } let noCacheLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), useInMemoryCache: false, cacheDir: .none, delegate: delegate @@ -137,7 +137,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), useInMemoryCache: true, cacheDir: .none, delegate: delegate @@ -189,7 +189,7 @@ final class ManifestLoaderCacheTests: XCTestCase { } let noCacheLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), useInMemoryCache: false, cacheDir: .none, delegate: delegate @@ -217,7 +217,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), cacheDir: path, delegate: delegate ) @@ -298,7 +298,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let loader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), cacheDir: path, extraManifestFlags: extraManifestFlags, delegate: delegate @@ -346,7 +346,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), cacheDir: path, delegate: delegate ) @@ -411,7 +411,7 @@ final class ManifestLoaderCacheTests: XCTestCase { let delegate = ManifestTestDelegate() let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), cacheDir: path, delegate: delegate ) @@ -484,7 +484,7 @@ final class ManifestLoaderCacheTests: XCTestCase { """ let manifestLoader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), cacheDir: .none, delegate: .none ) diff --git a/Tests/PackageLoadingTests/PDLoadingTests.swift b/Tests/PackageLoadingTests/PDLoadingTests.swift index 0ceab38b4e0..10b2a09ad26 100644 --- a/Tests/PackageLoadingTests/PDLoadingTests.swift +++ b/Tests/PackageLoadingTests/PDLoadingTests.swift @@ -17,7 +17,17 @@ import _InternalTestSupport import XCTest class PackageDescriptionLoadingTests: XCTestCase, ManifestLoaderDelegate { - lazy var manifestLoader = ManifestLoader(toolchain: try! UserToolchain.default, delegate: self) + private var _manifestLoader: ManifestLoader? + + func manifestLoader() async throws -> ManifestLoader { + if let loader = _manifestLoader { + return loader + } + let loader = ManifestLoader(toolchain: try await UserToolchain.default(), delegate: self) + _manifestLoader = loader + return loader + } + var parsedManifest = ThreadSafeBox() func willLoad(packageIdentity: PackageModel.PackageIdentity, packageLocation: String, manifestPath: AbsolutePath) { @@ -65,11 +75,17 @@ class PackageDescriptionLoadingTests: XCTestCase, ManifestLoaderDelegate { file: StaticString = #file, line: UInt = #line ) async throws -> (manifest: Manifest, diagnostics: [Basics.Diagnostic]) { - try await Self.loadAndValidateManifest( + let loader: ManifestLoader + if let customManifestLoader = customManifestLoader { + loader = customManifestLoader + } else { + loader = try await self.manifestLoader() + } + return try await Self.loadAndValidateManifest( content, toolsVersion: toolsVersion ?? self.toolsVersion, packageKind: packageKind ?? .fileSystem(.root), - manifestLoader: customManifestLoader ?? self.manifestLoader, + manifestLoader: loader, observabilityScope: observabilityScope, file: file, line: line diff --git a/Tests/PackageLoadingTests/PD_4_0_LoadingTests.swift b/Tests/PackageLoadingTests/PD_4_0_LoadingTests.swift index b3a50c22c7c..9fc674efe4d 100644 --- a/Tests/PackageLoadingTests/PD_4_0_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_4_0_LoadingTests.swift @@ -353,7 +353,7 @@ final class PackageDescription4_0LoadingTests: PackageDescriptionLoadingTests { try fs.writeFileContents(manifestPath, string: content) let observability = ObservabilitySystem.makeForTesting() - let manifest = try await manifestLoader.load( + let manifest = try await (try await manifestLoader()).load( manifestPath: manifestPath, packageKind: .root(.root), toolsVersion: .v4, diff --git a/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift b/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift index 1059a81d4a3..f0007c9d53c 100644 --- a/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_4_2_LoadingTests.swift @@ -403,7 +403,7 @@ final class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { ) } // Check we can load the repository. - let manifest = try await manifestLoader.load( + let manifest = try await (try await manifestLoader()).load( packagePath: root, packageKind: .root(.root), currentToolsVersion: .v4_2, @@ -432,7 +432,7 @@ final class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { string: manifestContents ) // Check we can load the manifest. - let manifest = try await manifestLoader.load(packagePath: packageDir, packageKind: .root(packageDir), currentToolsVersion: .v4_2, fileSystem: fs, observabilityScope: observability.topScope) + let manifest = try await (try await manifestLoader()).load(packagePath: packageDir, packageKind: .root(packageDir), currentToolsVersion: .v4_2, fileSystem: fs, observabilityScope: observability.topScope) XCTAssertNoDiagnostics(observability.diagnostics) XCTAssertEqual(manifest.displayName, "Trivial") @@ -446,7 +446,7 @@ final class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { string: "// swift-tools-version:4.0\n" + manifestContents ) // Check we can load the manifest. - let manifest2 = try await manifestLoader.load(packagePath: packageDir, packageKind: .root(packageDir), currentToolsVersion: .v4_2, fileSystem: fs, observabilityScope: observability.topScope) + let manifest2 = try await (try await manifestLoader()).load(packagePath: packageDir, packageKind: .root(packageDir), currentToolsVersion: .v4_2, fileSystem: fs, observabilityScope: observability.topScope) XCTAssertNoDiagnostics(observability.diagnostics) XCTAssertEqual(manifest2.displayName, "Trivial") } @@ -622,7 +622,7 @@ final class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { let observability = ObservabilitySystem.makeForTesting() let delegate = ManifestTestDelegate() - let manifestLoader = ManifestLoader(toolchain: try UserToolchain.default, cacheDir: path, delegate: delegate) + let manifestLoader = ManifestLoader(toolchain: try await UserToolchain.default(), cacheDir: path, delegate: delegate) let identityResolver = DefaultIdentityResolver() let dependencyMapper = DefaultDependencyMapper(identityResolver: identityResolver) @@ -682,7 +682,7 @@ final class PackageDescription4_2LoadingTests: PackageDescriptionLoadingTests { let total = 100 let observability = ObservabilitySystem.makeForTesting() let delegate = ManifestTestDelegate() - let manifestLoader = ManifestLoader(toolchain: try UserToolchain.default, cacheDir: path, delegate: delegate) + let manifestLoader = ManifestLoader(toolchain: try await UserToolchain.default(), cacheDir: path, delegate: delegate) let identityResolver = DefaultIdentityResolver() let dependencyMapper = DefaultDependencyMapper(identityResolver: identityResolver) diff --git a/Tests/PackageLoadingTests/PD_5_0_LoadingTests.swift b/Tests/PackageLoadingTests/PD_5_0_LoadingTests.swift index 58746bfb776..b07e4295d23 100644 --- a/Tests/PackageLoadingTests/PD_5_0_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_5_0_LoadingTests.swift @@ -367,7 +367,7 @@ final class PackageDescription5_0LoadingTests: PackageDescriptionLoadingTests { let manifestPath = path.appending(components: "pkg", "Package.swift") let loader = ManifestLoader( - toolchain: try UserToolchain.default, + toolchain: try await UserToolchain.default(), serializedDiagnostics: true, cacheDir: path) @@ -612,7 +612,7 @@ final class PackageDescription5_0LoadingTests: PackageDescriptionLoadingTests { let moduleTraceFilePath = path.appending("swift-module-trace") var env = Environment.current env["SWIFT_LOADED_MODULE_TRACE_FILE"] = moduleTraceFilePath.pathString - let toolchain = try UserToolchain(swiftSDK: SwiftSDK.default, environment: env) + let toolchain = try await UserToolchain(swiftSDK: try await SwiftSDK.default(), environment: env) let manifestLoader = ManifestLoader( toolchain: toolchain, serializedDiagnostics: true, diff --git a/Tests/PackageLoadingTests/PD_5_7_LoadingTests.swift b/Tests/PackageLoadingTests/PD_5_7_LoadingTests.swift index 335c861263b..23caea34580 100644 --- a/Tests/PackageLoadingTests/PD_5_7_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_5_7_LoadingTests.swift @@ -180,7 +180,7 @@ final class PackageDescription5_7LoadingTests: PackageDescriptionLoadingTests { """ let observability = ObservabilitySystem.makeForTesting() - let manifestLoader = ManifestLoader(toolchain: try UserToolchain.default, importRestrictions: (.v5_7, [])) + let manifestLoader = ManifestLoader(toolchain: try await UserToolchain.default(), importRestrictions: (.v5_7, [])) await XCTAssertAsyncThrowsError(try await loadAndValidateManifest(content, customManifestLoader: manifestLoader, observabilityScope: observability.topScope)) { error in if case ManifestParseError.importsRestrictedModules(let modules) = error { XCTAssertEqual(modules.sorted(), ["BestModule", "Foundation"]) diff --git a/Tests/PackageLoadingTests/PD_6_0_LoadingTests.swift b/Tests/PackageLoadingTests/PD_6_0_LoadingTests.swift index 88cac5613c2..3ce28ca672c 100644 --- a/Tests/PackageLoadingTests/PD_6_0_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_6_0_LoadingTests.swift @@ -109,7 +109,7 @@ final class PackageDescription6_0LoadingTests: PackageDescriptionLoadingTests { try repo.commit(message: "best") try repo.tag(name: "lunch") - let manifest = try await manifestLoader.load( + let manifest = try await (try await manifestLoader()).load( manifestPath: manifestPath, packageKind: .root(tmpdir), toolsVersion: self.toolsVersion, diff --git a/Tests/PackageLoadingTests/PD_6_2_LoadingTests.swift b/Tests/PackageLoadingTests/PD_6_2_LoadingTests.swift index 19ddde7e991..438a8e4fc0e 100644 --- a/Tests/PackageLoadingTests/PD_6_2_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_6_2_LoadingTests.swift @@ -75,7 +75,7 @@ struct PackageDescription6_2LoadingTests { toolsVersion: .v6_2, packageKind: .fileSystem(.root), manifestLoader: ManifestLoader( - toolchain: try! UserToolchain.default + toolchain: try await UserToolchain.default() ), observabilityScope: observability.topScope ) diff --git a/Tests/PackageModelTests/SwiftSDKBundleTests.swift b/Tests/PackageModelTests/SwiftSDKBundleTests.swift index 8262336c8c3..83c3942624d 100644 --- a/Tests/PackageModelTests/SwiftSDKBundleTests.swift +++ b/Tests/PackageModelTests/SwiftSDKBundleTests.swift @@ -402,7 +402,7 @@ final class SwiftSDKBundleTests: XCTestCase { ] ) let system = ObservabilitySystem.makeForTesting() - let hostSwiftSDK = try SwiftSDK.hostSwiftSDK(environment: [:]) + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: [:]) let hostTriple = try! Triple("arm64-apple-macosx14.0") let hostToolchainBinDir = AbsolutePath("/tmp") let archiver = MockArchiver() @@ -419,7 +419,7 @@ final class SwiftSDKBundleTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, store: store, @@ -431,7 +431,7 @@ final class SwiftSDKBundleTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customCompileTriple: .arm64Linux, @@ -448,7 +448,7 @@ final class SwiftSDKBundleTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, swiftSDKSelector: "\(testArtifactID)1", @@ -463,7 +463,7 @@ final class SwiftSDKBundleTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, swiftSDKSelector: "\(testArtifactID)2", @@ -482,7 +482,7 @@ final class SwiftSDKBundleTests: XCTestCase { let customCompileToolchain = AbsolutePath("/path/to/toolchain") try fileSystem.createDirectory(customCompileToolchain, recursive: true) - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customCompileToolchain: customCompileToolchain, diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 999622ee993..911d8221a12 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -706,21 +706,22 @@ final class SwiftSDKTests: XCTestCase { ) } - func testDefaultSDKs() throws { - let hostSDK = try SwiftSDK.hostSwiftSDK("/prefix/bin") + func testDefaultSDKs() async throws { + let hostSDK = try await SwiftSDK.hostSwiftSDKAsync("/prefix/bin") #if os(macOS) let iOSPlatform = try AbsolutePath(validating: "/usr/share/iPhoneOS.platform") let iOSRoot = try AbsolutePath(validating: "/usr/share/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk") let iOSTriple = try Triple("arm64-apple-ios") - let iOS = try XCTUnwrap(SwiftSDK.defaultSwiftSDK( + let iOSSDK = await SwiftSDK.defaultSwiftSDK( for: iOSTriple, hostSDK: hostSDK, environment: [ "SWIFTPM_PLATFORM_PATH_iphoneos": iOSPlatform.pathString, "SWIFTPM_SDKROOT_iphoneos": iOSRoot.pathString, ] - )) + ) + let iOS = try XCTUnwrap(iOSSDK) XCTAssertEqual(iOS.toolset.rootPaths, hostSDK.toolset.rootPaths) XCTAssertEqual(iOS.pathsConfiguration.sdkRootPath, iOSRoot) diff --git a/Tests/PackageModelTests/ToolsetTests.swift b/Tests/PackageModelTests/ToolsetTests.swift index d0568e4127a..91948741254 100644 --- a/Tests/PackageModelTests/ToolsetTests.swift +++ b/Tests/PackageModelTests/ToolsetTests.swift @@ -209,14 +209,14 @@ final class ToolsetTests: XCTestCase { ) } - func testToolsetTargetToolchain() throws { + func testToolsetTargetToolchain() async throws { let fileSystem = InMemoryFileSystem() for testFile in [compilersNoRoot, noValidToolsNoRoot, unknownToolsNoRoot, otherToolsNoRoot, someToolsWithRoot, someToolsWithRelativeRoot] { try fileSystem.writeFileContents(testFile.path, string: testFile.json.underlying) } - let hostSwiftSDK = try SwiftSDK.hostSwiftSDK(environment: [:]) + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: [:]) let hostTriple = try! Triple("arm64-apple-macosx14.0") let observability = ObservabilitySystem.makeForTesting() @@ -229,7 +229,7 @@ final class ToolsetTests: XCTestCase { ) do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customToolsets: [compilersNoRoot.path], @@ -250,7 +250,7 @@ final class ToolsetTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customToolsets: [someToolsWithRoot.path], @@ -271,7 +271,7 @@ final class ToolsetTests: XCTestCase { } do { - let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customToolsets: [compilersNoRoot.path, someToolsWithRoot.path], diff --git a/Tests/SPMBuildCoreTests/BuildParametersTests.swift b/Tests/SPMBuildCoreTests/BuildParametersTests.swift index cf79703fe9b..d799e2136ad 100644 --- a/Tests/SPMBuildCoreTests/BuildParametersTests.swift +++ b/Tests/SPMBuildCoreTests/BuildParametersTests.swift @@ -18,8 +18,8 @@ import Testing struct BuildParametersTests { @Test - func configurationDependentProperties() throws { - var parameters = mockBuildParameters( + func configurationDependentProperties() async throws { + var parameters = try await mockBuildParameters( destination: .host, environment: BuildEnvironment(platform: .linux, configuration: .debug) ) diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index cb99502be38..10a36eb3a34 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -280,13 +280,13 @@ final class SourceKitLSPAPITests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let destinationBuildParameters = mockBuildParameters(destination: .target) + let destinationBuildParameters = try await mockBuildParameters(destination: .target) try await withTemporaryDirectory { tmpDir in let pluginConfiguration = PluginConfiguration( scriptRunner: DefaultPluginScriptRunner( fileSystem: fs, cacheDir: tmpDir.appending("cache"), - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ), workDirectory: tmpDir.appending("work"), disableSandbox: false @@ -295,7 +295,7 @@ final class SourceKitLSPAPITests: XCTestCase { let loaded = try await BuildDescription.load( destinationBuildParameters: destinationBuildParameters, - toolsBuildParameters: mockBuildParameters(destination: .host), + toolsBuildParameters: try await mockBuildParameters(destination: .host), packageGraph: graph, pluginConfiguration: pluginConfiguration, traitConfiguration: TraitConfiguration(), diff --git a/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift b/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift index 1b7e8d0fd4b..700c0bf7ba0 100644 --- a/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift +++ b/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift @@ -22,7 +22,7 @@ import _InternalTestSupport import Workspace extension PIFBuilderParameters { - fileprivate static func constructDefaultParametersForTesting(temporaryDirectory: Basics.AbsolutePath) throws -> Self { + fileprivate static func constructDefaultParametersForTesting(temporaryDirectory: Basics.AbsolutePath) async throws -> Self { self.init( isPackageAccessModifierSupported: true, enableTestability: false, @@ -33,7 +33,7 @@ extension PIFBuilderParameters { pluginScriptRunner: DefaultPluginScriptRunner( fileSystem: localFileSystem, cacheDir: temporaryDirectory.appending(component: "plugin-cache-dir"), - toolchain: try UserToolchain.default + toolchain: try await UserToolchain.default() ), disableSandbox: false, pluginWorkingDirectory: temporaryDirectory.appending(component: "plugin-working-dir"), @@ -45,10 +45,10 @@ extension PIFBuilderParameters { fileprivate func withGeneratedPIF(fromFixture fixtureName: String, do doIt: (SwiftBuildSupport.PIF.TopLevelObject, TestingObservability) async throws -> ()) async throws { try await fixture(name: fixtureName) { fixturePath in let observabilitySystem = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: fixturePath, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) let rootInput = PackageGraphRootInput(packages: [fixturePath], dependencies: []) @@ -58,12 +58,12 @@ fileprivate func withGeneratedPIF(fromFixture fixtureName: String, do doIt: (Swi ) let builder = PIFBuilder( graph: graph, - parameters: try PIFBuilderParameters.constructDefaultParametersForTesting(temporaryDirectory: fixturePath), + parameters: try await PIFBuilderParameters.constructDefaultParametersForTesting(temporaryDirectory: fixturePath), fileSystem: localFileSystem, observabilityScope: observabilitySystem.topScope ) let pif = try await builder.constructPIF( - buildParameters: mockBuildParameters(destination: .host) + buildParameters: try await mockBuildParameters(destination: .host) ) try await doIt(pif, observabilitySystem) } diff --git a/Tests/WorkspaceTests/InitTests.swift b/Tests/WorkspaceTests/InitTests.swift index c5a6cc61319..30337b2b690 100644 --- a/Tests/WorkspaceTests/InitTests.swift +++ b/Tests/WorkspaceTests/InitTests.swift @@ -90,7 +90,7 @@ final class InitTests: XCTestCase { path, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple let binPath = path.appending(components: ".build", triple.platformBuildPathComponent, "debug") #if os(Windows) XCTAssertFileExists(binPath.appending("Foo.exe")) @@ -175,7 +175,7 @@ final class InitTests: XCTestCase { path, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple XCTAssertFileExists(path.appending(components: ".build", triple.platformBuildPathComponent, "debug", "Modules", "Foo.swiftmodule")) } } @@ -214,7 +214,7 @@ final class InitTests: XCTestCase { path, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple XCTAssertFileExists(path.appending(components: ".build", triple.platformBuildPathComponent, "debug", "Modules", "Foo.swiftmodule")) #endif } @@ -254,7 +254,7 @@ final class InitTests: XCTestCase { path, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple XCTAssertFileExists(path.appending(components: ".build", triple.platformBuildPathComponent, "debug", "Modules", "Foo.swiftmodule")) #endif } @@ -291,7 +291,7 @@ final class InitTests: XCTestCase { path, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple XCTAssertFileExists(path.appending(components: ".build", triple.platformBuildPathComponent, "debug", "Modules", "Foo.swiftmodule")) #endif } @@ -453,7 +453,7 @@ final class InitTests: XCTestCase { packageRoot, buildSystem: .native, ) - let triple = try UserToolchain.default.targetTriple + let triple = try await UserToolchain.default().targetTriple XCTAssertFileExists(packageRoot.appending(components: ".build", triple.platformBuildPathComponent, "debug", "Modules", "some_package.swiftmodule")) } } diff --git a/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift b/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift index 3f956e0913a..3cc5824256e 100644 --- a/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift +++ b/Tests/WorkspaceTests/ManifestSourceGenerationTests.swift @@ -51,7 +51,7 @@ final class ManifestSourceGenerationTests: XCTestCase { // Write the original manifest file contents, and load it. let manifestPath = packageDir.appending(component: Manifest.filename) try fs.writeFileContents(manifestPath, string: manifestContents) - let manifestLoader = ManifestLoader(toolchain: try UserToolchain.default) + let manifestLoader = ManifestLoader(toolchain: try await UserToolchain.default()) let identityResolver = DefaultIdentityResolver() let dependencyMapper = DefaultDependencyMapper(identityResolver: identityResolver) let manifest = try await manifestLoader.load( diff --git a/Tests/WorkspaceTests/RegistryPackageContainerTests.swift b/Tests/WorkspaceTests/RegistryPackageContainerTests.swift index d7eb6a20461..b0180f59448 100644 --- a/Tests/WorkspaceTests/RegistryPackageContainerTests.swift +++ b/Tests/WorkspaceTests/RegistryPackageContainerTests.swift @@ -37,7 +37,7 @@ final class RegistryPackageContainerTests: XCTestCase { let packageVersion = Version("1.0.0") let packagePath = AbsolutePath.root - func createProvider(_ toolsVersion: ToolsVersion) throws -> PackageContainerProvider { + func createProvider(_ toolsVersion: ToolsVersion) async throws -> PackageContainerProvider { let registryClient = try makeRegistryClient( packageIdentity: packageIdentity, packageVersion: packageVersion, @@ -86,19 +86,19 @@ final class RegistryPackageContainerTests: XCTestCase { } ) - return try Workspace._init( + return try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: packagePath, fileSystem: fs), customToolsVersion: toolsVersion, - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRegistryClient: registryClient ) } do { - let provider = try createProvider(.v4) + let provider = try await createProvider(.v4) let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let versions = try await container.toolsVersionsAppropriateVersionsDescending() @@ -106,7 +106,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v4_2) + let provider = try await createProvider(.v4_2) let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let versions = try await container.toolsVersionsAppropriateVersionsDescending() @@ -114,7 +114,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_4) + let provider = try await createProvider(.v5_4) let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let versions = try await container.toolsVersionsAppropriateVersionsDescending() @@ -130,7 +130,7 @@ final class RegistryPackageContainerTests: XCTestCase { let packageVersion = Version("1.0.0") let packagePath = AbsolutePath.root - func createProvider(_ toolsVersion: ToolsVersion) throws -> PackageContainerProvider { + func createProvider(_ toolsVersion: ToolsVersion) async throws -> PackageContainerProvider { let registryClient = try makeRegistryClient( packageIdentity: packageIdentity, packageVersion: packageVersion, @@ -152,19 +152,19 @@ final class RegistryPackageContainerTests: XCTestCase { } ) - return try Workspace._init( + return try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: packagePath, fileSystem: fs), customToolsVersion: toolsVersion, - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRegistryClient: registryClient ) } do { - let provider = try createProvider(.v5_2) // the version of the alternate + let provider = try await createProvider(.v5_2) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let version = try await container.toolsVersion(for: packageVersion) @@ -174,7 +174,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_3) // the version of the alternate + let provider = try await createProvider(.v5_3) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let version = try await container.toolsVersion(for: packageVersion) @@ -184,7 +184,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_4) // the version of the alternate + let provider = try await createProvider(.v5_4) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let version = try await container.toolsVersion(for: packageVersion) @@ -194,7 +194,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_5) // the version of the alternate + let provider = try await createProvider(.v5_5) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let version = try await container.toolsVersion(for: packageVersion) @@ -204,7 +204,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_6) // the version of the alternate + let provider = try await createProvider(.v5_6) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) let version = try await container.toolsVersion(for: packageVersion) @@ -224,7 +224,7 @@ final class RegistryPackageContainerTests: XCTestCase { let v5_3_3 = ToolsVersion(string: "5.3.3")! - func createProvider(_ toolsVersion: ToolsVersion) throws -> PackageContainerProvider { + func createProvider(_ toolsVersion: ToolsVersion) async throws -> PackageContainerProvider { let supportedVersions = Set([ToolsVersion.v5, .v5_3, v5_3_3, .v5_4, .v5_5]) let registryClient = try makeRegistryClient( packageIdentity: packageIdentity, @@ -251,12 +251,12 @@ final class RegistryPackageContainerTests: XCTestCase { } ) - return try Workspace._init( + return try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: packagePath, fileSystem: fs), customToolsVersion: toolsVersion, - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(), customRegistryClient: registryClient ) @@ -292,7 +292,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_3) // the version of the alternate + let provider = try await createProvider(.v5_3) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) @@ -300,7 +300,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(v5_3_3) // the version of the alternate + let provider = try await createProvider(v5_3_3) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) @@ -308,7 +308,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_4) // the version of the alternate + let provider = try await createProvider(.v5_4) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) @@ -316,7 +316,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_5) // the version of the alternate + let provider = try await createProvider(.v5_5) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) @@ -324,7 +324,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5_6) // the version of the alternate + let provider = try await createProvider(.v5_6) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) @@ -332,7 +332,7 @@ final class RegistryPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(.v5) // the version of the alternate + let provider = try await createProvider(.v5) // the version of the alternate let ref = PackageReference.registry(identity: packageIdentity) let container = try await provider.getContainer(for: ref) as! RegistryPackageContainer let manifest = try await container.loadManifest(version: packageVersion) diff --git a/Tests/WorkspaceTests/SourceControlPackageContainerTests.swift b/Tests/WorkspaceTests/SourceControlPackageContainerTests.swift index e73fb132090..ad7ce6d6fc6 100644 --- a/Tests/WorkspaceTests/SourceControlPackageContainerTests.swift +++ b/Tests/WorkspaceTests/SourceControlPackageContainerTests.swift @@ -158,11 +158,11 @@ final class SourceControlPackageContainerTests: XCTestCase { delegate: MockRepositoryManagerDelegate() ) - let provider = try Workspace._init( + let provider = try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: repoPath, fileSystem: fs), - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRepositoryManager: repositoryManager ) @@ -217,20 +217,20 @@ final class SourceControlPackageContainerTests: XCTestCase { delegate: MockRepositoryManagerDelegate() ) - func createProvider(_ currentToolsVersion: ToolsVersion) throws -> PackageContainerProvider { - return try Workspace._init( + func createProvider(_ currentToolsVersion: ToolsVersion) async throws -> PackageContainerProvider { + return try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: repoPath, fileSystem: fs), customToolsVersion: currentToolsVersion, - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRepositoryManager: repositoryManager ) } do { - let provider = try createProvider(ToolsVersion(version: "4.0.0")) + let provider = try await createProvider(ToolsVersion(version: "4.0.0")) let ref = PackageReference.localSourceControl(identity: PackageIdentity(path: repoPath), path: repoPath) let container = try await provider.getContainer(for: ref) let v = try await container.toolsVersionsAppropriateVersionsDescending() @@ -238,7 +238,7 @@ final class SourceControlPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(ToolsVersion(version: "4.2.0")) + let provider = try await createProvider(ToolsVersion(version: "4.2.0")) let ref = PackageReference.localSourceControl(identity: PackageIdentity(path: repoPath), path: repoPath) let container = try await provider.getContainer(for: ref) as! SourceControlPackageContainer XCTAssertTrue(container.validToolsVersionsCache.isEmpty) @@ -251,7 +251,7 @@ final class SourceControlPackageContainerTests: XCTestCase { } do { - let provider = try createProvider(ToolsVersion(version: "3.0.0")) + let provider = try await createProvider(ToolsVersion(version: "3.0.0")) let ref = PackageReference.localSourceControl(identity: PackageIdentity(path: repoPath), path: repoPath) let container = try await provider.getContainer(for: ref) let v = try await container.toolsVersionsAppropriateVersionsDescending() @@ -260,7 +260,7 @@ final class SourceControlPackageContainerTests: XCTestCase { // Test that getting dependencies on a revision that has unsupported tools version is diagnosed properly. do { - let provider = try createProvider(ToolsVersion(version: "4.0.0")) + let provider = try await createProvider(ToolsVersion(version: "4.0.0")) let ref = PackageReference.localSourceControl(identity: PackageIdentity(path: repoPath), path: repoPath) let container = try await provider.getContainer(for: ref) as! SourceControlPackageContainer let revision = try container.getRevision(forTag: "1.0.0") @@ -309,11 +309,11 @@ final class SourceControlPackageContainerTests: XCTestCase { delegate: MockRepositoryManagerDelegate() ) - let provider = try Workspace._init( + let provider = try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: repoPath, fileSystem: fs), - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRepositoryManager: repositoryManager ) @@ -365,11 +365,11 @@ final class SourceControlPackageContainerTests: XCTestCase { delegate: MockRepositoryManagerDelegate() ) - let provider = try Workspace._init( + let provider = try await Workspace._init( fileSystem: fs, environment: .mockEnvironment, location: .init(forRootPackage: repoPath, fileSystem: fs), - customHostToolchain: .mockHostToolchain(fs), + customHostToolchain: await .mockHostToolchain(fs), customManifestLoader: MockManifestLoader(manifests: [:]), customRepositoryManager: repositoryManager ) @@ -551,7 +551,7 @@ final class SourceControlPackageContainerTests: XCTestCase { try TargetDescription(name: packageDir.basename, path: packageDir.pathString), ] ) - let containerProvider = try Workspace._init( + let containerProvider = try await Workspace._init( fileSystem: localFileSystem, environment: .current, location: .init(forRootPackage: packageDir, fileSystem: localFileSystem), @@ -604,7 +604,7 @@ final class SourceControlPackageContainerTests: XCTestCase { delegate: repositoryManagerDelegate ) - let containerProvider = try Workspace._init( + let containerProvider = try await Workspace._init( fileSystem: localFileSystem, environment: .current, location: .init(forRootPackage: packageDirectory, fileSystem: localFileSystem), @@ -716,7 +716,7 @@ final class SourceControlPackageContainerTests: XCTestCase { ), ] ) - let containerProvider = try Workspace._init( + let containerProvider = try await Workspace._init( fileSystem: localFileSystem, environment: .current, location: .init(forRootPackage: packageDirectory, fileSystem: localFileSystem), diff --git a/Tests/WorkspaceTests/WorkspaceTests.swift b/Tests/WorkspaceTests/WorkspaceTests.swift index eaca8c6e7e9..be1d2075a75 100644 --- a/Tests/WorkspaceTests/WorkspaceTests.swift +++ b/Tests/WorkspaceTests/WorkspaceTests.swift @@ -171,17 +171,17 @@ final class WorkspaceTests: XCTestCase { func testInterpreterFlags() async throws { let fs = localFileSystem - try testWithTemporaryDirectory { path in + try await testWithTemporaryDirectory { path in let foo = path.appending("foo") let packageManifest = foo.appending("Package.swift") - func createWorkspace(_ content: String) throws -> Workspace { + func createWorkspace(_ content: String) async throws -> Workspace { try fs.writeFileContents(packageManifest, string: content) - let manifestLoader = try ManifestLoader(toolchain: UserToolchain.default) + let manifestLoader = try ManifestLoader(toolchain: try await UserToolchain.default()) let sandbox = path.appending("ws") - return try Workspace( + return try await Workspace.create( fileSystem: fs, forRootPackage: sandbox, customManifestLoader: manifestLoader, @@ -190,7 +190,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:4.0 import PackageDescription @@ -204,7 +204,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:3.1 import PackageDescription @@ -218,7 +218,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:999.0 import PackageDescription @@ -237,7 +237,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:6.0 import PackageDescription @@ -251,7 +251,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:6.1 import PackageDescription @@ -266,7 +266,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:6.2 import PackageDescription @@ -281,7 +281,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:5.9.2 import PackageDescription @@ -296,7 +296,7 @@ final class WorkspaceTests: XCTestCase { do { // Invalid package manifest should still produce build settings. - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:5.9.2 import PackageDescription @@ -307,7 +307,7 @@ final class WorkspaceTests: XCTestCase { } do { - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:3.0 import PackageDescription @@ -326,7 +326,7 @@ final class WorkspaceTests: XCTestCase { do { // Invalid package manifest should still produce build settings. - let ws = try createWorkspace( + let ws = try await createWorkspace( """ // swift-tools-version:5.1 import PackageDescription @@ -358,10 +358,10 @@ final class WorkspaceTests: XCTestCase { ) """ ) - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: pkgDir, - customManifestLoader: ManifestLoader(toolchain: UserToolchain.default), + customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), delegate: MockWorkspaceDelegate() ) let rootInput = PackageGraphRootInput(packages: [pkgDir], dependencies: []) @@ -889,7 +889,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "a", at: .checkout(.version("1.0.0"))) result.check(dependency: "aa", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "a", at: .checkout(.version("1.0.0"))) result.check(dependency: "aa", at: .checkout(.version("1.0.0"))) } @@ -910,7 +910,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "a", at: .checkout(.version("1.0.1"))) result.check(dependency: "aa", at: .checkout(.version("2.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "a", at: .checkout(.version("1.0.1"))) result.check(dependency: "aa", at: .checkout(.version("2.0.0"))) } @@ -1913,7 +1913,7 @@ final class WorkspaceTests: XCTestCase { } // Drop a build artifact in data directory. - let ws = try workspace.getOrCreateWorkspace() + let ws = try await workspace.getOrCreateWorkspace() let buildArtifact = ws.location.scratchDirectory.appending("test.o") try fs.writeFileContents(buildArtifact, bytes: "Hi") @@ -1922,7 +1922,7 @@ final class WorkspaceTests: XCTestCase { XCTAssert(fs.exists(ws.location.repositoriesCheckoutsDirectory)) // Check clean. - workspace.checkClean { diagnostics in + await workspace.checkClean { diagnostics in // Only the build artifact should be removed. XCTAssertFalse(fs.exists(buildArtifact)) XCTAssert(fs.exists(ws.location.repositoriesCheckoutsDirectory)) @@ -2207,7 +2207,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.2.3"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.2.3"))) } @@ -2218,7 +2218,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } @@ -2231,7 +2231,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } } @@ -2269,7 +2269,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertNoDiagnostics(diagnostics) } - try fs.removeFileTree(workspace.getOrCreateWorkspace().location.repositoriesCheckoutsDirectory) + try fs.removeFileTree(await workspace.getOrCreateWorkspace().location.repositoriesCheckoutsDirectory) try await workspace.checkPackageGraph(roots: ["Root"]) { graph, diagnostics in PackageGraphTesterXCTest(graph) { result in @@ -2457,7 +2457,7 @@ final class WorkspaceTests: XCTestCase { } // Edit foo. - let fooPath = try workspace.getOrCreateWorkspace().location.editsDirectory.appending("foo") + let fooPath = try await workspace.getOrCreateWorkspace().location.editsDirectory.appending("foo") await workspace.checkEdit(packageIdentity: "foo") { diagnostics in XCTAssertNoDiagnostics(diagnostics) } @@ -2611,7 +2611,7 @@ final class WorkspaceTests: XCTestCase { try await workspace.checkPackageGraph(roots: ["Root"]) { _, _ in } // Edit foo. - let fooPath = try workspace.getOrCreateWorkspace().location.editsDirectory.appending("Foo") + let fooPath = try await workspace.getOrCreateWorkspace().location.editsDirectory.appending("Foo") await workspace.checkEdit(packageIdentity: "Foo") { diagnostics in XCTAssertNoDiagnostics(diagnostics) } @@ -2662,7 +2662,7 @@ final class WorkspaceTests: XCTestCase { let deps: [MockDependency] = [ .sourceControl(path: "./Foo", requirement: .upToNextMajor(from: "1.0.0"), products: .specific(["Foo"])), ] - let ws = try workspace.getOrCreateWorkspace() + let ws = try await workspace.getOrCreateWorkspace() // Load the graph and edit foo. try await workspace.checkPackageGraph(deps: deps) { graph, diagnostics in @@ -2779,7 +2779,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .edited(nil)) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } @@ -2800,7 +2800,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.2.0"))) result.check(dependency: "bar", at: .edited(nil)) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.2.0"))) result.check(notPresent: "bar") } @@ -2813,7 +2813,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(dependency: "bar", at: .edited(nil)) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(notPresent: "bar") } @@ -2826,7 +2826,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } @@ -3060,7 +3060,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .edited(nil)) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } @@ -3183,7 +3183,7 @@ final class WorkspaceTests: XCTestCase { } } - let underlying = try workspace.getOrCreateWorkspace() + let underlying = try await workspace.getOrCreateWorkspace() let fooEditPath = sandbox.appending(components: ["edited", "foo"]) // mimic external process putting a dependency into edit mode @@ -3857,7 +3857,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } do { - let ws = try workspace.getOrCreateWorkspace() + let ws = try await workspace.getOrCreateWorkspace() let locationString = await ws.state.dependencies[.plain("foo")]?.packageRef.locationString XCTAssertEqual(locationString, "https://scm.com/org/foo") } @@ -3872,7 +3872,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.1.0"))) } do { - let ws = try workspace.getOrCreateWorkspace() + let ws = try await workspace.getOrCreateWorkspace() let locationString = await ws.state.dependencies[.plain("foo")]?.packageRef.locationString XCTAssertEqual(locationString, "https://scm.com/other/foo") } @@ -3918,7 +3918,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } @@ -3928,7 +3928,7 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(notPresent: "foo") } } @@ -3990,13 +3990,13 @@ final class WorkspaceTests: XCTestCase { await workspace.checkManagedDependencies { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) } let minToolsVersion = [pair.0, pair.1].min()! let expectedSchemeVersion = minToolsVersion >= .v5_6 ? 2 : 1 - let actualSchemeVersion = try workspace.getOrCreateWorkspace().resolvedPackagesStore.load().schemeVersion() + let actualSchemeVersion = try await workspace.getOrCreateWorkspace().resolvedPackagesStore.load().schemeVersion() XCTAssertEqual( actualSchemeVersion, expectedSchemeVersion, @@ -4107,7 +4107,7 @@ final class WorkspaceTests: XCTestCase { "https://localhost/org/bar" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) XCTAssertEqual( @@ -4148,7 +4148,7 @@ final class WorkspaceTests: XCTestCase { "https://localhost/org/bar.git" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) // URLs should be stable since URLs are canonically the same and we kept the resolved file between the two @@ -4190,7 +4190,7 @@ final class WorkspaceTests: XCTestCase { "https://localhost/org/bar.git" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.1.0"))) result.check(dependency: "bar", at: .checkout(.version("1.1.0"))) // URLs should reflect the actual dependencies since the new version forces rewrite of the resolved file @@ -4232,7 +4232,7 @@ final class WorkspaceTests: XCTestCase { "https://localhost/org/bar.git" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) // URLs should reflect the actual dependencies since we deleted the resolved file @@ -4330,12 +4330,12 @@ final class WorkspaceTests: XCTestCase { } } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.3.1"))) result.check(dependency: "bar", at: .checkout(.version("1.1.1"))) } - let resolvedPackagesStore = try workspace.getOrCreateWorkspace().resolvedPackagesStore.load() + let resolvedPackagesStore = try await workspace.getOrCreateWorkspace().resolvedPackagesStore.load() checkPinnedVersion(pin: resolvedPackagesStore.resolvedPackages["foo"]!, version: "1.3.1") checkPinnedVersion(pin: resolvedPackagesStore.resolvedPackages["bar"]!, version: "1.1.1") } @@ -5160,7 +5160,7 @@ final class WorkspaceTests: XCTestCase { "https://scm.com/org/foo" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) XCTAssertEqual( @@ -5190,7 +5190,7 @@ final class WorkspaceTests: XCTestCase { "https://scm.com/other/foo" ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.1.0"))) XCTAssertEqual( @@ -5255,14 +5255,14 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(dependency: "bar", at: .checkout(.branch("develop"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.3.2"))) result.check(dependency: "bar", at: .checkout(.branch("develop"))) } // Change pin of foo to something else. do { - let ws = try workspace.getOrCreateWorkspace() + let ws = try await workspace.getOrCreateWorkspace() let resolvedPackagesStore = try ws.resolvedPackagesStore.load() let fooPin = try XCTUnwrap( resolvedPackagesStore.resolvedPackages.values @@ -5294,7 +5294,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.branch("develop"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.branch("develop"))) } @@ -5307,7 +5307,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } @@ -5320,7 +5320,7 @@ final class WorkspaceTests: XCTestCase { result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } - workspace.checkResolved { result in + await workspace.checkResolved { result in result.check(dependency: "foo", at: .checkout(.version("1.0.0"))) result.check(dependency: "bar", at: .checkout(.version("1.0.0"))) } @@ -5533,9 +5533,9 @@ final class WorkspaceTests: XCTestCase { // Load the workspace. let observability = ObservabilitySystem.makeForTesting() - let workspace = try Workspace( + let workspace = try await Workspace.create( forRootPackage: packagePath, - customHostToolchain: UserToolchain.default + customHostToolchain: try await UserToolchain.default() ) // From here the API should be simple and straightforward: @@ -5978,7 +5978,7 @@ final class WorkspaceTests: XCTestCase { } // Edit foo. - let fooPath = try workspace.getOrCreateWorkspace().location.editsDirectory.appending("Foo") + let fooPath = try await workspace.getOrCreateWorkspace().location.editsDirectory.appending("Foo") await workspace.checkEdit(packageIdentity: "Foo") { diagnostics in XCTAssertNoDiagnostics(diagnostics) } @@ -8098,7 +8098,7 @@ final class WorkspaceTests: XCTestCase { let binaryArtifactsManager = try Workspace.BinaryArtifactsManager( fileSystem: fs, authorizationProvider: .none, - hostToolchain: UserToolchain.mockHostToolchain(fs), + hostToolchain: try await UserToolchain.mockHostToolchain(fs), checksumAlgorithm: checksumAlgorithm, cachePath: .none, customHTTPClient: .none, @@ -9291,7 +9291,7 @@ final class WorkspaceTests: XCTestCase { ) let observability = ObservabilitySystem.makeForTesting() - let wks = try workspace.getOrCreateWorkspace() + let wks = try await workspace.getOrCreateWorkspace() _ = try await wks.loadRootPackage( at: workspace.rootsDir.appending("Root"), observabilityScope: observability.topScope @@ -9304,7 +9304,7 @@ final class WorkspaceTests: XCTestCase { let fs = InMemoryFileSystem() try fs.createMockToolchain() let downloads = ThreadSafeKeyValueStore() - let hostToolchain = try UserToolchain.mockHostToolchain(fs) + let hostToolchain = try await UserToolchain.mockHostToolchain(fs) let ariFiles = [ """ @@ -9587,7 +9587,7 @@ final class WorkspaceTests: XCTestCase { let sandbox = AbsolutePath("/tmp/ws/") let fs = InMemoryFileSystem() try fs.createMockToolchain() - let hostToolchain = try UserToolchain.mockHostToolchain(fs) + let hostToolchain = try await UserToolchain.mockHostToolchain(fs) let ari = """ { @@ -9703,7 +9703,7 @@ final class WorkspaceTests: XCTestCase { let sandbox = AbsolutePath("/tmp/ws/") let fs = InMemoryFileSystem() try fs.createMockToolchain() - let hostToolchain = try UserToolchain.mockHostToolchain(fs) + let hostToolchain = try await UserToolchain.mockHostToolchain(fs) let ari = """ { @@ -9810,7 +9810,7 @@ final class WorkspaceTests: XCTestCase { let sandbox = AbsolutePath("/tmp/ws/") let fs = InMemoryFileSystem() try fs.createMockToolchain() - let hostToolchain = try UserToolchain.mockHostToolchain(fs) + let hostToolchain = try await UserToolchain.mockHostToolchain(fs) let ari = """ { @@ -9884,7 +9884,7 @@ final class WorkspaceTests: XCTestCase { try fs.createMockToolchain() - let hostToolchain = try UserToolchain.mockHostToolchain(fs) + let hostToolchain = try await UserToolchain.mockHostToolchain(fs) let androidTriple = try Triple("x86_64-unknown-linux-android") let macTriple = try Triple("arm64-apple-macosx") let notHostTriple = hostToolchain.targetTriple == androidTriple ? macTriple : androidTriple @@ -11913,7 +11913,7 @@ final class WorkspaceTests: XCTestCase { ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "https://github.com/org/foo.git" @@ -12052,7 +12052,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(result.managedDependencies["foo"]?.packageRef.locationString, "git@github.com:org/foo.git") } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "git@github.com:org/foo.git" @@ -12185,7 +12185,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(result.managedDependencies["foo"]?.packageRef.locationString, "git@github.com:org/foo.git") } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "git@github.com:org/foo.git" @@ -12214,7 +12214,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(result.managedDependencies["foo"]?.packageRef.locationString, "git@github.com:org/foo.git") } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "https://github.com/org/foo" @@ -12305,7 +12305,7 @@ final class WorkspaceTests: XCTestCase { ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "https://github.com/org/foo.git" @@ -12327,7 +12327,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(result.managedDependencies["foo"]?.packageRef.locationString, "git@github.com:org/foo.git") } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "git@github.com:org/foo.git" @@ -12465,7 +12465,7 @@ final class WorkspaceTests: XCTestCase { ) } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "https://github.com/org/foo.git" @@ -12493,7 +12493,7 @@ final class WorkspaceTests: XCTestCase { XCTAssertEqual(result.managedDependencies["foo"]?.packageRef.locationString, "git@github.com:org/foo.git") } - workspace.checkResolved { result in + await workspace.checkResolved { result in XCTAssertEqual( result.store.resolvedPackages["foo"]?.packageRef.locationString, "git@github.com:org/foo.git" @@ -12708,9 +12708,9 @@ final class WorkspaceTests: XCTestCase { """ ) - let manifestLoader = try ManifestLoader(toolchain: UserToolchain.default) + let manifestLoader = try ManifestLoader(toolchain: try await UserToolchain.default()) let sandbox = path.appending("ws") - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: fs, forRootPackage: sandbox, customManifestLoader: manifestLoader, @@ -12779,12 +12779,12 @@ final class WorkspaceTests: XCTestCase { fileSystem: fs ) - let customHostToolchain = try UserToolchain.mockHostToolchain(fs) + let customHostToolchain = try await UserToolchain.mockHostToolchain(fs) do { // no error let delegate = MockWorkspaceDelegate() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: fs, environment: .mockEnvironment, forRootPackage: .root, @@ -12802,7 +12802,7 @@ final class WorkspaceTests: XCTestCase { do { // actual error let delegate = MockWorkspaceDelegate() - let workspace = try Workspace( + let workspace = try await Workspace.create( fileSystem: fs, environment: .mockEnvironment, forRootPackage: .root,