Skip to content

Commit dd6335f

Browse files
committed
[PackageLoading] Better handling for directories with extension
Package builder started considering directories inside a target as a file that can have a rule. However, this wasn't gated behind the tools version check and we were not handling directories that are explicitly declared as sources in the package manifest. <rdar://problem/59243977>
1 parent 41fa2d3 commit dd6335f

File tree

3 files changed

+100
-3
lines changed

3 files changed

+100
-3
lines changed

Sources/PackageLoading/TargetSourcesBuilder.swift

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ public struct TargetSourcesBuilder {
221221
}
222222
}
223223

224+
/// Returns true if the given path is a declared source.
225+
func isDeclaredSource(_ path: AbsolutePath) -> Bool {
226+
return path == targetPath || declaredSources?.contains(path) == true
227+
}
228+
224229
/// Compute the contents of the files in a target.
225230
///
226231
/// This avoids recursing into certain directories like exclude or the
@@ -258,14 +263,22 @@ public struct TargetSourcesBuilder {
258263
continue
259264
}
260265

261-
// Append and continue if the path doesn't have an extension or is not a directory.
262-
if curr.extension != nil || !fs.isDirectory(curr) {
266+
// Consider non-directories as source files.
267+
if !fs.isDirectory(curr) {
263268
contents.append(curr)
264269
continue
265270
}
266271

267272
// At this point, curr can only be a directory.
268273
//
274+
// Starting tools version with resources, pick directories as
275+
// sources that have an extension but are not explicitly
276+
// declared as sources in the manifest.
277+
if toolsVersion >= .vNext && curr.extension != nil && !isDeclaredSource(curr) {
278+
contents.append(curr)
279+
continue
280+
}
281+
269282
// Check if the directory is marked to be copied.
270283
let directoryMarkedToBeCopied = target.resources.contains{ resource in
271284
let resourcePath = self.targetPath.appending(RelativePath(resource.path))

Tests/PackageLoadingTests/PackageBuilderTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,53 @@ class PackageBuilderTests: XCTestCase {
246246
}
247247
}
248248

249+
func testDeclaredSourcesWithDot() throws {
250+
let fs = InMemoryFileSystem(emptyFiles:
251+
"/Sources/swift.lib/foo.swift",
252+
"/Sources/swiftlib1/swift.lib/foo.swift",
253+
"/Sources/swiftlib2/swift.lib/foo.swift",
254+
"/Sources/swiftlib3/swift.lib/foo.swift",
255+
"/Sources/swiftlib3/swift.lib/foo.bar/bar.swift",
256+
"/done"
257+
)
258+
259+
let manifest = Manifest.createV4Manifest(
260+
name: "MyPackage",
261+
targets: [
262+
TargetDescription(
263+
name: "swift.lib"
264+
),
265+
TargetDescription(
266+
name: "swiftlib1",
267+
path: "Sources/swiftlib1",
268+
sources: ["swift.lib"]
269+
),
270+
TargetDescription(
271+
name: "swiftlib2",
272+
path: "Sources/swiftlib2/swift.lib"
273+
),
274+
TargetDescription(
275+
name: "swiftlib3",
276+
path: "Sources/swiftlib3/swift.lib"
277+
),
278+
]
279+
)
280+
PackageBuilderTester(manifest, in: fs) { result, _ in
281+
result.checkModule("swift.lib") { module in
282+
module.checkSources(sources: ["foo.swift"])
283+
}
284+
result.checkModule("swiftlib1") { module in
285+
module.checkSources(sources: ["swift.lib/foo.swift"])
286+
}
287+
result.checkModule("swiftlib2") { module in
288+
module.checkSources(sources: ["foo.swift"])
289+
}
290+
result.checkModule("swiftlib3") { module in
291+
module.checkSources(sources: ["foo.bar/bar.swift", "foo.swift"])
292+
}
293+
}
294+
}
295+
249296
func testDeclaredExecutableProducts() {
250297
// Check that declaring executable product doesn't collide with the
251298
// inferred products.

Tests/PackageLoadingTests/TargetSourcesBuilderTests.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class TargetSourcesBuilderTests: XCTestCase {
6060
XCTAssertEqual(contents, [
6161
"/Bar.swift",
6262
"/Foo.swift",
63-
"/Hello.something",
63+
"/Hello.something/hello.txt",
6464
"/file",
6565
"/path/to/somefile.txt",
6666
"/some/path.swift",
@@ -70,6 +70,43 @@ class TargetSourcesBuilderTests: XCTestCase {
7070
XCTAssertNoDiagnostics(diags)
7171
}
7272

73+
func testDirectoryWithExt() throws {
74+
let target = TargetDescription(
75+
name: "Foo",
76+
path: nil,
77+
exclude: ["some2"],
78+
sources: nil,
79+
publicHeadersPath: nil,
80+
type: .regular
81+
)
82+
83+
let fs = InMemoryFileSystem()
84+
fs.createEmptyFiles(at: .root, files: [
85+
"/.some2/hello.swift",
86+
"/Hello.something/hello.txt",
87+
])
88+
89+
let diags = DiagnosticsEngine()
90+
91+
let builder = TargetSourcesBuilder(
92+
packageName: "",
93+
packagePath: .root,
94+
target: target,
95+
path: .root,
96+
toolsVersion: .vNext,
97+
fs: fs,
98+
diags: diags
99+
)
100+
101+
let contents = builder.computeContents().map{ $0.pathString }.sorted()
102+
103+
XCTAssertEqual(contents, [
104+
"/Hello.something",
105+
])
106+
107+
XCTAssertNoDiagnostics(diags)
108+
}
109+
73110
func testBasicRuleApplication() throws {
74111
let target = TargetDescription(
75112
name: "Foo",

0 commit comments

Comments
 (0)