Skip to content

Commit 8001413

Browse files
authored
rdar://101564030 (PackageGraph.computeTestTargetsForExecutableTargets() incorrectly returns test mappings for plugin usage targets) (#5841)
A target's use of a plugin is represented as a kind of dependency, but this should not influence the test association. Otherwise every test that depends on a library that uses a plugin seems to be associated with every other target that uses the plugin.
1 parent db9a253 commit 8001413

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

Sources/PackageGraph/PackageGraph.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,15 @@ public struct PackageGraph {
188188
// Create map of test target to set of its direct dependencies.
189189
let testTargetDepMap: [ResolvedTarget: Set<ResolvedTarget>] = try {
190190
let testTargetDeps = rootTargets.filter({ $0.type == .test }).map({
191-
($0, Set($0.dependencies.compactMap({ $0.target })))
191+
($0, Set($0.dependencies.compactMap{ $0.target }.filter{ $0.type != .plugin }))
192192
})
193193
return try Dictionary(throwingUniqueKeysWithValues: testTargetDeps)
194194
}()
195195

196196
for target in rootTargets where target.type == .executable {
197-
// Find all dependencies of this target within its package.
197+
// Find all dependencies of this target within its package. Note that we do not traverse plugin usages.
198198
let dependencies = try topologicalSort(target.dependencies, successors: {
199-
$0.dependencies.compactMap { $0.target }.map { .target($0, conditions: []) }
199+
$0.dependencies.compactMap{ $0.target }.filter{ $0.type != .plugin }.map{ .target($0, conditions: []) }
200200
}).compactMap({ $0.target })
201201

202202
// Include the test targets whose dependencies intersect with the

Tests/FunctionalTests/PluginTests.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,42 @@ class PluginTests: XCTestCase {
509509
}
510510
}
511511

512+
func testPluginUsageDoesntAffectTestTargetMappings() throws {
513+
try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency")
514+
515+
try fixture(name: "Miscellaneous/Plugins/MySourceGenPlugin") { packageDir in
516+
// Load a workspace from the package.
517+
let observability = ObservabilitySystem.makeForTesting()
518+
let workspace = try Workspace(
519+
fileSystem: localFileSystem,
520+
forRootPackage: packageDir,
521+
customManifestLoader: ManifestLoader(toolchain: UserToolchain.default),
522+
delegate: MockWorkspaceDelegate()
523+
)
524+
525+
// Load the root manifest.
526+
let rootInput = PackageGraphRootInput(packages: [packageDir], dependencies: [])
527+
let rootManifests = try tsc_await {
528+
workspace.loadRootManifests(
529+
packages: rootInput.packages,
530+
observabilityScope: observability.topScope,
531+
completion: $0
532+
)
533+
}
534+
XCTAssert(rootManifests.count == 1, "\(rootManifests)")
535+
536+
// Load the package graph.
537+
let packageGraph = try workspace.loadPackageGraph(rootInput: rootInput, observabilityScope: observability.topScope)
538+
XCTAssertNoDiagnostics(observability.diagnostics)
539+
540+
// Make sure that the use of plugins doesn't bleed into the use of plugins by tools.
541+
let testTargetMappings = try packageGraph.computeTestTargetsForExecutableTargets()
542+
for (target, testTargets) in testTargetMappings {
543+
XCTAssertFalse(testTargets.contains{ $0.name == "MySourceGenPluginTests" }, "target: \(target), testTargets: \(testTargets)")
544+
}
545+
}
546+
}
547+
512548
func testCommandPluginCancellation() throws {
513549
// Only run the test if the environment in which we're running actually supports Swift concurrency (which the plugin APIs require).
514550
try XCTSkipIf(!UserToolchain.default.supportsSwiftConcurrency(), "skipping because test environment doesn't support concurrency")

0 commit comments

Comments
 (0)