From e01f41fd504f4bb221cb66ae4b6dabe7e1a79a48 Mon Sep 17 00:00:00 2001 From: Aki <75532970+AkiSakurai@users.noreply.github.com> Date: Mon, 7 Jul 2025 22:31:41 +0800 Subject: [PATCH] Include out-of-target sources --- .../PackageLoading/TargetSourcesBuilder.swift | 27 ++++++++++++++++--- .../PackageBuilderTests.swift | 27 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/Sources/PackageLoading/TargetSourcesBuilder.swift b/Sources/PackageLoading/TargetSourcesBuilder.swift index 17f36fb2cbe..0d3c82fa80b 100644 --- a/Sources/PackageLoading/TargetSourcesBuilder.swift +++ b/Sources/PackageLoading/TargetSourcesBuilder.swift @@ -199,8 +199,23 @@ public struct TargetSourcesBuilder { additionalResources = [] } - let headers = pathToRule.lazy.filter { $0.value == .header }.map { $0.key }.sorted() - let compilePaths = pathToRule.lazy.filter { $0.value == .compile }.map { $0.key } + var additionalSources: [Basics.AbsolutePath] = [] + var additionalHeaders: [Basics.AbsolutePath] = [] + if self.toolsVersion >= .vNext { + if let declaredSources = self.declaredSources { + let unhandledSources = self.computeContents(for: declaredSources.filter { !$0.isDescendant(of: self.targetPath) }) + for source in unhandledSources { + if let ext = source.extension, FileRuleDescription.header.fileTypes.contains(ext) { + additionalHeaders.append(source) + } else { + additionalSources.append(source) + } + } + } + } + + let headers = (pathToRule.lazy.filter { $0.value == .header }.map { $0.key } + additionalHeaders).sorted() + let compilePaths = (pathToRule.lazy.filter { $0.value == .compile }.map { $0.key } + additionalSources) let sources = Sources(paths: Array(compilePaths).sorted(), root: targetPath) let resources: [Resource] = (pathToRule.compactMap { resource(for: $0.key, with: $0.value) } + additionalResources).sorted { a, b in a.path.pathString < b.path.pathString @@ -415,9 +430,9 @@ public struct TargetSourcesBuilder { /// /// This avoids recursing into certain directories like exclude or the /// ones that should be copied as-is. - public func computeContents() -> [Basics.AbsolutePath] { + public func computeContents(for paths: [Basics.AbsolutePath]) -> [Basics.AbsolutePath] { var contents: [Basics.AbsolutePath] = [] - var queue: [Basics.AbsolutePath] = [targetPath] + var queue: [Basics.AbsolutePath] = paths // Ignore xcodeproj and playground directories. var ignoredDirectoryExtensions = ["xcodeproj", "playground", "xcworkspace"] @@ -519,6 +534,10 @@ public struct TargetSourcesBuilder { return contents } + public func computeContents() -> [Basics.AbsolutePath] { + self.computeContents(for: [self.targetPath]) + } + public static func computeContents(for generatedFiles: [Basics.AbsolutePath], toolsVersion: ToolsVersion, additionalFileRules: [FileRuleDescription], defaultLocalization: String?, targetName: String, targetPath: Basics.AbsolutePath, observabilityScope: ObservabilityScope) -> (sources: [Basics.AbsolutePath], resources: [Resource]) { var sources = [Basics.AbsolutePath]() var resources = [Resource]() diff --git a/Tests/PackageLoadingTests/PackageBuilderTests.swift b/Tests/PackageLoadingTests/PackageBuilderTests.swift index a00ad7eeeb2..ffc0cfe641b 100644 --- a/Tests/PackageLoadingTests/PackageBuilderTests.swift +++ b/Tests/PackageLoadingTests/PackageBuilderTests.swift @@ -3477,6 +3477,33 @@ final class PackageBuilderTests: XCTestCase { } } } + + func testOutOfTargetSource() throws { + let fs = InMemoryFileSystem( + emptyFiles: + "/Sources/foo/foo.swift", + "/Sources/foo/foobar/foobar.swift", + + "/Sources/bar/bar.swift" + ) + + let manifest = try Manifest.createRootManifest( + displayName: "pkg", + toolsVersion: .vNext, + targets: [ + TargetDescription( + name: "foo", + sources: ["../bar/bar.swift", "foobar"] + ), + ] + ) + + PackageBuilderTester(manifest, in: fs) { package, _ in + package.checkModule("foo") { module in + module.checkSources(sources: ["foobar/foobar.swift","../bar/bar.swift"]) + } + } + } } final class PackageBuilderTester {