Skip to content

Commit e3b6e5d

Browse files
authored
Plugin import scanner isn't passing in the library directory (#6323)
The Workspace type has a facility for scanning package plugins for imports. But since it's not passing in the actual plugin directory provided by the caller (whether it's SwiftPM or Xcode), any modules provided by an IDE aren't picked up if they are guarded by `#if canImport()`. This includes `XcodeProjectPlugin`, which is one of the additional plugin modules provided by Xcode. The same would be true for other IDEs. Changes: - `Workspace.loadPluginImports` now also passes the path of the plugin directory to the import scanning - extended the `testScanImportsInPluginTargets` unit test to check for this case rdar://106387043
1 parent 877ea26 commit e3b6e5d

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

Sources/Workspace/Workspace.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ extension Workspace {
12931293
packageGraph: PackageGraph,
12941294
completion: @escaping(Result<[PackageIdentity: [String: [String]]], Error>) -> Void) {
12951295
let pluginTargets = packageGraph.allTargets.filter{$0.type == .plugin}
1296-
let scanner = SwiftcImportScanner(swiftCompilerEnvironment: hostToolchain.swiftCompilerEnvironment, swiftCompilerFlags: hostToolchain.swiftCompilerFlags, swiftCompilerPath: hostToolchain.swiftCompilerPath)
1296+
let scanner = SwiftcImportScanner(swiftCompilerEnvironment: hostToolchain.swiftCompilerEnvironment, swiftCompilerFlags: hostToolchain.swiftCompilerFlags + ["-I", hostToolchain.swiftPMLibrariesLocation.pluginLibraryPath.pathString], swiftCompilerPath: hostToolchain.swiftCompilerPath)
12971297
var importList = [PackageIdentity: [String: [String]]]()
12981298

12991299
for pluginTarget in pluginTargets {

Tests/SPMBuildCoreTests/PluginInvocationTests.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,19 +1011,30 @@ class PluginInvocationTests: XCTestCase {
10111011
try localFileSystem.writeFileContents(qPluginTargetDir.appending("plugin.swift"), string: """
10121012
import PackagePlugin
10131013
import XcodeProjectPlugin
1014+
#if canImport(ModuleFoundViaExtraSearchPaths)
1015+
import ModuleFoundViaExtraSearchPaths
1016+
#endif
10141017
@main struct QBuildToolPlugin: BuildToolPlugin {
10151018
func createBuildCommands(
10161019
context: PluginContext,
10171020
target: Target
10181021
) throws -> [Command] { }
10191022
}
10201023
""")
1024+
1025+
// Create something that looks like another module that can be detected via `canImport()`.
1026+
let fakeExtraModulesDir = tmpPath.appending("ExtraModules")
1027+
try localFileSystem.createDirectory(fakeExtraModulesDir, recursive: true)
1028+
let fakeExtraModuleFile = fakeExtraModulesDir.appending("ModuleFoundViaExtraSearchPaths.swiftmodule")
1029+
try localFileSystem.writeFileContents(fakeExtraModuleFile, string: "")
1030+
10211031
/////////
10221032
// Load a workspace from the package.
10231033
let observability = ObservabilitySystem.makeForTesting()
10241034
let workspace = try Workspace(
10251035
fileSystem: localFileSystem,
1026-
forRootPackage: packageDir,
1036+
location: try Workspace.Location(forRootPackage: packageDir, fileSystem: localFileSystem),
1037+
customHostToolchain: UserToolchain(destination: .hostDestination(), customLibrariesLocation: .init(manifestLibraryPath: fakeExtraModulesDir, pluginLibraryPath: fakeExtraModulesDir)),
10271038
customManifestLoader: ManifestLoader(toolchain: UserToolchain.default),
10281039
delegate: MockWorkspaceDelegate()
10291040
)
@@ -1060,8 +1071,8 @@ class PluginInvocationTests: XCTestCase {
10601071
} else if pkg.description == "otherpackage" {
10611072
XCTAssertNotNil(dict[pkg]?["QPlugin"])
10621073

1063-
let possibleImports1 = ["PackagePlugin", "XcodeProjectPlugin"]
1064-
let possibleImports2 = ["PackagePlugin", "XcodeProjectPlugin", "_SwiftConcurrencyShims"]
1074+
let possibleImports1 = ["PackagePlugin", "XcodeProjectPlugin", "ModuleFoundViaExtraSearchPaths"]
1075+
let possibleImports2 = ["PackagePlugin", "XcodeProjectPlugin", "ModuleFoundViaExtraSearchPaths", "_SwiftConcurrencyShims"]
10651076
XCTAssertTrue(entry["QPlugin"] == possibleImports1 ||
10661077
entry["QPlugin"] == possibleImports2)
10671078
count += 1

0 commit comments

Comments
 (0)