From c0521b3b9ff05cb1e0dc58c0595629c53a19606b Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Thu, 19 Jun 2025 09:00:58 -0400 Subject: [PATCH 01/15] Activate swift build support for command plugins --- .../PackageCommands/PluginCommand.swift | 22 ++++---- .../Commands/Utilities/PluginDelegate.swift | 51 +++++++++++-------- Tests/CommandsTests/PackageCommandTests.swift | 21 +++++--- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/Sources/Commands/PackageCommands/PluginCommand.swift b/Sources/Commands/PackageCommands/PluginCommand.swift index 891e154a1c6..ecd191d7aaf 100644 --- a/Sources/Commands/PackageCommands/PluginCommand.swift +++ b/Sources/Commands/PackageCommands/PluginCommand.swift @@ -205,12 +205,17 @@ struct PluginCommand: AsyncSwiftCommand { swiftCommandState.shouldDisableSandbox = swiftCommandState.shouldDisableSandbox || pluginArguments.globalOptions.security .shouldDisableSandbox + let buildSystemKind = + pluginArguments.globalOptions.build.buildSystem != .native ? + pluginArguments.globalOptions.build.buildSystem : + swiftCommandState.options.build.buildSystem + // At this point we know we found exactly one command plugin, so we run it. In SwiftPM CLI, we have only one root package. try await PluginCommand.run( plugin: matchingPlugins[0], package: packageGraph.rootPackages[packageGraph.rootPackages.startIndex], packageGraph: packageGraph, - buildSystem: pluginArguments.globalOptions.build.buildSystem, + buildSystem: buildSystemKind, options: pluginOptions, arguments: unparsedArguments, swiftCommandState: swiftCommandState @@ -327,7 +332,9 @@ struct PluginCommand: AsyncSwiftCommand { let toolSearchDirs = [try swiftCommandState.getTargetToolchain().swiftCompilerPath.parentDirectory] + getEnvSearchPaths(pathString: Environment.current[.path], currentWorkingDirectory: .none) - let buildParameters = try swiftCommandState.toolsBuildParameters + var buildParameters = try 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. let buildSystem = try await swiftCommandState.createBuildSystem( explicitBuildSystem: buildSystemKind, @@ -342,16 +349,11 @@ struct PluginCommand: AsyncSwiftCommand { fileSystem: swiftCommandState.fileSystem, environment: buildParameters.buildEnvironment, for: try pluginScriptRunner.hostTriple - ) { name, _ in + ) { name, path in // Build the product referenced by the tool, and add the executable to the tool map. Product dependencies are not supported within a package, so if the tool happens to be from the same package, we instead find the executable that corresponds to the product. There is always one, because of autogeneration of implicit executables with the same name as the target if there isn't an explicit one. try await buildSystem.build(subset: .product(name, for: .host)) - if let builtTool = try buildSystem.buildPlan.buildProducts.first(where: { - $0.product.name == name && $0.buildParameters.destination == .host - }) { - return try builtTool.binaryPath - } else { - return nil - } + + return buildParameters.buildPath.appending(path) } // Set up a delegate to handle callbacks from the command plugin. diff --git a/Sources/Commands/Utilities/PluginDelegate.swift b/Sources/Commands/Utilities/PluginDelegate.swift index ae75b3ea919..98464b43227 100644 --- a/Sources/Commands/Utilities/PluginDelegate.swift +++ b/Sources/Commands/Utilities/PluginDelegate.swift @@ -181,30 +181,39 @@ final class PluginDelegate: PluginInvocationDelegate { // Run the build. This doesn't return until the build is complete. let success = await buildSystem.buildIgnoringError(subset: buildSubset) - // Create and return the build result record based on what the delegate collected and what's in the build plan. - let builtProducts = try buildSystem.buildPlan.buildProducts.filter { - switch subset { - case .all(let includingTests): - return includingTests ? true : $0.product.type != .test - case .product(let name): - return $0.product.name == name - case .target(let name): - return $0.product.name == name + let packageGraph = try await buildSystem.getPackageGraph() + + var builtArtifacts: [PluginInvocationBuildResult.BuiltArtifact] = [] + + for rootPkg in packageGraph.rootPackages { + let builtProducts = rootPkg.products.filter { + switch subset { + case .all(let includingTests): + return includingTests ? true : $0.type != .test + case .product(let name): + return $0.name == name + case .target(let name): + return $0.name == name + } } - } - let builtArtifacts: [PluginInvocationBuildResult.BuiltArtifact] = try builtProducts.compactMap { - switch $0.product.type { - case .library(let kind): - return try .init( - path: $0.binaryPath.pathString, - kind: (kind == .dynamic) ? .dynamicLibrary : .staticLibrary - ) - case .executable: - return try .init(path: $0.binaryPath.pathString, kind: .executable) - default: - return nil + + let artifacts: [PluginInvocationBuildResult.BuiltArtifact] = try builtProducts.compactMap { + switch $0.type { + case .library(let kind): + return .init( + path: try buildParameters.binaryPath(for: $0).pathString, + kind: (kind == .dynamic) ? .dynamicLibrary : .staticLibrary + ) + case .executable: + return .init(path: try buildParameters.binaryPath(for: $0).pathString, kind: .executable) + default: + return nil + } } + + builtArtifacts.append(contentsOf: artifacts) } + return PluginInvocationBuildResult( succeeded: success, logText: bufferedOutputStream.bytes.cString, diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 537612b23ff..d10f237b8ad 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -3462,9 +3462,11 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { let (stdout, _) = try await self.execute(["my-build-tester", "--product", "MyExecutable", "--print-commands"], packagePath: packageDir) XCTAssertMatch(stdout, .contains("Building for debugging...")) XCTAssertNoMatch(stdout, .contains("Building for production...")) - XCTAssertMatch(stdout, .contains("-module-name MyExecutable")) - XCTAssertMatch(stdout, .contains("-DEXTRA_SWIFT_FLAG")) - XCTAssertMatch(stdout, .contains("Build of product 'MyExecutable' complete!")) + if buildSystemProvider == .native { + XCTAssertMatch(stdout, .contains("-module-name MyExecutable")) + XCTAssertMatch(stdout, .contains("-DEXTRA_SWIFT_FLAG")) + XCTAssertMatch(stdout, .contains("Build of product 'MyExecutable' complete!")) + } XCTAssertMatch(stdout, .contains("succeeded: true")) switch buildSystemProvider { case .native: @@ -3483,7 +3485,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyExecutable")) - XCTAssertMatch(stdout, .contains("Build of product 'MyExecutable' complete!")) + if buildSystemProvider == .native { + XCTAssertMatch(stdout, .contains("Build of product 'MyExecutable' complete!")) + } XCTAssertMatch(stdout, .contains("succeeded: true")) switch buildSystemProvider { case .native: @@ -3502,7 +3506,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyLibrary")) - XCTAssertMatch(stdout, .contains("Build of product 'MyStaticLibrary' complete!")) + if buildSystemProvider == .native { + XCTAssertMatch(stdout, .contains("Build of product 'MyStaticLibrary' complete!")) + } XCTAssertMatch(stdout, .contains("succeeded: true")) switch buildSystemProvider { case .native: @@ -3521,7 +3527,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .contains("Building for production...")) XCTAssertNoMatch(stdout, .contains("Building for debug...")) XCTAssertNoMatch(stdout, .contains("-module-name MyLibrary")) - XCTAssertMatch(stdout, .contains("Build of product 'MyDynamicLibrary' complete!")) + if buildSystemProvider == .native { + XCTAssertMatch(stdout, .contains("Build of product 'MyDynamicLibrary' complete!")) + } XCTAssertMatch(stdout, .contains("succeeded: true")) switch buildSystemProvider { case .native: @@ -4107,7 +4115,6 @@ class PackageCommandSwiftBuildTests: PackageCommandTestCase { } override func testCommandPluginTestingCallbacks() async throws { - throw XCTSkip("SWBINTTODO: Requires PIF generation to adopt new test runner product type") try XCTSkipOnWindows(because: "TSCBasic/Path.swift:969: Assertion failed, https://github.com/swiftlang/swift-package-manager/issues/8602") try await super.testCommandPluginTestingCallbacks() } From 7d6eca8ba7ef6623c07109cfabb4f0380f31aaff Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 08:39:44 -0400 Subject: [PATCH 02/15] Fix failing tests Filter dynamic targets when discovering configured targets Use the build plan and binary path for the native build system tool path calculation --- .../PackageCommands/PluginCommand.swift | 13 ++++++++++- .../SwiftBuildSupport/SwiftBuildSystem.swift | 3 ++- Tests/FunctionalTests/PluginTests.swift | 16 +++++++++----- Tests/FunctionalTests/TraitTests.swift | 22 +++++++++++-------- 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Sources/Commands/PackageCommands/PluginCommand.swift b/Sources/Commands/PackageCommands/PluginCommand.swift index ecd191d7aaf..ec2243a6a71 100644 --- a/Sources/Commands/PackageCommands/PluginCommand.swift +++ b/Sources/Commands/PackageCommands/PluginCommand.swift @@ -353,7 +353,18 @@ struct PluginCommand: AsyncSwiftCommand { // Build the product referenced by the tool, and add the executable to the tool map. Product dependencies are not supported within a package, so if the tool happens to be from the same package, we instead find the executable that corresponds to the product. There is always one, because of autogeneration of implicit executables with the same name as the target if there isn't an explicit one. try await buildSystem.build(subset: .product(name, for: .host)) - return buildParameters.buildPath.appending(path) + // TODO determine if there is a common way to calculate the build tool binary path that doesn't depend on the build system. + if buildSystemKind == .native { + if let builtTool = try buildSystem.buildPlan.buildProducts.first(where: { + $0.product.name == name && $0.buildParameters.destination == .host + }) { + return try builtTool.binaryPath + } else { + return nil + } + } else { + return buildParameters.buildPath.appending(path) + } } // Set up a delegate to handle callbacks from the command plugin. diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index 0a688010f3e..75ae6601c8d 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -316,7 +316,8 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { let workspaceInfo = try await session.workspaceInfo() configuredTargets = try [pifTargetName].map { targetName in - let infos = workspaceInfo.targetInfos.filter { $0.targetName == targetName } + // TODO use an API to decide if this is a dynamic target info + let infos = workspaceInfo.targetInfos.filter { $0.targetName == targetName && !$0.guid.hasSuffix("-dynamic") } switch infos.count { case 0: self.observabilityScope.emit(error: "Could not find target named '\(targetName)'") diff --git a/Tests/FunctionalTests/PluginTests.swift b/Tests/FunctionalTests/PluginTests.swift index 6269ff112e2..7decd876caf 100644 --- a/Tests/FunctionalTests/PluginTests.swift +++ b/Tests/FunctionalTests/PluginTests.swift @@ -753,14 +753,18 @@ final class PluginTests { @Test( .enabled(if: (try? UserToolchain.default)!.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency"), + arguments: [BuildSystemProvider.Kind.native, .swiftbuild] ) - func testLocalAndRemoteToolDependencies() async throws { + func testLocalAndRemoteToolDependencies(buildSystem: BuildSystemProvider.Kind) async throws { try await fixture(name: "Miscellaneous/Plugins/PluginUsingLocalAndRemoteTool") { path in - let (stdout, stderr) = try await executeSwiftPackage(path.appending("MyLibrary"), configuration: .debug, extraArgs: ["plugin", "my-plugin"]) - #expect(stderr.contains("Linking RemoteTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Linking LocalTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Linking ImpliedLocalTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Build of product 'ImpliedLocalTool' complete!"), "stdout:\n\(stderr)\n\(stdout)") + let (stdout, stderr) = try await executeSwiftPackage(path.appending("MyLibrary"), configuration: .debug, extraArgs: ["--build-system", buildSystem.rawValue, "plugin", "my-plugin"]) + if buildSystem == .native { + // Native build system is more explicit about what it's doing in stderr + #expect(stderr.contains("Linking RemoteTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Linking LocalTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Linking ImpliedLocalTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Build of product 'ImpliedLocalTool' complete!"), "stdout:\n\(stderr)\n\(stdout)") + } #expect(stdout.contains("A message from the remote tool."), "stdout:\n\(stderr)\n\(stdout)") #expect(stdout.contains("A message from the local tool."), "stdout:\n\(stderr)\n\(stdout)") #expect(stdout.contains("A message from the implied local tool."), "stdout:\n\(stderr)\n\(stdout)") diff --git a/Tests/FunctionalTests/TraitTests.swift b/Tests/FunctionalTests/TraitTests.swift index 160ddd6c81b..afdc0ec8796 100644 --- a/Tests/FunctionalTests/TraitTests.swift +++ b/Tests/FunctionalTests/TraitTests.swift @@ -487,15 +487,19 @@ struct TraitTests { buildSystem: BuildSystemProvider.Kind, ) async throws { try await fixture(name: "Traits") { fixturePath in - let (stdout, _) = try await executeSwiftPackage( - fixturePath.appending("Package10"), - extraArgs: ["plugin", "extract", "--experimental-prune-unused-dependencies"], - buildSystem: buildSystem, - ) - let path = String(stdout.split(whereSeparator: \.isNewline).first!) - let symbolGraph = try String(contentsOfFile: "\(path)/Package10Library1.symbols.json", encoding: .utf8) - #expect(symbolGraph.contains("TypeGatedByPackage10Trait1")) - #expect(symbolGraph.contains("TypeGatedByPackage10Trait2")) + try await withKnownIssue { + let (stdout, _) = try await executeSwiftPackage( + fixturePath.appending("Package10"), + extraArgs: ["plugin", "extract", "--experimental-prune-unused-dependencies"], + buildSystem: buildSystem, + ) + let path = String(stdout.split(whereSeparator: \.isNewline).first!) + let symbolGraph = try String(contentsOfFile: "\(path)/Package10Library1.symbols.json", encoding: .utf8) + #expect(symbolGraph.contains("TypeGatedByPackage10Trait1")) + #expect(symbolGraph.contains("TypeGatedByPackage10Trait2")) + } when: { + buildSystem == .swiftbuild + } } } From 0f78b718034fc32f1183cfad9c7ce558355af055 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 12:23:56 -0400 Subject: [PATCH 03/15] Skip test with known issue with Windows Add runtime library environment to the command plugin invocation for the tools that it runs --- .../Plugins/DefaultPluginScriptRunner.swift | 15 ++++++++--- Tests/FunctionalTests/PluginTests.swift | 27 +++++++++++-------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Sources/SPMBuildCore/Plugins/DefaultPluginScriptRunner.swift b/Sources/SPMBuildCore/Plugins/DefaultPluginScriptRunner.swift index 38da378e0ac..f8a98a664e5 100644 --- a/Sources/SPMBuildCore/Plugins/DefaultPluginScriptRunner.swift +++ b/Sources/SPMBuildCore/Plugins/DefaultPluginScriptRunner.swift @@ -463,13 +463,22 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable { let process = Foundation.Process() process.executableURL = URL(fileURLWithPath: command[0]) process.arguments = Array(command.dropFirst()) - process.environment = ProcessInfo.processInfo.environment + + var env = Environment.current + + // Update the environment for any runtime library paths that tools compiled + // for the command plugin might require after they have been built. + let runtimeLibPaths = self.toolchain.runtimeLibraryPaths + for libPath in runtimeLibPaths { + env.appendPath(key: .libraryPath, value: libPath.pathString) + } + #if os(Windows) let pluginLibraryPath = self.toolchain.swiftPMLibrariesLocation.pluginLibraryPath.pathString - var env = Environment.current env.prependPath(key: .path, value: pluginLibraryPath) - process.environment = .init(env) #endif + process.environment = .init(env) + process.currentDirectoryURL = workingDirectory.asURL // Set up a pipe for sending structured messages to the plugin on its stdin. diff --git a/Tests/FunctionalTests/PluginTests.swift b/Tests/FunctionalTests/PluginTests.swift index 7decd876caf..ad6ddad70d1 100644 --- a/Tests/FunctionalTests/PluginTests.swift +++ b/Tests/FunctionalTests/PluginTests.swift @@ -752,22 +752,27 @@ final class PluginTests { } @Test( + .bug("https://github.com/swiftlang/swift-package-manager/issues/8602"), .enabled(if: (try? UserToolchain.default)!.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency"), arguments: [BuildSystemProvider.Kind.native, .swiftbuild] ) func testLocalAndRemoteToolDependencies(buildSystem: BuildSystemProvider.Kind) async throws { - try await fixture(name: "Miscellaneous/Plugins/PluginUsingLocalAndRemoteTool") { path in - let (stdout, stderr) = try await executeSwiftPackage(path.appending("MyLibrary"), configuration: .debug, extraArgs: ["--build-system", buildSystem.rawValue, "plugin", "my-plugin"]) - if buildSystem == .native { - // Native build system is more explicit about what it's doing in stderr - #expect(stderr.contains("Linking RemoteTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Linking LocalTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Linking ImpliedLocalTool"), "stdout:\n\(stderr)\n\(stdout)") - #expect(stderr.contains("Build of product 'ImpliedLocalTool' complete!"), "stdout:\n\(stderr)\n\(stdout)") + try await withKnownIssue (isIntermittent: true) { + try await fixture(name: "Miscellaneous/Plugins/PluginUsingLocalAndRemoteTool") { path in + let (stdout, stderr) = try await executeSwiftPackage(path.appending("MyLibrary"), configuration: .debug, extraArgs: ["--build-system", buildSystem.rawValue, "plugin", "my-plugin"]) + if buildSystem == .native { + // Native build system is more explicit about what it's doing in stderr + #expect(stderr.contains("Linking RemoteTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Linking LocalTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Linking ImpliedLocalTool"), "stdout:\n\(stderr)\n\(stdout)") + #expect(stderr.contains("Build of product 'ImpliedLocalTool' complete!"), "stdout:\n\(stderr)\n\(stdout)") + } + #expect(stdout.contains("A message from the remote tool."), "stdout:\n\(stderr)\n\(stdout)") + #expect(stdout.contains("A message from the local tool."), "stdout:\n\(stderr)\n\(stdout)") + #expect(stdout.contains("A message from the implied local tool."), "stdout:\n\(stderr)\n\(stdout)") } - #expect(stdout.contains("A message from the remote tool."), "stdout:\n\(stderr)\n\(stdout)") - #expect(stdout.contains("A message from the local tool."), "stdout:\n\(stderr)\n\(stdout)") - #expect(stdout.contains("A message from the implied local tool."), "stdout:\n\(stderr)\n\(stdout)") + } when: { + ProcessInfo.hostOperatingSystem == .windows // Intermittent depending on the file path length } } From 0ee14e4bf6cbf6551cc4947d9a31d9496b86bf23 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 13:35:32 -0400 Subject: [PATCH 04/15] Check for dynamic targets using the same approach as the PIF builder Fix failing package command test --- Sources/SwiftBuildSupport/SwiftBuildSystem.swift | 4 ++-- Tests/CommandsTests/PackageCommandTests.swift | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index 75ae6601c8d..fe3c64c219d 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -316,8 +316,8 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { let workspaceInfo = try await session.workspaceInfo() configuredTargets = try [pifTargetName].map { targetName in - // TODO use an API to decide if this is a dynamic target info - let infos = workspaceInfo.targetInfos.filter { $0.targetName == targetName && !$0.guid.hasSuffix("-dynamic") } + // TODO we filter dynamic tarts until Swift Build doesn't give them to us anymore + let infos = workspaceInfo.targetInfos.filter { $0.targetName == targetName && !TargetSuffix.dynamic.hasSuffix(id: GUID($0.guid)) } switch infos.count { case 0: self.observabilityScope.emit(error: "Could not find target named '\(targetName)'") diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index d10f237b8ad..c8b2743e2aa 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2914,7 +2914,8 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, isEmpty) // Filter some unrelated output that could show up on stderr. let filteredStderr = stderr.components(separatedBy: "\n") - .filter { !$0.contains("Unable to locate libSwiftScan") }.joined(separator: "\n") + .filter { !$0.contains("Unable to locate libSwiftScan") } + .filter { !($0.contains("warning: ") && $0.contains("unable to find libclang")) }.joined(separator: "\n") XCTAssertMatch(filteredStderr, isEmpty) } @@ -2924,7 +2925,8 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, containsLogtext) // Filter some unrelated output that could show up on stderr. let filteredStderr = stderr.components(separatedBy: "\n") - .filter { !$0.contains("Unable to locate libSwiftScan") }.joined(separator: "\n") + .filter { !$0.contains("Unable to locate libSwiftScan") } + .filter { !($0.contains("warning: ") && $0.contains("unable to find libclang")) }.joined(separator: "\n") XCTAssertMatch(filteredStderr, isEmpty) } From c082371a312ee14c96e80c01147239c56c8fd8ff Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 16:03:27 -0400 Subject: [PATCH 05/15] Add testCommandBuildTestability test for increased coverage Skip testCommandPluginTargetBuilds on Linux due to bug building fixture in release mode Skip testCommandPluginSymbolGraphCallbacks until symbol graph callback is supported with swiftbuild --- .../SwiftBuildSupport/SwiftBuildSystem.swift | 11 ++++++---- Tests/CommandsTests/PackageCommandTests.swift | 22 ++++++++++++++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index fe3c64c219d..d725532fde9 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -434,10 +434,13 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { self.observabilityScope.emit(info: "\(String(decoding: info.data, as: UTF8.self))") case .taskStarted(let info): try buildState.started(task: info) - if let commandLineDisplay = info.commandLineDisplayString { - self.observabilityScope.emit(info: "\(info.executionDescription)\n\(commandLineDisplay)") - } else { - self.observabilityScope.emit(info: "\(info.executionDescription)") + + if self.logLevel.isVerbose { + if let commandLineDisplay = info.commandLineDisplayString { + self.outputStream.send("\(info.executionDescription)\n\(commandLineDisplay)") + } else { + self.outputStream.send("\(info.executionDescription)") + } } case .taskComplete(let info): let startedInfo = try buildState.completed(task: info) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index c8b2743e2aa..bd5e54673cc 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2802,8 +2802,16 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { // 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 debugTarget = [".build", "debug", executableName("placeholder")] - let releaseTarget = [".build", "release", executableName("placeholder")] + #if os(Linux) + let osSuffix = "-linux" + #else if os(Windows) + let ossSuffix = "-windows" + #else + let osSuffix = "" + #endif + + let debugTarget = self.buildSystemProvider == .native ? [".build", "debug", executableName("placeholder")] : [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "Products", "Debug\(osSuffix)", "placeholder"] + let releaseTarget = self.buildSystemProvider == .native ? [".build", "release", executableName("placeholder")] : [".build", try UserToolchain.default.targetTriple.platformBuildPathComponent, "Products", "Release\(osSuffix)", "placeholder"] func AssertIsExecutableFile(_ fixturePath: AbsolutePath, file: StaticString = #filePath, line: UInt = #line) { XCTAssert( @@ -2837,6 +2845,10 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { AssertNotExists(fixturePath.appending(components: releaseTarget)) } + if self.buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem == .linux { + throw XCTSkip("Failure to build the executable in release mode on Linux with the swiftbuild build system: https://github.com/swiftlang/swift-package-manager/issues/8855") + } + // 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 let _ = try await self.execute(["-c", "debug", "build-target", "build-release"], packagePath: fixturePath) @@ -4107,9 +4119,13 @@ class PackageCommandSwiftBuildTests: PackageCommandTestCase { override func testNoParameters() async throws { try await super.testNoParameters() } + + override func testCommandPluginSymbolGraphCallbacks() async throws { + throw XCTSkip("SWBINTTODO: Symbol graph extraction does not yet work with swiftbuild build system") + } override func testCommandPluginBuildTestability() async throws { - throw XCTSkip("SWBINTTODO: Test fails as plugins are not currenty supported") + try await super.testCommandPluginBuildTestability() } override func testMigrateCommand() async throws { From 2539d5f081971e70d30fe48edc62824d9ceb7634 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 16:04:24 -0400 Subject: [PATCH 06/15] Fix platform conditional --- Tests/CommandsTests/PackageCommandTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index bd5e54673cc..47b1d25ffed 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2804,7 +2804,7 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { #if os(Linux) let osSuffix = "-linux" - #else if os(Windows) + #elseif os(Windows) let ossSuffix = "-windows" #else let osSuffix = "" From ad872c09b45bade022d922ab0958b32692486fbe Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 20 Jun 2025 19:38:40 -0400 Subject: [PATCH 07/15] Re-add the emission of command line display strings to observability scope Skip test on autolink extract errors on non-macOS platforms --- Sources/SwiftBuildSupport/SwiftBuildSystem.swift | 6 ++++++ Tests/CommandsTests/PackageCommandTests.swift | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index d725532fde9..0f267352da1 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -435,6 +435,12 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { case .taskStarted(let info): try buildState.started(task: info) + if let commandLineDisplay = info.commandLineDisplayString { + self.observabilityScope.emit(info: "\(info.executionDescription)\n\(commandLineDisplay)") + } else { + self.observabilityScope.emit(info: "\(info.executionDescription)") + } + if self.logLevel.isVerbose { if let commandLineDisplay = info.commandLineDisplayString { self.outputStream.send("\(info.executionDescription)\n\(commandLineDisplay)") diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 47b1d25ffed..8869dcc35ed 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -3512,6 +3512,10 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("executable"))) + } catch { + if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { + throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + } } // Invoke the plugin with parameters choosing a verbose build of MyStaticLibrary for release. @@ -3533,6 +3537,10 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("staticLibrary"))) + } catch { + if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { + throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + } } // Invoke the plugin with parameters choosing a verbose build of MyDynamicLibrary for release. @@ -3558,6 +3566,10 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("dynamicLibrary"))) + } catch { + if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { + throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + } } } } From 427853863cc2c7405dc512b2444d8d86b26a5a85 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Mon, 23 Jun 2025 11:43:26 -0400 Subject: [PATCH 08/15] Skip tests that fail to build in release mode on Linux --- Tests/CommandsTests/PackageCommandTests.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 8869dcc35ed..eaa84f415b1 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2880,6 +2880,8 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } + if ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Build error building release artifacts with autolink-extract on non-macOS platforms: https://github.com/swiftlang/swift-build/issues/602") } + // Overall configuration: debug, plugin build request: release -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) From 95d57df8d3bb43b85513ab2f05b0c9c6e899cd25 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Mon, 23 Jun 2025 13:36:28 -0400 Subject: [PATCH 09/15] Fix compile error with Windows Fix todo comment spelling --- Sources/SwiftBuildSupport/SwiftBuildSystem.swift | 2 +- Tests/CommandsTests/PackageCommandTests.swift | 4 ++-- Tests/FunctionalTests/TraitTests.swift | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index 0f267352da1..dbffb77c473 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -316,7 +316,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { let workspaceInfo = try await session.workspaceInfo() configuredTargets = try [pifTargetName].map { targetName in - // TODO we filter dynamic tarts until Swift Build doesn't give them to us anymore + // TODO we filter dynamic targets until Swift Build doesn't give them to us anymore let infos = workspaceInfo.targetInfos.filter { $0.targetName == targetName && !TargetSuffix.dynamic.hasSuffix(id: GUID($0.guid)) } switch infos.count { case 0: diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index eaa84f415b1..314c77b4a8c 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2805,7 +2805,7 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { #if os(Linux) let osSuffix = "-linux" #elseif os(Windows) - let ossSuffix = "-windows" + let osSuffix = "-windows" #else let osSuffix = "" #endif @@ -2880,7 +2880,7 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } - if ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Build error building release artifacts with autolink-extract on non-macOS platforms: https://github.com/swiftlang/swift-build/issues/602") } + if buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Build error building release artifacts with autolink-extract on non-macOS platforms: https://github.com/swiftlang/swift-build/issues/602") } // Overall configuration: debug, plugin build request: release -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in diff --git a/Tests/FunctionalTests/TraitTests.swift b/Tests/FunctionalTests/TraitTests.swift index afdc0ec8796..61cfcd43bad 100644 --- a/Tests/FunctionalTests/TraitTests.swift +++ b/Tests/FunctionalTests/TraitTests.swift @@ -487,6 +487,7 @@ struct TraitTests { buildSystem: BuildSystemProvider.Kind, ) async throws { try await fixture(name: "Traits") { fixturePath in + // The swiftbuild build system doesn't yet have the ability for command plugins to request symbol graphs try await withKnownIssue { let (stdout, _) = try await executeSwiftPackage( fixturePath.appending("Package10"), From 3677b7888550b2a6b4eceeb2129dbde1b87743a1 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Mon, 23 Jun 2025 14:58:01 -0400 Subject: [PATCH 10/15] Switch test skips to new issue building release artifacts with Linux --- Tests/CommandsTests/PackageCommandTests.swift | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index 314c77b4a8c..c98d5dd5414 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2845,8 +2845,8 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { AssertNotExists(fixturePath.appending(components: releaseTarget)) } - if self.buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem == .linux { - throw XCTSkip("Failure to build the executable in release mode on Linux with the swiftbuild build system: https://github.com/swiftlang/swift-package-manager/issues/8855") + if self.buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { + throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } // If the plugin requests a release binary, that is what will be built, regardless of overall configuration @@ -2880,7 +2880,7 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } - if buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Build error building release artifacts with autolink-extract on non-macOS platforms: https://github.com/swiftlang/swift-build/issues/602") } + if buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } // Overall configuration: debug, plugin build request: release -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in @@ -3516,8 +3516,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("executable"))) } catch { if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } + throw error } // Invoke the plugin with parameters choosing a verbose build of MyStaticLibrary for release. @@ -3541,8 +3542,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("staticLibrary"))) } catch { if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } + throw error } // Invoke the plugin with parameters choosing a verbose build of MyDynamicLibrary for release. @@ -3570,8 +3572,9 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("dynamicLibrary"))) } catch { if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Autolink extract failure with Linux https://github.com/swiftlang/swift-package-manager/issues/8855") + throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } + throw error } } } From 2f1c8bad2743d3ff4ee42099c74352d0e695fbd1 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Tue, 24 Jun 2025 09:55:05 -0400 Subject: [PATCH 11/15] Skip the testCommandPluginBuildingCallbacks due to path issues in CI --- Tests/CommandsTests/PackageCommandTests.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index c98d5dd5414..e61b3d4dfc8 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -4140,6 +4140,11 @@ class PackageCommandSwiftBuildTests: PackageCommandTestCase { override func testCommandPluginSymbolGraphCallbacks() async throws { throw XCTSkip("SWBINTTODO: Symbol graph extraction does not yet work with swiftbuild build system") } + + override func testCommandPluginBuildingCallbacks() async throws { + try XCTSkipOnWindows(because: "TSCBasic/Path.swift:969: Assertion failed, https://github.com/swiftlang/swift-package-manager/issues/8602") + try await super.testCommandPluginBuildingCallbacks() + } override func testCommandPluginBuildTestability() async throws { try await super.testCommandPluginBuildTestability() From 0b009b6dbdebc41cc569102ae812f391cd632823 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Tue, 24 Jun 2025 11:14:46 -0400 Subject: [PATCH 12/15] Tidy up --- Tests/CommandsTests/PackageCommandTests.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index e61b3d4dfc8..d57c971174d 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -4145,10 +4145,6 @@ class PackageCommandSwiftBuildTests: PackageCommandTestCase { try XCTSkipOnWindows(because: "TSCBasic/Path.swift:969: Assertion failed, https://github.com/swiftlang/swift-package-manager/issues/8602") try await super.testCommandPluginBuildingCallbacks() } - - override func testCommandPluginBuildTestability() async throws { - try await super.testCommandPluginBuildTestability() - } override func testMigrateCommand() async throws { throw XCTSkip("SWBINTTODO: Build plan is not currently supported") From ea88c638d088506643bdde7c4377ba50aa819ab8 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Wed, 25 Jun 2025 14:58:02 -0400 Subject: [PATCH 13/15] Fix CI failures --- Tests/CommandsTests/BuildCommandTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/CommandsTests/BuildCommandTests.swift b/Tests/CommandsTests/BuildCommandTests.swift index a9fa3e390bc..644b9ad7abf 100644 --- a/Tests/CommandsTests/BuildCommandTests.swift +++ b/Tests/CommandsTests/BuildCommandTests.swift @@ -910,7 +910,7 @@ struct BuildCommandTestCases { } } } when: { - ProcessInfo.hostOperatingSystem != .macOS && buildSystem == .swiftbuild + ProcessInfo.hostOperatingSystem == .windows && buildSystem == .swiftbuild } } @@ -1008,7 +1008,7 @@ struct BuildCommandTestCases { func getTaskAllowEntitlement( buildSystem: BuildSystemProvider.Kind, ) async throws { - try await withKnownIssue { + try await withKnownIssue (isIntermittent: true) { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in #if os(macOS) // try await building with default parameters. This should succeed. We build verbosely so we get full command @@ -1094,7 +1094,7 @@ struct BuildCommandTestCases { #expect(!buildResult.stdout.contains("codesign --force --sign - --entitlements")) } } when: { - [.swiftbuild, .xcode].contains(buildSystem) + [.swiftbuild, .xcode].contains(buildSystem) && ProcessInfo.hostOperatingSystem != .linux } } From 449e87bb2bc98cf19f8b08d690ef207fd07d1d9c Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Wed, 25 Jun 2025 15:03:58 -0400 Subject: [PATCH 14/15] Remove intermittent flag --- Tests/CommandsTests/BuildCommandTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/CommandsTests/BuildCommandTests.swift b/Tests/CommandsTests/BuildCommandTests.swift index 644b9ad7abf..3baccf81974 100644 --- a/Tests/CommandsTests/BuildCommandTests.swift +++ b/Tests/CommandsTests/BuildCommandTests.swift @@ -1008,7 +1008,7 @@ struct BuildCommandTestCases { func getTaskAllowEntitlement( buildSystem: BuildSystemProvider.Kind, ) async throws { - try await withKnownIssue (isIntermittent: true) { + try await withKnownIssue { try await fixture(name: "ValidLayouts/SingleModule/ExecutableNew") { fixturePath in #if os(macOS) // try await building with default parameters. This should succeed. We build verbosely so we get full command From 1b7a6e7790ac8edb11a7208fd392ce791efe3652 Mon Sep 17 00:00:00 2001 From: Chris McGee Date: Fri, 27 Jun 2025 09:01:00 -0400 Subject: [PATCH 15/15] Unskip swiftbuild tests that previously failed due to missing dsymutil --- Tests/CommandsTests/PackageCommandTests.swift | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/Tests/CommandsTests/PackageCommandTests.swift b/Tests/CommandsTests/PackageCommandTests.swift index d57c971174d..3b96873e169 100644 --- a/Tests/CommandsTests/PackageCommandTests.swift +++ b/Tests/CommandsTests/PackageCommandTests.swift @@ -2845,10 +2845,6 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { AssertNotExists(fixturePath.appending(components: releaseTarget)) } - if self.buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { - throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") - } - // 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 let _ = try await self.execute(["-c", "debug", "build-target", "build-release"], packagePath: fixturePath) @@ -2880,8 +2876,6 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "debug", "true"], packagePath: fixturePath)) } - if buildSystemProvider == .swiftbuild && ProcessInfo.hostOperatingSystem != .macOS { throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") } - // Overall configuration: debug, plugin build request: release -> without testability try await fixture(name: "Miscellaneous/Plugins/CommandPluginTestStub") { fixturePath in await XCTAssertAsyncNoThrow(try await self.execute(["-c", "debug", "check-testability", "InternalModule", "release", "false"], packagePath: fixturePath)) @@ -3514,11 +3508,6 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("executable"))) - } catch { - if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") - } - throw error } // Invoke the plugin with parameters choosing a verbose build of MyStaticLibrary for release. @@ -3540,11 +3529,6 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("staticLibrary"))) - } catch { - if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") - } - throw error } // Invoke the plugin with parameters choosing a verbose build of MyDynamicLibrary for release. @@ -3570,11 +3554,6 @@ class PackageCommandTestCase: CommandsBuildProviderTestCase { XCTFail("unimplemented assertion for --build-system xcode") } XCTAssertMatch(stdout, .and(.contains("artifact-kind:"), .contains("dynamicLibrary"))) - } catch { - if ProcessInfo.hostOperatingSystem != .macOS && self.buildSystemProvider == .swiftbuild { - throw XCTSkip("Failed to find dsymutil tool: https://github.com/swiftlang/swift-package-manager/issues/8862") - } - throw error } } }