From 8155e042b56ca4b34ca64073dfae71d504b6db7c Mon Sep 17 00:00:00 2001 From: Vasily Fedorov Date: Sun, 23 Jan 2022 03:59:49 +0300 Subject: [PATCH 1/3] Add support for swift modules with @objc interfaces --- .../Artifacts/ArtifactSwiftProductsBuilder.swift | 2 +- .../XCRemoteCache/Artifacts/SwiftmoduleFileExtension.swift | 2 ++ .../Artifacts/ArtifactSwiftProductsBuilderImplTests.swift | 6 ++++++ .../Artifacts/BuildArtifactCreatorTests.swift | 5 +++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift b/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift index 2bcdbbf..acd5f29 100644 --- a/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift +++ b/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift @@ -52,7 +52,7 @@ protocol ArtifactSwiftProductsBuilder { 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 static let swiftmoduleExtensionsToInclude = ["swiftmodule", "swiftdoc", "swiftsourceinfo", "swiftinterface"] 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..9f9b6c3 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, @@ -73,6 +75,7 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { try fileManager.spt_createEmptyFile(swiftmoduleFile) try fileManager.spt_createEmptyFile(swiftmoduleDocFile) try fileManager.spt_createEmptyFile(swiftmoduleSourceInfoFile) + try fileManager.spt_createEmptyFile(swiftmoduleInterfaceFile) let builderSwiftmoduleDir = builder .buildingArtifactSwiftModulesLocation() @@ -83,12 +86,15 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { 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 { diff --git a/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift b/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift index 63f9019..4b8ab50 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") @@ -98,6 +101,7 @@ class BuildArtifactCreatorTests: FileXCTestCase { 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) @@ -111,6 +115,7 @@ class BuildArtifactCreatorTests: FileXCTestCase { unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftmodule"), unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftdoc"), unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftsourceinfo"), + unzippedURL.appendingPathComponent("swiftmodule/arch/Target.swiftinterface"), ]) } From da0d1c20d2903e30a4027f64c6d561445e32ef02 Mon Sep 17 00:00:00 2001 From: Vasily Fedorov Date: Sun, 23 Jan 2022 18:13:42 +0300 Subject: [PATCH 2/3] Separated testing for including swiftinterface file in artifacts builders --- .../ArtifactSwiftProductsBuilder.swift | 2 -- ...rtifactSwiftProductsBuilderImplTests.swift | 24 ++++++++++++++++++- .../Artifacts/BuildArtifactCreatorTests.swift | 20 ++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift b/Sources/XCRemoteCache/Artifacts/ArtifactSwiftProductsBuilder.swift index acd5f29..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", "swiftinterface"] private let workingDir: URL private let moduleName: String? private let fileManager: FileManager diff --git a/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift b/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift index 9f9b6c3..2eeb86e 100644 --- a/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift +++ b/Tests/XCRemoteCacheTests/Artifacts/ArtifactSwiftProductsBuilderImplTests.swift @@ -71,7 +71,29 @@ class ArtifactSwiftProductsBuilderImplTests: FileXCTestCase { ) } - func testIncludesAllSwiftmoduleFiles() throws { + func testIncludesAllBasicSwiftmoduleFiles() throws { + try fileManager.spt_createEmptyFile(swiftmoduleFile) + try fileManager.spt_createEmptyFile(swiftmoduleDocFile) + try fileManager.spt_createEmptyFile(swiftmoduleSourceInfoFile) + let builderSwiftmoduleDir = + builder + .buildingArtifactSwiftModulesLocation() + .appendingPathComponent("arm64") + let expectedBuildedSwiftmoduleFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftmodule") + let expectedBuildedSwiftmoduledocFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftdoc") + let expectedBuildedSwiftSourceInfoFile = + builderSwiftmoduleDir.appendingPathComponent("MyModule.swiftsourceinfo") + + 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)) + } + + func testIncludesAllEvolutionEnabledSwiftmoduleFiles() throws { try fileManager.spt_createEmptyFile(swiftmoduleFile) try fileManager.spt_createEmptyFile(swiftmoduleDocFile) try fileManager.spt_createEmptyFile(swiftmoduleSourceInfoFile) diff --git a/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift b/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift index 4b8ab50..eb44e31 100644 --- a/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift +++ b/Tests/XCRemoteCacheTests/Artifacts/BuildArtifactCreatorTests.swift @@ -101,6 +101,26 @@ class BuildArtifactCreatorTests: FileXCTestCase { try fileManager.spt_createEmptyFile(swiftmoduleURL) try fileManager.spt_createEmptyFile(swiftdocURL) try fileManager.spt_createEmptyFile(swiftSourceInfoURL) + + 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"), + ]) + } + + 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) From 93b8dcd0c3a9682b6c7b4b17a83f10332a4ad49f Mon Sep 17 00:00:00 2001 From: Vasily Fedorov Date: Sun, 23 Jan 2022 18:21:52 +0300 Subject: [PATCH 3/3] Also added swiftinterface file check to swiftc tests --- Tests/XCRemoteCacheTests/Commands/SwiftcTests.swift | 5 +++++ 1 file changed, 5 insertions(+) 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) }