diff --git a/Sources/XCRemoteCache/Commands/Plugins/Thinning/SwiftProductsArchitecturesRecognizer.swift b/Sources/XCRemoteCache/Commands/Plugins/Thinning/SwiftProductsArchitecturesRecognizer.swift index 1c9cf6b..bb2afb0 100644 --- a/Sources/XCRemoteCache/Commands/Plugins/Thinning/SwiftProductsArchitecturesRecognizer.swift +++ b/Sources/XCRemoteCache/Commands/Plugins/Thinning/SwiftProductsArchitecturesRecognizer.swift @@ -44,7 +44,10 @@ class DefaultSwiftProductsArchitecturesRecognizer: SwiftProductsArchitecturesRec let moduleDirectory = builtProductsDir .appendingPathComponent(moduleName) .appendingPathExtension(Self.SwiftmoduleDirExtension) - let productFiles = try dirAccessor.items(at: moduleDirectory) + // Skip folders (e.g. 'Project' dir that stores .sourceinfo, introduced in Xcode13) + let productFiles = try dirAccessor.items(at: moduleDirectory).filter { url in + try dirAccessor.itemType(atPath: url.path) == .file + } /// files in a moduleDirectory have basename corresponding to the /// architecture (e.g. 'x86_64-apple-ios-simulator.swiftmodule', 'x86_64.swiftmodule' ...) let architectures = productFiles.map { file -> String in @@ -55,7 +58,7 @@ class DefaultSwiftProductsArchitecturesRecognizer: SwiftProductsArchitecturesRec } return basenameFile.lastPathComponent } - // remove duplicates comming from files with different extensions (swiftmodule, swiftdoc etc.) + // remove duplicates coming from files with different extensions (swiftmodule, swiftdoc etc.) return Set(architectures).sorted() } } diff --git a/Sources/XCRemoteCache/Commands/Swiftc/SwiftcProductsGenerator.swift b/Sources/XCRemoteCache/Commands/Swiftc/SwiftcProductsGenerator.swift index fc86947..ae728bf 100644 --- a/Sources/XCRemoteCache/Commands/Swiftc/SwiftcProductsGenerator.swift +++ b/Sources/XCRemoteCache/Commands/Swiftc/SwiftcProductsGenerator.swift @@ -50,11 +50,22 @@ class DiskSwiftcProductsGenerator: SwiftcProductsGenerator { ) { self.modulePathOutput = modulePathOutput let modulePathBasename = modulePathOutput.deletingPathExtension() + let modulePathDir = modulePathOutput.deletingLastPathComponent() + let moduleName = modulePathBasename.lastPathComponent // all swiftmodule-related should be located next to the ".swiftmodule" + // except of '.swiftsourceinfo', which should be placed in 'Project' dir destinationSwiftmodulePaths = Dictionary( uniqueKeysWithValues: SwiftmoduleFileExtension.SwiftmoduleExtensions .map { ext, _ in - (ext, modulePathBasename.appendingPathExtension(ext.rawValue)) + switch (ext) { + case .swiftsourceinfo: + let dest = modulePathDir.appendingPathComponent("Project") + .appendingPathComponent(moduleName) + .appendingPathExtension(ext.rawValue) + return (ext, dest) + default: + return (ext, modulePathBasename.appendingPathExtension(ext.rawValue)) + } } ) self.objcHeaderOutput = objcHeaderOutput diff --git a/Tests/XCRemoteCacheTests/Commands/MirroredLinkingSwiftcProductsGeneratorTests.swift b/Tests/XCRemoteCacheTests/Commands/MirroredLinkingSwiftcProductsGeneratorTests.swift index 3aac0f4..5ab2147 100644 --- a/Tests/XCRemoteCacheTests/Commands/MirroredLinkingSwiftcProductsGeneratorTests.swift +++ b/Tests/XCRemoteCacheTests/Commands/MirroredLinkingSwiftcProductsGeneratorTests.swift @@ -66,7 +66,7 @@ class MirroredLinkingSwiftcProductsGeneratorTests: FileXCTestCase { XCTAssertEqual(fileManager.contents(atPath: expectedHeaderFile.path), "header".data(using: .utf8)) } - func testLinksSwiftSourceInfoToLocationDir() throws { + func testLinksSwiftSourceInfoToProductsDir() throws { let workingDir = try prepareTempDir() let moduleFile = try fileManager.spt_createFile( workingDir.appendingPathComponent("MyModule.swiftmodule"), @@ -93,6 +93,7 @@ class MirroredLinkingSwiftcProductsGeneratorTests: FileXCTestCase { let headersDir = workingDir.appendingPathComponent("headers") let expectedSwiftSourceInfoFile = buildDir .appendingPathComponent("MyModule.swiftmodule") + .appendingPathComponent("Project") .appendingPathComponent("arm64.swiftsourceinfo") let generator = MirroredLinkingSwiftcProductsGenerator( arch: "arm64", diff --git a/Tests/XCRemoteCacheTests/Commands/Plugins/Thinning/DefaultSwiftProductsArchitecturesRecognizerTests.swift b/Tests/XCRemoteCacheTests/Commands/Plugins/Thinning/DefaultSwiftProductsArchitecturesRecognizerTests.swift index f1bc341..5626166 100644 --- a/Tests/XCRemoteCacheTests/Commands/Plugins/Thinning/DefaultSwiftProductsArchitecturesRecognizerTests.swift +++ b/Tests/XCRemoteCacheTests/Commands/Plugins/Thinning/DefaultSwiftProductsArchitecturesRecognizerTests.swift @@ -84,4 +84,18 @@ class DefaultSwiftProductsArchitecturesRecognizerTests: FileXCTestCase { XCTAssertEqual(architectures, ["x86"]) } + + func testRecognizesArchitectureFromFilesOnly() throws { + let swiftmodule = swiftmoduleDir.appendingPathComponent("x86.swiftmodule") + let swiftmoduleExtraDir = swiftmoduleDir.appendingPathComponent("Dir") + try fileManager.spt_createEmptyFile(swiftmodule) + try fileManager.spt_createEmptyDir(swiftmoduleExtraDir) + + let architectures = try recognizer.recognizeArchitectures( + builtProductsDir: builtProductsDir, + moduleName: "MyModule" + ) + + XCTAssertEqual(architectures, ["x86"]) + } }