From 01419cedd119115bc3e2b5408700df55878d1109 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Fri, 10 Oct 2025 10:32:04 -0400 Subject: [PATCH 1/3] Add async versions of `UserToolchain.init` and `SwiftSDK.hostSwiftSDK` Both methods previously made calls to the version of `AsyncProcess.checkNonZeroExit` that blocks the calling thread, forcing consumers to either block or implement workarounds to hop off the calling thread. This patch adds async versions of these methods and ports most usages to use them, marking the required call sites as async and awaiting them. --- .../Sources/package-info/example.swift | 2 +- .../Commands/PackageCommands/APIDiff.swift | 17 +- .../PackageCommands/AddDependency.swift | 6 +- .../Commands/PackageCommands/AddProduct.swift | 6 +- .../Commands/PackageCommands/AddSetting.swift | 10 +- .../Commands/PackageCommands/AddTarget.swift | 2 +- .../PackageCommands/AddTargetDependency.swift | 6 +- .../PackageCommands/AuditBinaryArtifact.swift | 2 +- Sources/Commands/PackageCommands/Config.swift | 22 +- .../Commands/PackageCommands/Describe.swift | 2 +- .../PackageCommands/DumpCommands.swift | 12 +- .../PackageCommands/EditCommands.swift | 4 +- Sources/Commands/PackageCommands/Format.swift | 2 +- Sources/Commands/PackageCommands/Init.swift | 20 +- .../Commands/PackageCommands/Install.swift | 4 +- .../Commands/PackageCommands/Migrate.swift | 16 +- .../PackageCommands/PluginCommand.swift | 8 +- .../PackageCommands/ResetCommands.swift | 6 +- .../Commands/PackageCommands/Resolve.swift | 2 +- .../PackageCommands/ToolsVersionCommand.swift | 4 +- Sources/Commands/PackageCommands/Update.swift | 2 +- .../Commands/Snippets/Cards/SnippetCard.swift | 2 +- Sources/Commands/SwiftBuildCommand.swift | 6 +- Sources/Commands/SwiftRunCommand.swift | 20 +- Sources/Commands/SwiftTestCommand.swift | 78 +++--- Sources/Commands/Utilities/APIDigester.swift | 2 +- .../Commands/Utilities/PluginDelegate.swift | 16 +- .../Commands/Utilities/TestingSupport.swift | 63 ++--- Sources/CoreCommands/BuildSystemSupport.swift | 44 ++- Sources/CoreCommands/Options.swift | 12 +- Sources/CoreCommands/SwiftCommandState.swift | 260 +++++++++--------- .../PackageCollectionsCommand.swift | 2 +- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 125 +++++---- Sources/PackageModel/UserToolchain.swift | 39 +-- .../PackageRegistryCommand+Auth.swift | 4 +- .../PackageRegistryCommand+Publish.swift | 2 +- .../PackageRegistryCommand.swift | 8 +- .../SwiftSDKCommand/ConfigureSwiftSDK.swift | 3 +- .../SwiftSDKCommand/SwiftSDKSubcommand.swift | 7 +- Sources/Workspace/Workspace.swift | 37 +-- .../MockBuildTestHelper.swift | 10 +- .../BuildSystemProvider+Configuration.swift | 4 +- .../MockBuildTestHelper.swift | 27 +- .../_InternalTestSupport/MockWorkspace.swift | 60 ++-- .../SwiftTesting+TraitConditional.swift | 18 +- Sources/_InternalTestSupport/Toolchain.swift | 14 +- Sources/swift-bootstrap/main.swift | 6 +- .../BuildPrebuilts.swift | 20 +- Tests/BuildTests/BuildOperationTests.swift | 21 +- Tests/BuildTests/BuildPlanTests.swift | 175 ++++++------ .../BuildTests/BuildSystemDelegateTests.swift | 2 +- .../ClangTargetBuildDescriptionTests.swift | 41 +-- Tests/BuildTests/IncrementalBuildTests.swift | 14 +- Tests/BuildTests/PluginInvocationTests.swift | 93 ++++--- Tests/BuildTests/PluginsBuildPlanTests.swift | 20 +- Tests/BuildTests/PrepareForIndexTests.swift | 8 +- .../ProductBuildDescriptionTests.swift | 4 +- Tests/CommandsTests/APIDiffTests.swift | 2 +- Tests/CommandsTests/BuildCommandTests.swift | 20 +- Tests/CommandsTests/PackageCommandTests.swift | 38 +-- .../SwiftCommandStateTests.swift | 26 +- Tests/CommandsTests/TestCommandTests.swift | 2 +- .../FunctionalTests/CFamilyTargetTests.swift | 12 +- .../DependencyResolutionTests.swift | 8 +- .../FunctionalTests/MiscellaneousTests.swift | 17 +- .../ModuleAliasingFixtureTests.swift | 8 +- Tests/FunctionalTests/ModuleMapTests.swift | 6 +- Tests/FunctionalTests/PluginTests.swift | 31 ++- Tests/FunctionalTests/ToolsVersionTests.swift | 2 +- .../ManifestLoaderCacheTests.swift | 18 +- .../PackageLoadingTests/PDLoadingTests.swift | 22 +- .../PD_4_0_LoadingTests.swift | 2 +- .../PD_4_2_LoadingTests.swift | 10 +- .../PD_5_0_LoadingTests.swift | 4 +- .../PD_5_7_LoadingTests.swift | 2 +- .../PD_6_0_LoadingTests.swift | 2 +- .../PD_6_2_LoadingTests.swift | 2 +- .../SwiftSDKBundleTests.swift | 12 +- Tests/PackageModelTests/SwiftSDKTests.swift | 9 +- Tests/PackageModelTests/ToolsetTests.swift | 10 +- .../BuildParametersTests.swift | 4 +- .../SourceKitLSPAPITests.swift | 6 +- .../PIFBuilderTests.swift | 12 +- Tests/WorkspaceTests/InitTests.swift | 12 +- .../ManifestSourceGenerationTests.swift | 2 +- .../RegistryPackageContainerTests.swift | 46 ++-- .../SourceControlPackageContainerTests.swift | 32 +-- Tests/WorkspaceTests/WorkspaceTests.swift | 150 +++++----- 88 files changed, 1037 insertions(+), 914 deletions(-) diff --git a/Examples/package-info/Sources/package-info/example.swift b/Examples/package-info/Sources/package-info/example.swift index 579a5331e25..02f3484cb22 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(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..9193699a2c0 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( 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..94edf4899e0 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( 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..2dcaa916f2e 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( 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.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 + ) + + // Check if we ended up with the host toolchain. + if hostSwiftSDK == swiftSDK { + return hostToolchain + } + + return try await UserToolchain(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.hostSwiftSDK( + environment: self.environment, + observabilityScope: self.observabilityScope + ) + hostSwiftSDK.targetTriple = self.hostTriple + + return try await UserToolchain( + 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..f4c12bc1f58 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -525,8 +525,8 @@ public struct SwiftSDK: Equatable { _ binDir: Basics.AbsolutePath? = nil, originalWorkingDirectory: Basics.AbsolutePath? = nil, environment: Environment - ) throws -> SwiftSDK { - try self.hostSwiftSDK(binDir, environment: environment) + ) async throws -> SwiftSDK { + try await self.hostSwiftSDK(binDir, environment: environment) } /// The Swift SDK for the host platform. @@ -535,8 +535,8 @@ public struct SwiftSDK: Equatable { environment: Environment = .current, observabilityScope: ObservabilityScope? = nil, fileSystem: any FileSystem = Basics.localFileSystem - ) throws -> SwiftSDK { - try self.systemSwiftSDK( + ) async throws -> SwiftSDK { + try await self.systemSwiftSDK( binDir, environment: environment, observabilityScope: observabilityScope, @@ -544,6 +544,7 @@ public struct SwiftSDK: Equatable { ) } + /// A default Swift SDK on the host. /// /// Equivalent to `hostSwiftSDK`, except on macOS, where passing a non-nil `darwinPlatformOverride` @@ -554,56 +555,79 @@ public struct SwiftSDK: Equatable { observabilityScope: ObservabilityScope? = nil, 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) - - let sdkPath: Basics.AbsolutePath? + ) 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 (async version). + private static func getSDKPath( + for darwinPlatform: DarwinPlatform, + environment: Environment + ) async 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( + 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") } - sdkPath = try AbsolutePath(validating: sdkPathStr) + return try AbsolutePath(validating: sdkPathStr) } - #else - sdkPath = nil - #endif + } + + /// 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 +663,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") } @@ -654,16 +678,19 @@ public struct SwiftSDK: Equatable { public static func sdkPlatformPaths( for darwinPlatform: DarwinPlatform, environment: Environment = .current - ) throws -> PlatformPaths { + ) async throws -> PlatformPaths { 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 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") @@ -690,22 +717,16 @@ public struct SwiftSDK: Equatable { /// Cache storage for sdk platform paths. private static var _sdkPlatformFrameworkPath: [DarwinPlatform: PlatformPaths] = [:] - /// 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) - } - - /// Returns a default Swift SDK of a given target environment. + /// 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 @@ -732,7 +753,7 @@ public struct SwiftSDK: Equatable { store: SwiftSDKBundleStore, observabilityScope: ObservabilityScope, fileSystem: FileSystem - ) throws -> SwiftSDK { + ) async throws -> SwiftSDK { var swiftSDK: SwiftSDK var isBasedOnHostSDK: Bool = false @@ -755,7 +776,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 +786,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..25251404659 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? = { @@ -179,11 +175,11 @@ public final class UserToolchain: Toolchain { return try getTool(name, binDirectories: envSearchPaths, fileSystem: fileSystem) } - private static func getTargetInfo(swiftCompiler: AbsolutePath) throws -> JSON { + 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 AsyncProcess.popen(args: swiftCompiler.pathString, "-print-target-info") + let result = try await AsyncProcess.popen(args: swiftCompiler.pathString, "-print-target-info") compilerOutput = try result.utf8Output().spm_chomp() } catch { throw InternalError( @@ -670,22 +666,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, @@ -694,7 +674,7 @@ public final class UserToolchain: Toolchain { customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil, customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil, fileSystem: any FileSystem = localFileSystem - ) throws { + ) async throws { self.swiftSDK = swiftSDK self.environment = environment @@ -735,12 +715,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 await Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) + } + self.targetInfo = targetInfo triple = try swiftSDK.targetTriple ?? Self.getHostTriple(targetInfo: targetInfo, versioned: false) } 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..ac9fbe4e4b1 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.hostSwiftSDK() + let hostToolchain = try await UserToolchain(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..c5d571cbfd4 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.hostSwiftSDK(environment: environment) + let hostToolchain = try await UserToolchain( + 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..8daa085bc7c 100644 --- a/Sources/Workspace/Workspace.swift +++ b/Sources/Workspace/Workspace.swift @@ -206,8 +206,8 @@ public class Workspace { customRepositoryProvider: (any RepositoryProvider)? = .none, // delegate delegate: Delegate? = .none - ) throws { - try self.init( + ) async throws { + try await self.init( fileSystem: fileSystem, environment: environment, location: location, @@ -272,10 +272,10 @@ public class Workspace { customRepositoryProvider: RepositoryProvider? = .none, // delegate delegate: Delegate? = .none - ) throws { + ) async throws { let fileSystem = fileSystem ?? localFileSystem let location = try Location(forRootPackage: packagePath, fileSystem: fileSystem) - try self.init( + try await self.init( fileSystem: fileSystem, environment: environment, location: location, @@ -326,7 +326,7 @@ public class Workspace { customRepositoryProvider: RepositoryProvider? = .none, // delegate delegate: Delegate? = .none - ) throws { + ) async throws { let fileSystem = fileSystem ?? localFileSystem let location = try Location(forRootPackage: packagePath, fileSystem: fileSystem) let manifestLoader = ManifestLoader( @@ -336,7 +336,7 @@ public class Workspace { delegate: delegate.map(WorkspaceManifestLoaderDelegate.init(workspaceDelegate:)), pruneDependencies: configuration?.pruneDependencies ?? false ) - try self.init( + try await self.init( fileSystem: fileSystem, location: location, authorizationProvider: authorizationProvider, @@ -385,8 +385,8 @@ public class Workspace { customChecksumAlgorithm: HashAlgorithm? = .none, // delegate delegate: Delegate? = .none - ) throws -> Workspace { - try .init( + ) async throws -> Workspace { + try await .init( fileSystem: fileSystem, environment: environment, location: location, @@ -446,7 +446,7 @@ public class Workspace { customChecksumAlgorithm: HashAlgorithm?, // delegate delegate: Delegate? - ) throws { + ) 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. @@ -459,13 +459,18 @@ public class Workspace { ) let currentToolsVersion = customToolsVersion ?? ToolsVersion.current - let hostToolchain = try customHostToolchain ?? UserToolchain( - swiftSDK: .hostSwiftSDK( - environment: environment - ), - environment: environment, - fileSystem: fileSystem - ) + let hostToolchain: UserToolchain + if let customHostToolchain { + hostToolchain = customHostToolchain + } else { + hostToolchain = try await UserToolchain( + swiftSDK: .hostSwiftSDK( + environment: environment + ), + environment: environment, + fileSystem: fileSystem + ) + } var manifestLoader = customManifestLoader ?? ManifestLoader( toolchain: hostToolchain, cacheDir: location.sharedManifestsCacheDirectory, 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..04a4c83622b 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.hostSwiftSDK(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( 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..bd298af075d 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.hostSwiftSDK(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..c7752a009e7 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,11 +224,11 @@ 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( + self.hostToolchain = try await UserToolchain( swiftSDK: SwiftSDK.hostSwiftSDK( environment: environment, fileSystem: fileSystem diff --git a/Sources/swift-build-prebuilts/BuildPrebuilts.swift b/Sources/swift-build-prebuilts/BuildPrebuilts.swift index 09e46bb518d..97208dcea8c 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.hostSwiftSDK( + environment: environment, + fileSystem: fileSystem + ) + let hostToolchain = try await UserToolchain( + 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(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..d90b6244ca6 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( 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( 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( 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( 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( 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..b2a8021babb 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( 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( 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( 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( 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( 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( 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( 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( 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..98704dbd2e6 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( + swiftSDK: try await SwiftSDK.hostSwiftSDK(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( + swiftSDK: try await SwiftSDK.hostSwiftSDK(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..664b6b85008 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( + swiftSDK: await .hostSwiftSDK(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( + swiftSDK: await .hostSwiftSDK(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( 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..11195738cc2 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( 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( 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( 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( 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..791766aae74 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.hostSwiftSDK(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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customCompileToolchain: customCompileToolchain, diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 999622ee993..49a98444ad2 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.hostSwiftSDK("/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..1b1f4e5aa1c 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.hostSwiftSDK(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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( 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.deriveTargetSwiftSDK( 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..3f94658e48b 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( 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..11d9fed8202 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( 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( 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( 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( 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( 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( fileSystem: fs, environment: .mockEnvironment, forRootPackage: .root, From 8bac989e67047039055bff8c09b782fa26dd137b Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Thu, 16 Oct 2025 11:38:28 -0400 Subject: [PATCH 2/3] Add back async versions until the ecosystem can adopt the async versions --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 108 ++++++++ Sources/PackageModel/UserToolchain.swift | 233 ++++++++++++++++++ 2 files changed, 341 insertions(+) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index f4c12bc1f58..c61e6bef412 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -529,6 +529,22 @@ public struct SwiftSDK: Equatable { try await self.hostSwiftSDK(binDir, environment: environment) } + /// The Swift SDK for the host platform. + @available(*, deprecated, message: "Use the async alternative") + public static func hostSwiftSDK( + _ binDir: Basics.AbsolutePath? = nil, + environment: Environment = .current, + observabilityScope: ObservabilityScope? = nil, + fileSystem: any FileSystem = Basics.localFileSystem + ) throws -> SwiftSDK { + try self.systemSwiftSDK( + binDir, + environment: environment, + observabilityScope: observabilityScope, + fileSystem: fileSystem + ) + } + /// The Swift SDK for the host platform. public static func hostSwiftSDK( _ binDir: Basics.AbsolutePath? = nil, @@ -544,6 +560,37 @@ public struct SwiftSDK: Equatable { ) } + /// 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 + ) throws -> SwiftSDK { + #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 + + return try Self.buildSwiftSDK( + binDir: binDir, + sdkPath: sdkPath, + sdkPaths: sdkPaths, + environment: environment, + fileSystem: fileSystem + ) + } /// A default Swift SDK on the host. /// @@ -577,6 +624,27 @@ public struct SwiftSDK: Equatable { ) } + /// Helper to get the SDK path for a Darwin platform (async version). + private static func getSDKPath( + for darwinPlatform: DarwinPlatform, + environment: Environment + ) 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 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 get the SDK path for a Darwin platform (async version). private static func getSDKPath( for darwinPlatform: DarwinPlatform, @@ -674,6 +742,46 @@ public struct SwiftSDK: Equatable { return (fwk: frameworkPath, lib: libraryPath) } + /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform. + public static func sdkPlatformPaths( + for darwinPlatform: DarwinPlatform, + environment: Environment = .current + ) 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 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" + ) + + let sdkPlatformFrameworkPath = PlatformPaths(frameworks: [frameworksPath, privateFrameworksPath], libraries: [librariesPath]) + _sdkPlatformFrameworkPath[darwinPlatform] = sdkPlatformFrameworkPath + return sdkPlatformFrameworkPath + } + /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform. public static func sdkPlatformPaths( for darwinPlatform: DarwinPlatform, diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 25251404659..7b283990050 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -175,6 +175,27 @@ public final class UserToolchain: Toolchain { return try getTool(name, binDirectories: envSearchPaths, fileSystem: fileSystem) } + private static func getTargetInfo(swiftCompiler: AbsolutePath) throws -> JSON { + // Call the compiler to get the target info JSON. + let compilerOutput: String + do { + let result = try 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 getTargetInfo(swiftCompiler: AbsolutePath) async throws -> JSON { // Call the compiler to get the target info JSON. let compilerOutput: String @@ -666,6 +687,218 @@ public final class UserToolchain: Toolchain { case custom(searchPaths: [AbsolutePath], useXcrun: Bool = true) } + @available(*, deprecated, message: "Use the async alternative") + public init( + swiftSDK: SwiftSDK, + environment: Environment = .current, + searchStrategy: SearchStrategy = .default, + customTargetInfo: JSON? = nil, + customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil, + customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil, + fileSystem: any FileSystem = localFileSystem + ) throws { + self.swiftSDK = swiftSDK + self.environment = environment + + switch searchStrategy { + case .default: + // Get the search paths from PATH. + self.envSearchPaths = getEnvSearchPaths( + pathString: environment[.path], + currentWorkingDirectory: fileSystem.currentWorkingDirectory + ) + self.useXcrun = !(fileSystem is InMemoryFileSystem) + case .custom(let searchPaths, let useXcrun): + self.envSearchPaths = searchPaths + self.useXcrun = useXcrun + } + + let swiftCompilers = try UserToolchain.determineSwiftCompilers( + binDirectories: swiftSDK.toolset.rootPaths, + useXcrun: self.useXcrun, + environment: environment, + searchPaths: self.envSearchPaths, + fileSystem: fileSystem + ) + self.swiftCompilerPath = swiftCompilers.compile + self.architectures = swiftSDK.architectures + + if let customInstalledSwiftPMConfiguration { + self.installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration + } else { + let path = swiftCompilerPath.parentDirectory.parentDirectory.appending(components: [ + "share", "pm", "config.json", + ]) + self.installedSwiftPMConfiguration = try Self.loadJSONResource( + config: path, + type: InstalledSwiftPMConfiguration.self, + default: InstalledSwiftPMConfiguration.default) + } + + var triple: Basics.Triple + if let targetTriple = swiftSDK.targetTriple { + self.targetInfo = nil + triple = targetTriple + } else { + // targetInfo from the compiler + 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) + } + + // 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 = self.architectures, architectures.count == 1 { + let components = triple.tripleString.drop(while: { $0 != "-" }) + triple = try Triple(architectures[0] + components) + } + + self.targetTriple = triple + + var swiftCompilerFlags: [String] = [] + var extraLinkerFlags: [String] = [] + + let swiftTestingPath: AbsolutePath? = try Self.deriveSwiftTestingPath( + derivedSwiftCompiler: swiftCompilers.compile, + swiftSDK: self.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 ?? [] + + self.extraFlags = BuildFlags( + cCompilerFlags: swiftSDK.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [], + cxxCompilerFlags: swiftSDK.toolset.knownTools[.cxxCompiler]?.extraCLIOptions ?? [], + swiftCompilerFlags: swiftCompilerFlags, + linkerFlags: extraLinkerFlags, + xcbuildFlags: swiftSDK.toolset.knownTools[.xcbuild]?.extraCLIOptions ?? []) + + self.includeSearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + self.librarySearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + + self.librarianPath = try swiftSDK.toolset.knownTools[.librarian]?.path ?? UserToolchain.determineLibrarian( + triple: triple, + binDirectories: swiftSDK.toolset.rootPaths, + useXcrun: useXcrun, + environment: environment, + searchPaths: envSearchPaths, + extraSwiftFlags: self.extraFlags.swiftCompilerFlags, + fileSystem: fileSystem + ) + + if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { + let sysrootFlags = [triple.isDarwin() ? "-isysroot" : "--sysroot", sdkDir.pathString] + self.extraFlags.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 + self.extraFlags.cCompilerFlags += [ + "-D_DEBUG", + "-D_MT", + "-D_DLL", + "-Xclang", + "--dependent-lib=msvcrtd", + ] + + case .multithreadedDLL: + // Defines _MT, and _DLL + // Linker uses MSVCRT.lib + self.extraFlags.cCompilerFlags += ["-D_MT", "-D_DLL", "-Xclang", "--dependent-lib=msvcrt"] + + case .multithreadedDebug: + // Defines _DEBUG, and _MT + // Linker uses LIBCMTD.lib + self.extraFlags.cCompilerFlags += ["-D_DEBUG", "-D_MT", "-Xclang", "--dependent-lib=libcmtd"] + + case .multithreaded: + // Defines _MT + // Linker uses LIBCMT.lib + self.extraFlags.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 useXcrun) = searchStrategy, !useXcrun { + xctestPath = nil + } else { + xctestPath = try Self.deriveXCTestPath( + swiftSDK: self.swiftSDK, + triple: triple, + environment: environment, + fileSystem: fileSystem + ) + } + + self.configuration = .init( + librarianPath: librarianPath, + swiftCompilerPath: swiftCompilers.manifest, + swiftCompilerFlags: self.extraFlags.swiftCompilerFlags, + swiftCompilerEnvironment: environment, + swiftPMLibrariesLocation: swiftPMLibrariesLocation, + sdkRootPath: self.swiftSDK.pathsConfiguration.sdkRootPath, + xctestPath: xctestPath, + swiftTestingPath: swiftTestingPath + ) + + self.fileSystem = fileSystem + } + public init( swiftSDK: SwiftSDK, environment: Environment = .current, From c93aa441d748dc7fcf15bf283131f0204b7a3002 Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Mon, 20 Oct 2025 15:10:10 -0400 Subject: [PATCH 3/3] Use renamed async versions of the new methods --- .../Sources/package-info/example.swift | 2 +- .../Commands/PackageCommands/APIDiff.swift | 2 +- Sources/Commands/Utilities/APIDigester.swift | 2 +- Sources/CoreCommands/SwiftCommandState.swift | 10 +- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 61 ++- Sources/PackageModel/UserToolchain.swift | 137 ++++-- .../SwiftSDKCommand/ConfigureSwiftSDK.swift | 4 +- .../SwiftSDKCommand/SwiftSDKSubcommand.swift | 4 +- Sources/Workspace/Workspace.swift | 390 +++++++++++++++++- .../_InternalTestSupport/MockWorkspace.swift | 4 +- Sources/_InternalTestSupport/Toolchain.swift | 2 +- Sources/swift-bootstrap/main.swift | 4 +- .../BuildPrebuilts.swift | 6 +- Tests/BuildTests/BuildPlanTests.swift | 10 +- Tests/BuildTests/PluginInvocationTests.swift | 16 +- Tests/BuildTests/PluginsBuildPlanTests.swift | 8 +- Tests/CommandsTests/PackageCommandTests.swift | 10 +- Tests/FunctionalTests/PluginTests.swift | 8 +- .../SwiftSDKBundleTests.swift | 12 +- Tests/PackageModelTests/SwiftSDKTests.swift | 2 +- Tests/PackageModelTests/ToolsetTests.swift | 8 +- .../PIFBuilderTests.swift | 2 +- Tests/WorkspaceTests/WorkspaceTests.swift | 12 +- 23 files changed, 592 insertions(+), 124 deletions(-) diff --git a/Examples/package-info/Sources/package-info/example.swift b/Examples/package-info/Sources/package-info/example.swift index 02f3484cb22..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 await 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 9193699a2c0..921d4e06585 100644 --- a/Sources/Commands/PackageCommands/APIDiff.swift +++ b/Sources/Commands/PackageCommands/APIDiff.swift @@ -284,7 +284,7 @@ struct APIDiff: AsyncSwiftCommand { try workingCopy.checkout(revision: baselineRevision) // Create the workspace for this package. - let workspace = try await Workspace( + let workspace = try await Workspace.create( forRootPackage: baselinePackageRoot, cancellator: swiftCommandState.cancellator ) diff --git a/Sources/Commands/Utilities/APIDigester.swift b/Sources/Commands/Utilities/APIDigester.swift index 94edf4899e0..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 await Workspace( + let workspace = try await Workspace.create( forRootPackage: baselinePackageRoot, cancellator: swiftCommandState.cancellator ) diff --git a/Sources/CoreCommands/SwiftCommandState.swift b/Sources/CoreCommands/SwiftCommandState.swift index 2dcaa916f2e..d35472d7f5f 100644 --- a/Sources/CoreCommands/SwiftCommandState.swift +++ b/Sources/CoreCommands/SwiftCommandState.swift @@ -491,7 +491,7 @@ public final class SwiftCommandState { self.observabilityHandler.progress, self.observabilityHandler.prompt ) - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: self.fileSystem, location: .init( scratchDirectory: self.scratchDirectory, @@ -831,7 +831,7 @@ public final class SwiftCommandState { outputHandler: { print($0.description) } ) - swiftSDK = try await SwiftSDK.deriveTargetSwiftSDK( + swiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostToolchain.targetTriple, customToolsets: self.options.locations.toolsetPaths, @@ -851,17 +851,17 @@ public final class SwiftCommandState { return hostToolchain } - return try await UserToolchain(swiftSDK: swiftSDK, environment: self.environment, fileSystem: self.fileSystem) + return try await UserToolchain.create(swiftSDK: swiftSDK, environment: self.environment, fileSystem: self.fileSystem) } public func getHostToolchain() async throws -> UserToolchain { - var hostSwiftSDK = try await SwiftSDK.hostSwiftSDK( + var hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync( environment: self.environment, observabilityScope: self.observabilityScope ) hostSwiftSDK.targetTriple = self.hostTriple - return try await UserToolchain( + return try await UserToolchain.create( swiftSDK: hostSwiftSDK, environment: self.environment, customTargetInfo: targetInfo, diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index c61e6bef412..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,17 +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 ) async throws -> SwiftSDK { - try await self.hostSwiftSDK(binDir, environment: environment) + try await self.hostSwiftSDKAsync(binDir, environment: environment) } - /// The Swift SDK for the host platform. - @available(*, deprecated, message: "Use the async alternative") + /// The Swift SDK for the host platform (synchronous version). public static func hostSwiftSDK( _ binDir: Basics.AbsolutePath? = nil, environment: Environment = .current, @@ -545,8 +545,8 @@ public struct SwiftSDK: Equatable { ) } - /// The Swift SDK for the host platform. - public static func hostSwiftSDK( + /// The Swift SDK for the host platform (asynchronous version). + public static func hostSwiftSDKAsync( _ binDir: Basics.AbsolutePath? = nil, environment: Environment = .current, observabilityScope: ObservabilityScope? = nil, @@ -624,7 +624,7 @@ public struct SwiftSDK: Equatable { ) } - /// Helper to get the SDK path for a Darwin platform (async version). + /// Helper to get the SDK path for a Darwin platform (sync version). private static func getSDKPath( for darwinPlatform: DarwinPlatform, environment: Environment @@ -847,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, @@ -861,6 +861,51 @@ public struct SwiftSDK: Equatable { store: SwiftSDKBundleStore, 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 diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 7b283990050..0c89cd0ee34 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -687,7 +687,6 @@ public final class UserToolchain: Toolchain { case custom(searchPaths: [AbsolutePath], useXcrun: Bool = true) } - @available(*, deprecated, message: "Use the async alternative") public init( swiftSDK: SwiftSDK, environment: Environment = .current, @@ -899,7 +898,11 @@ public final class UserToolchain: Toolchain { self.fileSystem = fileSystem } - public init( + /// 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, @@ -907,76 +910,78 @@ public final class UserToolchain: Toolchain { customLibrariesLocation: ToolchainConfiguration.SwiftPMLibrariesLocation? = nil, customInstalledSwiftPMConfiguration: InstalledSwiftPMConfiguration? = nil, fileSystem: any FileSystem = localFileSystem - ) async throws { - self.swiftSDK = swiftSDK - self.environment = environment + ) async throws -> UserToolchain { + let envSearchPaths: [AbsolutePath] + let useXcrun: Bool switch searchStrategy { case .default: // Get the search paths from PATH. - self.envSearchPaths = getEnvSearchPaths( + envSearchPaths = getEnvSearchPaths( pathString: environment[.path], currentWorkingDirectory: fileSystem.currentWorkingDirectory ) - self.useXcrun = !(fileSystem is InMemoryFileSystem) - case .custom(let searchPaths, let useXcrun): - self.envSearchPaths = searchPaths - self.useXcrun = useXcrun + useXcrun = !(fileSystem is InMemoryFileSystem) + case .custom(let searchPaths, let useXcrunFlag): + envSearchPaths = searchPaths + useXcrun = useXcrunFlag } let swiftCompilers = try UserToolchain.determineSwiftCompilers( binDirectories: swiftSDK.toolset.rootPaths, - useXcrun: self.useXcrun, + useXcrun: useXcrun, environment: environment, - searchPaths: self.envSearchPaths, + searchPaths: envSearchPaths, fileSystem: fileSystem ) - self.swiftCompilerPath = swiftCompilers.compile - self.architectures = swiftSDK.architectures + let swiftCompilerPath = swiftCompilers.compile + let architectures = swiftSDK.architectures + let installedSwiftPMConfiguration: InstalledSwiftPMConfiguration if let customInstalledSwiftPMConfiguration { - self.installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration + installedSwiftPMConfiguration = customInstalledSwiftPMConfiguration } else { let path = swiftCompilerPath.parentDirectory.parentDirectory.appending(components: [ "share", "pm", "config.json", ]) - self.installedSwiftPMConfiguration = try Self.loadJSONResource( + installedSwiftPMConfiguration = try Self.loadJSONResource( config: path, type: InstalledSwiftPMConfiguration.self, default: InstalledSwiftPMConfiguration.default) } var triple: Basics.Triple + let targetInfo: JSON? if let targetTriple = swiftSDK.targetTriple { - self.targetInfo = nil + targetInfo = nil triple = targetTriple } else { // targetInfo from the compiler - let targetInfo: JSON + let computedTargetInfo: JSON if let customTargetInfo { - targetInfo = customTargetInfo + computedTargetInfo = customTargetInfo } else { - targetInfo = try await Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) + computedTargetInfo = try await Self.getTargetInfo(swiftCompiler: swiftCompilers.compile) } - self.targetInfo = targetInfo - triple = try swiftSDK.targetTriple ?? Self.getHostTriple(targetInfo: targetInfo, versioned: false) + 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 = self.architectures, architectures.count == 1 { + if let architectures = architectures, architectures.count == 1 { let components = triple.tripleString.drop(while: { $0 != "-" }) triple = try Triple(architectures[0] + components) } - self.targetTriple = triple + let targetTriple = triple var swiftCompilerFlags: [String] = [] var extraLinkerFlags: [String] = [] let swiftTestingPath: AbsolutePath? = try Self.deriveSwiftTestingPath( derivedSwiftCompiler: swiftCompilers.compile, - swiftSDK: self.swiftSDK, + swiftSDK: swiftSDK, triple: triple, environment: environment, fileSystem: fileSystem @@ -1014,29 +1019,31 @@ public final class UserToolchain: Toolchain { extraLinkerFlags += swiftSDK.toolset.knownTools[.linker]?.extraCLIOptions ?? [] - self.extraFlags = BuildFlags( + 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 ?? []) - self.includeSearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] - self.librarySearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + let includeSearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] + let librarySearchPaths = swiftSDK.pathsConfiguration.includeSearchPaths ?? [] - self.librarianPath = try swiftSDK.toolset.knownTools[.librarian]?.path ?? UserToolchain.determineLibrarian( + let librarianPath = try swiftSDK.toolset.knownTools[.librarian]?.path ?? UserToolchain.determineLibrarian( triple: triple, binDirectories: swiftSDK.toolset.rootPaths, useXcrun: useXcrun, environment: environment, searchPaths: envSearchPaths, - extraSwiftFlags: self.extraFlags.swiftCompilerFlags, + extraSwiftFlags: extraFlags.swiftCompilerFlags, fileSystem: fileSystem ) + var modifiedExtraFlags = extraFlags + if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { let sysrootFlags = [triple.isDarwin() ? "-isysroot" : "--sysroot", sdkDir.pathString] - self.extraFlags.cCompilerFlags.insert(contentsOf: sysrootFlags, at: 0) + modifiedExtraFlags.cCompilerFlags.insert(contentsOf: sysrootFlags, at: 0) } if triple.isWindows() { @@ -1050,7 +1057,7 @@ public final class UserToolchain: Toolchain { case .multithreadedDebugDLL: // Defines _DEBUG, _MT, and _DLL // Linker uses MSVCRTD.lib - self.extraFlags.cCompilerFlags += [ + modifiedExtraFlags.cCompilerFlags += [ "-D_DEBUG", "-D_MT", "-D_DLL", @@ -1061,17 +1068,17 @@ public final class UserToolchain: Toolchain { case .multithreadedDLL: // Defines _MT, and _DLL // Linker uses MSVCRT.lib - self.extraFlags.cCompilerFlags += ["-D_MT", "-D_DLL", "-Xclang", "--dependent-lib=msvcrt"] + modifiedExtraFlags.cCompilerFlags += ["-D_MT", "-D_DLL", "-Xclang", "--dependent-lib=msvcrt"] case .multithreadedDebug: // Defines _DEBUG, and _MT // Linker uses LIBCMTD.lib - self.extraFlags.cCompilerFlags += ["-D_DEBUG", "-D_MT", "-Xclang", "--dependent-lib=libcmtd"] + modifiedExtraFlags.cCompilerFlags += ["-D_DEBUG", "-D_MT", "-Xclang", "--dependent-lib=libcmtd"] case .multithreaded: // Defines _MT // Linker uses LIBCMT.lib - self.extraFlags.cCompilerFlags += ["-D_MT", "-Xclang", "--dependent-lib=libcmt"] + modifiedExtraFlags.cCompilerFlags += ["-D_MT", "-Xclang", "--dependent-lib=libcmt"] } } } @@ -1085,28 +1092,78 @@ public final class UserToolchain: Toolchain { ) let xctestPath: AbsolutePath? - if case .custom(_, let useXcrun) = searchStrategy, !useXcrun { + if case .custom(_, let useXcrunFlag) = searchStrategy, !useXcrunFlag { xctestPath = nil } else { xctestPath = try Self.deriveXCTestPath( - swiftSDK: self.swiftSDK, + swiftSDK: swiftSDK, triple: triple, environment: environment, fileSystem: fileSystem ) } - self.configuration = .init( + let configuration = ToolchainConfiguration( librarianPath: librarianPath, swiftCompilerPath: swiftCompilers.manifest, - swiftCompilerFlags: self.extraFlags.swiftCompilerFlags, + swiftCompilerFlags: modifiedExtraFlags.swiftCompilerFlags, swiftCompilerEnvironment: environment, swiftPMLibrariesLocation: swiftPMLibrariesLocation, - sdkRootPath: self.swiftSDK.pathsConfiguration.sdkRootPath, + 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 } diff --git a/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift b/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift index ac9fbe4e4b1..fcf5b25bd97 100644 --- a/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift +++ b/Sources/SwiftSDKCommand/ConfigureSwiftSDK.swift @@ -116,8 +116,8 @@ struct ConfigureSwiftSDK: AsyncParsableCommand { let observabilityScope = observabilitySystem.topScope let swiftSDKsDirectory = try self.getOrCreateSwiftSDKsDirectory() - let hostSwiftSDK = try await SwiftSDK.hostSwiftSDK() - let hostToolchain = try await UserToolchain(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 c5d571cbfd4..821ea2fc1db 100644 --- a/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift +++ b/Sources/SwiftSDKCommand/SwiftSDKSubcommand.swift @@ -62,8 +62,8 @@ extension SwiftSDKSubcommand { let swiftSDKsDirectory = try self.getOrCreateSwiftSDKsDirectory() let environment = Environment.current - let hostSwiftSDK = try await SwiftSDK.hostSwiftSDK(environment: environment) - let hostToolchain = try await UserToolchain( + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: environment) + let hostToolchain = try await UserToolchain.create( swiftSDK: hostSwiftSDK, environment: environment ) diff --git a/Sources/Workspace/Workspace.swift b/Sources/Workspace/Workspace.swift index 8daa085bc7c..b51e067c0a2 100644 --- a/Sources/Workspace/Workspace.swift +++ b/Sources/Workspace/Workspace.swift @@ -206,8 +206,146 @@ public class Workspace { customRepositoryProvider: (any RepositoryProvider)? = .none, // delegate delegate: Delegate? = .none - ) async throws { - try await self.init( + ) throws { + try self.init( + 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 + ) + } + + /// 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, @@ -272,10 +410,10 @@ public class Workspace { customRepositoryProvider: RepositoryProvider? = .none, // delegate delegate: Delegate? = .none - ) async throws { + ) throws { let fileSystem = fileSystem ?? localFileSystem let location = try Location(forRootPackage: packagePath, fileSystem: fileSystem) - try await self.init( + try self.init( fileSystem: fileSystem, environment: environment, location: location, @@ -326,7 +464,7 @@ public class Workspace { customRepositoryProvider: RepositoryProvider? = .none, // delegate delegate: Delegate? = .none - ) async throws { + ) throws { let fileSystem = fileSystem ?? localFileSystem let location = try Location(forRootPackage: packagePath, fileSystem: fileSystem) let manifestLoader = ManifestLoader( @@ -336,7 +474,7 @@ public class Workspace { delegate: delegate.map(WorkspaceManifestLoaderDelegate.init(workspaceDelegate:)), pruneDependencies: configuration?.pruneDependencies ?? false ) - try await self.init( + try self.init( fileSystem: fileSystem, location: location, authorizationProvider: authorizationProvider, @@ -385,8 +523,8 @@ public class Workspace { customChecksumAlgorithm: HashAlgorithm? = .none, // delegate delegate: Delegate? = .none - ) async throws -> Workspace { - try await .init( + ) throws -> Workspace { + try .init( fileSystem: fileSystem, environment: environment, location: location, @@ -416,6 +554,235 @@ 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? + ) 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 = try customHostToolchain ?? UserToolchain( + swiftSDK: .hostSwiftSDK( + environment: environment + ), + 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 convenience init( // core fileSystem: FileSystem, @@ -463,10 +830,9 @@ public class Workspace { if let customHostToolchain { hostToolchain = customHostToolchain } else { - hostToolchain = try await UserToolchain( - swiftSDK: .hostSwiftSDK( - environment: environment - ), + let swiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: environment) + hostToolchain = try await UserToolchain.create( + swiftSDK: swiftSDK, environment: environment, fileSystem: fileSystem ) diff --git a/Sources/_InternalTestSupport/MockWorkspace.swift b/Sources/_InternalTestSupport/MockWorkspace.swift index 04a4c83622b..a0262446d6b 100644 --- a/Sources/_InternalTestSupport/MockWorkspace.swift +++ b/Sources/_InternalTestSupport/MockWorkspace.swift @@ -34,7 +34,7 @@ extension UserToolchain { _ fileSystem: InMemoryFileSystem, hostTriple: Triple? = nil ) async throws -> UserToolchain { - var hostSwiftSDK = try await SwiftSDK.hostSwiftSDK(environment: .mockEnvironment, fileSystem: fileSystem) + var hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync(environment: .mockEnvironment, fileSystem: fileSystem) if let hostTriple = hostTriple { hostSwiftSDK.targetTriple = hostTriple } else { @@ -43,7 +43,7 @@ extension UserToolchain { let env = Environment.mockEnvironment - return try await UserToolchain( + return try await UserToolchain.create( swiftSDK: hostSwiftSDK, environment: env, searchStrategy: .custom( diff --git a/Sources/_InternalTestSupport/Toolchain.swift b/Sources/_InternalTestSupport/Toolchain.swift index bd298af075d..14b246a384a 100644 --- a/Sources/_InternalTestSupport/Toolchain.swift +++ b/Sources/_InternalTestSupport/Toolchain.swift @@ -44,7 +44,7 @@ package func resolveBinDir() throws -> AbsolutePath { extension SwiftSDK { public static func `default`() async throws -> Self { let binDir = try resolveBinDir() - return try await SwiftSDK.hostSwiftSDK(binDir, environment: .current) + return try await SwiftSDK.hostSwiftSDKAsync(binDir, environment: .current) } } diff --git a/Sources/swift-bootstrap/main.swift b/Sources/swift-bootstrap/main.swift index c7752a009e7..9c5fa412978 100644 --- a/Sources/swift-bootstrap/main.swift +++ b/Sources/swift-bootstrap/main.swift @@ -228,8 +228,8 @@ struct SwiftBootstrapBuildTool: AsyncParsableCommand { self.identityResolver = DefaultIdentityResolver() self.dependencyMapper = DefaultDependencyMapper(identityResolver: self.identityResolver) let environment = Environment.current - self.hostToolchain = try await 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 97208dcea8c..ad062936e2d 100644 --- a/Sources/swift-build-prebuilts/BuildPrebuilts.swift +++ b/Sources/swift-build-prebuilts/BuildPrebuilts.swift @@ -80,11 +80,11 @@ struct BuildPrebuilts: AsyncParsableCommand { func computeSwiftVersion() async throws -> String? { let fileSystem = localFileSystem let environment = Environment.current - let hostSwiftSDK = try await SwiftSDK.hostSwiftSDK( + let hostSwiftSDK = try await SwiftSDK.hostSwiftSDKAsync( environment: environment, fileSystem: fileSystem ) - let hostToolchain = try await UserToolchain( + let hostToolchain = try await UserToolchain.create( swiftSDK: hostSwiftSDK, environment: environment ) @@ -151,7 +151,7 @@ struct BuildPrebuilts: AsyncParsableCommand { // Update package with the libraries let packageFile = repoDir.appending(component: "Package.swift") - let workspace = try await 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 diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index d90b6244ca6..35b18661068 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -5263,7 +5263,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try await UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5390,7 +5390,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try await UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5509,7 +5509,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let mockToolchain = try await UserToolchain( + let mockToolchain = try await UserToolchain.create( swiftSDK: userSwiftSDK, environment: env, searchStrategy: .custom( @@ -5643,7 +5643,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { swiftStaticResourcesPath: "/usr/lib/swift_static/none" ) ) - let toolchain = try await UserToolchain( + let toolchain = try await UserToolchain.create( swiftSDK: swiftSDK, environment: .mockEnvironment, customTargetInfo: UserToolchain.mockTargetInfo, @@ -5804,7 +5804,7 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) let env = Environment.mockEnvironment - let toolchain = try await UserToolchain( + let toolchain = try await UserToolchain.create( swiftSDK: swiftSDK, environment: env, searchStrategy: .custom( diff --git a/Tests/BuildTests/PluginInvocationTests.swift b/Tests/BuildTests/PluginInvocationTests.swift index b2a8021babb..3731f244cad 100644 --- a/Tests/BuildTests/PluginInvocationTests.swift +++ b/Tests/BuildTests/PluginInvocationTests.swift @@ -328,7 +328,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -709,7 +709,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -789,7 +789,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -929,7 +929,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -1072,7 +1072,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -1261,7 +1261,7 @@ final class PluginInvocationTests: XCTestCase { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() let environment = Environment.current - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, location: try Workspace.Location(forRootPackage: packageDir, fileSystem: localFileSystem), customHostToolchain: await UserToolchain( @@ -1415,7 +1415,7 @@ final class PluginInvocationTests: XCTestCase { ) // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -1447,7 +1447,7 @@ final class PluginInvocationTests: XCTestCase { // Construct a toolchain with a made-up host/target triple let swiftSDK = try await SwiftSDK.default() - let toolchain = try await UserToolchain( + let toolchain = try await UserToolchain.create( swiftSDK: SwiftSDK( hostTriple: hostTriple, targetTriple: hostTriple, diff --git a/Tests/BuildTests/PluginsBuildPlanTests.swift b/Tests/BuildTests/PluginsBuildPlanTests.swift index 98704dbd2e6..928853e68e3 100644 --- a/Tests/BuildTests/PluginsBuildPlanTests.swift +++ b/Tests/BuildTests/PluginsBuildPlanTests.swift @@ -62,8 +62,8 @@ struct PluginsBuildPlanTests { func commandPluginDependenciesWhenNotCrossCompiling( buildData: BuildData, ) async throws { - let hostToolchain = try await UserToolchain( - swiftSDK: try await SwiftSDK.hostSwiftSDK(environment: [:]), + let hostToolchain = try await UserToolchain.create( + swiftSDK: try await SwiftSDK.hostSwiftSDKAsync(environment: [:]), environment: [:] ) let hostTriple = try! hostToolchain.targetTriple.withoutVersion().tripleString @@ -116,8 +116,8 @@ struct PluginsBuildPlanTests { func commandPluginDependenciesWhenCrossCompiling( buildData: BuildData, ) async throws { - let hostToolchain = try await UserToolchain( - swiftSDK: try await SwiftSDK.hostSwiftSDK(environment: [:]), + let hostToolchain = try await UserToolchain.create( + swiftSDK: try await SwiftSDK.hostSwiftSDKAsync(environment: [:]), environment: [:] ) // let hostTriple = try! hostToolchain.targetTriple.withoutVersion().tripleString diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 664b6b85008..988ee4216e9 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -4691,8 +4691,8 @@ struct PackageCommandTests { """ ) let environment = Environment.current - let hostTriple = try await UserToolchain( - swiftSDK: await .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 await UserToolchain( - swiftSDK: await .hostSwiftSDK(environment: environment), + let hostTriple = try await UserToolchain.create( + swiftSDK: try await .hostSwiftSDKAsync(environment: environment), environment: environment ).targetTriple let hostTripleString = @@ -7275,7 +7275,7 @@ struct PackageCommandTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: await UserToolchain.default()), diff --git a/Tests/FunctionalTests/PluginTests.swift b/Tests/FunctionalTests/PluginTests.swift index 11195738cc2..efc4e2d26e1 100644 --- a/Tests/FunctionalTests/PluginTests.swift +++ b/Tests/FunctionalTests/PluginTests.swift @@ -707,7 +707,7 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() let defaultToolchain = try await UserToolchain.default() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: defaultToolchain), @@ -909,7 +909,7 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() let defaultToolchain = try await UserToolchain.default() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: defaultToolchain), @@ -1009,7 +1009,7 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() let defaultToolchain = try await UserToolchain.default() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: packageDir, customManifestLoader: ManifestLoader(toolchain: defaultToolchain), @@ -1330,7 +1330,7 @@ final class PluginTests { // Load a workspace from the package. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, location: .init(forRootPackage: packageDir, fileSystem: localFileSystem), customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), diff --git a/Tests/PackageModelTests/SwiftSDKBundleTests.swift b/Tests/PackageModelTests/SwiftSDKBundleTests.swift index 791766aae74..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 await 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 await 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 await 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 await 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 await 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 await 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 49a98444ad2..911d8221a12 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -707,7 +707,7 @@ final class SwiftSDKTests: XCTestCase { } func testDefaultSDKs() async throws { - let hostSDK = try await SwiftSDK.hostSwiftSDK("/prefix/bin") + let hostSDK = try await SwiftSDK.hostSwiftSDKAsync("/prefix/bin") #if os(macOS) let iOSPlatform = try AbsolutePath(validating: "/usr/share/iPhoneOS.platform") diff --git a/Tests/PackageModelTests/ToolsetTests.swift b/Tests/PackageModelTests/ToolsetTests.swift index 1b1f4e5aa1c..91948741254 100644 --- a/Tests/PackageModelTests/ToolsetTests.swift +++ b/Tests/PackageModelTests/ToolsetTests.swift @@ -216,7 +216,7 @@ final class ToolsetTests: XCTestCase { try fileSystem.writeFileContents(testFile.path, string: testFile.json.underlying) } - let hostSwiftSDK = try await 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 await 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 await 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 await SwiftSDK.deriveTargetSwiftSDK( + let targetSwiftSDK = try await SwiftSDK.deriveTargetSwiftSDKAsync( hostSwiftSDK: hostSwiftSDK, hostTriple: hostTriple, customToolsets: [compilersNoRoot.path, someToolsWithRoot.path], diff --git a/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift b/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift index 3f94658e48b..700c0bf7ba0 100644 --- a/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift +++ b/Tests/SwiftBuildSupportTests/PIFBuilderTests.swift @@ -45,7 +45,7 @@ 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 await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: fixturePath, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), diff --git a/Tests/WorkspaceTests/WorkspaceTests.swift b/Tests/WorkspaceTests/WorkspaceTests.swift index 11d9fed8202..be1d2075a75 100644 --- a/Tests/WorkspaceTests/WorkspaceTests.swift +++ b/Tests/WorkspaceTests/WorkspaceTests.swift @@ -181,7 +181,7 @@ final class WorkspaceTests: XCTestCase { let manifestLoader = try ManifestLoader(toolchain: try await UserToolchain.default()) let sandbox = path.appending("ws") - return try await Workspace( + return try await Workspace.create( fileSystem: fs, forRootPackage: sandbox, customManifestLoader: manifestLoader, @@ -358,7 +358,7 @@ final class WorkspaceTests: XCTestCase { ) """ ) - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: localFileSystem, forRootPackage: pkgDir, customManifestLoader: ManifestLoader(toolchain: try await UserToolchain.default()), @@ -5533,7 +5533,7 @@ final class WorkspaceTests: XCTestCase { // Load the workspace. let observability = ObservabilitySystem.makeForTesting() - let workspace = try await Workspace( + let workspace = try await Workspace.create( forRootPackage: packagePath, customHostToolchain: try await UserToolchain.default() ) @@ -12710,7 +12710,7 @@ final class WorkspaceTests: XCTestCase { let manifestLoader = try ManifestLoader(toolchain: try await UserToolchain.default()) let sandbox = path.appending("ws") - let workspace = try await Workspace( + let workspace = try await Workspace.create( fileSystem: fs, forRootPackage: sandbox, customManifestLoader: manifestLoader, @@ -12784,7 +12784,7 @@ final class WorkspaceTests: XCTestCase { do { // no error let delegate = MockWorkspaceDelegate() - let workspace = try await 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 await Workspace( + let workspace = try await Workspace.create( fileSystem: fs, environment: .mockEnvironment, forRootPackage: .root,