diff --git a/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift b/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift index 2bcdbbf..6e7f2f7 100644 --- a/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift +++ b/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift @@ -51,8 +51,6 @@ protocol ArtifactSwiftProductsBuilder { /// # {workingDir}/xccache/produced/include/#{moduleName} (if `moduleName` is defined) class ArtifactSwiftProductsBuilderImpl: ArtifactSwiftProductsBuilder { - /// List of all required swiftmodule related extensions that should be copied to the artifact - private static let swiftmoduleExtensionsToInclude = ["swiftmodule", "swiftdoc", "swiftsourceinfo"] private let workingDir: URL private let moduleName: String? private let fileManager: FileManager diff --git a/Sources/XCRemoteCache/Artifacts/SwiftmoduleFileExtension.swift b/Sources/XCRemoteCache/Artifacts/SwiftmoduleFileExtension.swift index b45acda..85ff2db 100644 --- a/Sources/XCRemoteCache/Artifacts/SwiftmoduleFileExtension.swift +++ b/Sources/XCRemoteCache/Artifacts/SwiftmoduleFileExtension.swift @@ -30,6 +30,7 @@ enum SwiftmoduleFileExtension: String { case swiftmodule case swiftdoc case swiftsourceinfo + case swiftinterface } extension SwiftmoduleFileExtension { @@ -38,5 +39,6 @@ extension SwiftmoduleFileExtension { .swiftmodule: .required, .swiftdoc: .required, .swiftsourceinfo: .optional, + .swiftinterface: .optional, ] } diff --git a/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift b/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift index 9fa5769..2eeb86e 100644 --- a/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift +++ b/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift @@ -27,6 +27,7 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { private var swiftmoduleFile: URL! private var swiftmoduleDocFile: URL! private var swiftmoduleSourceInfoFile: URL! + private var swiftmoduleInterfaceFile: URL! private var workingDir: URL! private var builder: ArtifactSwiftProductsBuilderImpl! @@ -37,6 +38,7 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { swiftmoduleFile = moduleDir.appendingPathComponent("MyModule.swiftmodule") swiftmoduleDocFile = moduleDir.appendingPathComponent("MyModule.swiftdoc") swiftmoduleSourceInfoFile = moduleDir.appendingPathComponent("MyModule.swiftsourceinfo") + swiftmoduleInterfaceFile = moduleDir.appendingPathComponent("MyModule.swiftinterface") workingDir = rootDir.appendingPathComponent("working") builder = ArtifactSwiftProductsBuilderImpl( workingDir: workingDir, @@ -69,7 +71,7 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { ) } - func testIncludesAllSwiftmoduleFiles() throws { + func testIncludesAllBasicSwiftmoduleFiles() throws { try fileManager.spt_createEmptyFile(swiftmoduleFile) try fileManager.spt_createEmptyFile(swiftmoduleDocFile) try fileManager.spt_createEmptyFile(swiftmoduleSourceInfoFile) @@ -91,6 +93,32 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { XCTAssertTrue(fileManager.fileExists(atPath: expectedBuildedSwiftSourceInfoFile.path)) } + func testIncludesAllEvolutionEnabledSwiftmoduleFiles() throws { + try fileManager.spt_createEmptyFile(swiftmoduleFile) + try fileManager.spt_createEmptyFile(swiftmoduleDocFile) + try fileManager.spt_createEmptyFile(swiftmoduleSourceInfoFile) + try fileManager.spt_createEmptyFile(swiftmoduleInterfaceFile) + let builderSwiftmoduleDir = + builder + .buildingArtifactSwiftModulesLocation() + .appendingPathComponent("arm64") + let expectedBuildedSwiftmoduleFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftmodule") + let expectedBuildedSwiftmoduledocFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftdoc") + let expectedBuildedSwiftSourceInfoFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftsourceinfo") + let expectedBuildedSwiftInterfaceFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftinterface") + + try builder.includeModuleDefinitionsToTheArtifact(arch: "arm64", moduleURL: swiftmoduleFile) + + XCTAssertTrue(fileManager.fileExists(atPath: expectedBuildedSwiftmoduleFile.path)) + XCTAssertTrue(fileManager.fileExists(atPath: expectedBuildedSwiftmoduledocFile.path)) + XCTAssertTrue(fileManager.fileExists(atPath: expectedBuildedSwiftSourceInfoFile.path)) + XCTAssertTrue(fileManager.fileExists(atPath: expectedBuildedSwiftInterfaceFile.path)) + } + func testFailsIncludingWhenMissingRequiredSwiftmoduleFiles() throws { XCTAssertThrowsError( try builder.includeModuleDefinitionsToTheArtifact( diff --git a/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift b/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift index 63f9019..eb44e31 100644 --- a/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift +++ b/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift @@ -31,6 +31,7 @@ class BuildArtifactCreatorTests: FileXCTestCase { private var swiftmoduleURL: URL! private var swiftdocURL: URL! private var swiftSourceInfoURL: URL! + private var swiftInterfaceURL: URL! private var executablePath: String! private var executableURL: URL! private var creator: BuildArtifactCreator! @@ -50,6 +51,8 @@ class BuildArtifactCreatorTests: FileXCTestCase { .appendingPathComponent("Target.swiftdoc") swiftSourceInfoURL = workDirectory.appendingPathComponent("Objects-normal") .appendingPathComponent("Target.swiftsourceinfo") + swiftInterfaceURL = workDirectory.appendingPathComponent("Objects-normal") + .appendingPathComponent("Target.swiftinterface") executablePath = "libTarget.a" executableURL = buildDir.appendingPathComponent(executablePath) dSYM = executableURL.deletingPathExtension().appendingPathExtension(".dSYM") @@ -114,6 +117,28 @@ class BuildArtifactCreatorTests: FileXCTestCase { ]) } + func testPackagesEvolutionEnabledSwiftmoduleFiles() throws { + try fileManager.spt_createEmptyFile(swiftmoduleURL) + try fileManager.spt_createEmptyFile(swiftdocURL) + try fileManager.spt_createEmptyFile(swiftSourceInfoURL) + try fileManager.spt_createEmptyFile(swiftInterfaceURL) + + try creator.includeModuleDefinitionsToTheArtifact(arch: "arch", moduleURL: swiftmoduleURL) + let artifact = try creator.createArtifact(artifactKey: "key", meta: sampleMeta) + + let unzippedURL = workDirectory.appendingPathComponent(UUID().uuidString) + try Zip.unzipFile(artifact.package, destination: unzippedURL, overwrite: true, password: nil, progress: nil) + let allFiles = try fileManager.spt_allFilesRecusively(unzippedURL) + XCTAssertEqual(Set(allFiles), [ + unzippedURL.appendingPathComponent("libTarget.a"), + unzippedURL.appendingPathComponent("fileKey.json"), + unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftmodule"), + unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftdoc"), + unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftsourceinfo"), + unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftinterface"), + ]) + } + func testFailsPackageWhenSwiftmoduleRelatedFilesAreMissing() throws { // Creating only `Target.swiftmodule`, without `.swiftdoc` try fileManager.spt_createEmptyFile(swiftmoduleURL) diff --git a/Tests/XCRemoteCacheTests/Commands/SwiftcTests.swift b/Tests/XCRemoteCacheTests/Commands/SwiftcTests.swift index 55c888c..41b9c69 100644 --- a/Tests/XCRemoteCacheTests/Commands/SwiftcTests.swift +++ b/Tests/XCRemoteCacheTests/Commands/SwiftcTests.swift @@ -280,6 +280,9 @@ class SwiftcTests: FileXCTestCase { let artifactSwiftSourceInfo = URL( fileURLWithPath: "/cachedArtifact/swiftmodule/archTest/Target.swiftsourceinfo" ) + let artifactSwiftInterfaceInfo = URL( + fileURLWithPath: "/cachedArtifact/swiftmodule/archTest/Target.swiftinterface" + ) artifactOrganizer = ArtifactOrganizerFake(artifactRoot: artifactRoot) let swiftc = Swiftc( @@ -303,12 +306,14 @@ class SwiftcTests: FileXCTestCase { let swiftModuleURL = swiftModuleFiles.0[.swiftmodule] let swiftDocURL = swiftModuleFiles.0[.swiftdoc] let swiftSourceInfoURL = swiftModuleFiles.0[.swiftsourceinfo] + let swiftInterfaceURL = swiftModuleFiles.0[.swiftinterface] let swiftHeaderURL = swiftModuleFiles.1 XCTAssertEqual(swiftModuleURL, artifactSwiftmodule) XCTAssertEqual(swiftDocURL, artifactSwiftdoc) XCTAssertEqual(swiftSourceInfoURL, artifactSwiftSourceInfo) XCTAssertEqual(swiftHeaderURL, artifactObjCHeader) + XCTAssertEqual(swiftInterfaceURL, artifactSwiftInterfaceInfo) }