Skip to content

Commit 7c2828b

Browse files
committed
[PackageBuilder] Fix test target ref in manifest for external packages
This was caused due to test targets not being constructed when a package acts as a dependency. <rdar://problem/28038874> SR-2353: Test dependencies block a package for being used downstream
1 parent 68fea29 commit 7c2828b

File tree

5 files changed

+99
-13
lines changed

5 files changed

+99
-13
lines changed

Sources/PackageGraph/PackageGraphLoader.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public struct PackageGraphLoader {
4949
public init() { }
5050

5151
/// Load the package graph for the given package path.
52-
public func load(rootManifest: Manifest, externalManifests: [Manifest]) throws -> PackageGraph {
52+
public func load(rootManifest: Manifest, externalManifests: [Manifest], fileSystem: FileSystem = localFileSystem) throws -> PackageGraph {
5353
let allManifests = externalManifests + [rootManifest]
5454

5555
// Create the packages and convert to modules.
@@ -68,7 +68,7 @@ public struct PackageGraphLoader {
6868
// FIXME: We should always load the tests, but just change which
6969
// tests we build based on higher-level logic. This would make it
7070
// easier to allow testing of external package tests.
71-
let builder = PackageBuilder(manifest: manifest, path: packagePath)
71+
let builder = PackageBuilder(manifest: manifest, path: packagePath, fileSystem: fileSystem)
7272
let package = try builder.construct(includingTestModules: isRootPackage)
7373
packages.append(package)
7474

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,11 @@ public struct PackageBuilder {
208208
/// - includingTestModules: Whether the package's test modules should be loaded.
209209
public func construct(includingTestModules: Bool) throws -> Package {
210210
let modules = try constructModules()
211-
let testModules: [Module]
212-
if includingTestModules {
213-
testModules = try constructTestModules(modules: modules)
214-
} else {
215-
testModules = []
216-
}
211+
let testModules = try constructTestModules(modules: modules)
217212
try fillDependencies(modules: modules + testModules)
218-
let products = try constructProducts(modules, testModules: testModules)
219-
return Package(manifest: manifest, path: packagePath, modules: modules, testModules: testModules, products: products)
213+
// FIXME: Lift includingTestModules into a higher module.
214+
let products = try constructProducts(modules, testModules: includingTestModules ? testModules : [])
215+
return Package(manifest: manifest, path: packagePath, modules: modules, testModules: includingTestModules ? testModules : [], products: products)
220216
}
221217

222218
// MARK: Utility Predicates

Tests/PackageGraphTests/PackageGraphTests.swift

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,104 @@
1010

1111
import XCTest
1212

13+
import Basic
1314
import PackageGraph
15+
import PackageDescription
16+
import PackageLoading
17+
import PackageModel
18+
19+
private let v1: Version = "1.0.0"
1420

1521
class PackageGraphTests: XCTestCase {
16-
func testBasics() {
17-
// Implement.
22+
23+
func testBasic() throws {
24+
let fs = InMemoryFileSystem(emptyFiles:
25+
"/Foo/source.swift",
26+
"/Foo/Tests/FooTests/source.swift",
27+
"/Bar/source.swift",
28+
"/Bar/Tests/BarTests/source.swift"
29+
)
30+
31+
let g = try loadMockPackageGraph([
32+
"/Foo": Package(name: "Foo"),
33+
"/Bar": Package(name: "Bar", dependencies: [.Package(url: "/Foo", majorVersion: 1)]),
34+
], root: "/Bar", in: fs)
35+
36+
PackageGraphTester(g) { result in
37+
result.check(packages: "Bar", "Foo")
38+
result.check(modules: "Bar", "Foo")
39+
result.check(testModules: "BarTests")
40+
}
41+
}
42+
43+
// Make sure there is no error when we reference Test targets in a package and then
44+
// use it as a dependency to another package. SR-2353
45+
func testTestTargetDeclInExternalPackage() throws {
46+
let fs = InMemoryFileSystem(emptyFiles:
47+
"/Foo/source.swift",
48+
"/Foo/Tests/SomeTests/source.swift",
49+
"/Bar/source.swift",
50+
"/Bar/Tests/BarTests/source.swift"
51+
)
52+
53+
let g = try loadMockPackageGraph([
54+
"/Foo": Package(name: "Foo", targets: [Target(name: "SomeTests", dependencies: ["Foo"])]),
55+
"/Bar": Package(name: "Bar", dependencies: [.Package(url: "/Foo", majorVersion: 1)]),
56+
], root: "/Bar", in: fs)
57+
58+
PackageGraphTester(g) { result in
59+
result.check(packages: "Bar", "Foo")
60+
result.check(modules: "Bar", "Foo")
61+
result.check(testModules: "BarTests")
62+
}
1863
}
1964

2065
static var allTests = [
21-
("testBasics", testBasics),
66+
("testBasic", testBasic),
67+
("testTestTargetDeclInExternalPackage", testTestTargetDeclInExternalPackage),
2268
]
2369
}
70+
71+
private func PackageGraphTester(_ graph: PackageGraph, _ result: (PackageGraphResult) -> Void) {
72+
result(PackageGraphResult(graph))
73+
}
74+
75+
private class PackageGraphResult {
76+
let graph: PackageGraph
77+
78+
init(_ graph: PackageGraph) {
79+
self.graph = graph
80+
}
81+
82+
func check(packages: String..., file: StaticString = #file, line: UInt = #line) {
83+
XCTAssertEqual(graph.packages.map {$0.name}, packages, file: file, line: line)
84+
}
85+
86+
func check(modules: String..., file: StaticString = #file, line: UInt = #line) {
87+
XCTAssertEqual(graph.packages.flatMap {$0.modules.map {$0.name} }, modules, file: file, line: line)
88+
}
89+
90+
func check(testModules: String..., file: StaticString = #file, line: UInt = #line) {
91+
XCTAssertEqual(graph.packages.flatMap {$0.testModules.map {$0.name} }, testModules, file: file, line: line)
92+
}
93+
}
94+
95+
private func loadMockPackageGraph(_ packageMap: [String: PackageDescription.Package], root: String, in fs: FileSystem) throws -> PackageGraph {
96+
var externalManifests = [Manifest]()
97+
var rootManifest: Manifest!
98+
for (url, package) in packageMap {
99+
let manifest = Manifest(
100+
path: AbsolutePath(url).appending(component: Manifest.filename),
101+
url: url,
102+
package: package,
103+
products: [],
104+
version: v1
105+
)
106+
if url == root {
107+
rootManifest = manifest
108+
} else {
109+
externalManifests.append(manifest)
110+
}
111+
}
112+
return try PackageGraphLoader().load(rootManifest: rootManifest, externalManifests: externalManifests, fileSystem: fs)
113+
}

0 commit comments

Comments
 (0)