From 9b95516f974b729d395216874124a08a5b0a7ab4 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 15:47:27 +0100 Subject: [PATCH 01/16] adding logging --- .../PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift index e236ec1..889d2fb 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift @@ -342,6 +342,9 @@ private extension SwiftPackageFileAnalyzer { // MARK: Target Resources + logger?.log("Old project base path \(oldProjectBasePath)", from: String(describing: Self.self)) + logger?.log("New project base path \(newProjectBasePath)", from: String(describing: Self.self)) + let oldResourcePaths = Set((oldTarget.resources?.map(\.path) ?? []).map { $0.trimmingPrefix(oldProjectBasePath) }) let newResourcePaths = Set((newTarget.resources?.map(\.path) ?? []).map { $0.trimmingPrefix(newProjectBasePath) }) From 8bedc5de48d906b18fd416ca9fc2ac63a7b82e21 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 16:32:05 +0100 Subject: [PATCH 02/16] refactored SwiftPackageFileAnalyzer --- .../SwiftPackageFileAnalyzer+Targets.swift | 191 ++++++++++++++++++ .../SwiftPackageFileAnalyzer.swift | 151 +------------- .../SwiftInterfaceProducer/XcodeTools.swift | 2 +- Tests/UnitTests/XcodeToolsTests.swift | 2 +- 4 files changed, 195 insertions(+), 151 deletions(-) create mode 100644 Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift new file mode 100644 index 0000000..f6d4447 --- /dev/null +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -0,0 +1,191 @@ +// +// SwiftPackageFileAnalyzer+Targets.swift +// public-api-diff +// +// Created by Alexander Guretzki on 10/02/2025. +// + +import Foundation + +import PADCore +import PADLogging + +import FileHandlingModule +import ShellModule +import SwiftPackageFileHelperModule + +extension SwiftPackageFileAnalyzer { + + internal func analyzeTargets( + old: [SwiftPackageDescription.Target], + new: [SwiftPackageDescription.Target], + oldProjectBasePath: String, + newProjectBasePath: String + ) throws -> [Change] { + guard old != new else { return [] } + + let oldTargetNames = Set(old.map(\.name)) + let newTargetNames = Set(new.map(\.name)) + + let added = newTargetNames.subtracting(oldTargetNames) + let removed = oldTargetNames.subtracting(newTargetNames) + let consistent = Set(oldTargetNames).intersection(Set(newTargetNames)) + + var changes = [Change]() + + changes += added.compactMap { addition in + guard let addedTarget = new.first(where: { $0.name == addition }) else { return nil } + return .init( + changeType: .addition(description: addedTarget.description), + parentPath: Constants.packageFileName(child: "targets") + ) + } + + try consistent.forEach { productName in + guard + let oldTarget = old.first(where: { $0.name == productName }), + let newTarget = new.first(where: { $0.name == productName }) + else { return } + + changes += try analyzeTarget( + oldTarget: oldTarget, + newTarget: newTarget, + oldProjectBasePath: oldProjectBasePath, + newProjectBasePath: newProjectBasePath + ) + } + + changes += removed.compactMap { removal in + guard let removedTarget = old.first(where: { $0.name == removal }) else { return nil } + return .init( + changeType: .removal(description: removedTarget.description), + parentPath: Constants.packageFileName(child: "targets") + ) + } + + return changes + } + + private func analyzeTarget( + oldTarget: SwiftPackageDescription.Target, + newTarget: SwiftPackageDescription.Target, + oldProjectBasePath: String, + newProjectBasePath: String + ) throws -> [Change] { + guard oldTarget != newTarget else { return [] } + + var listOfChanges = analyzeDependencies( + oldTarget: oldTarget, + newTarget: newTarget + ) + + listOfChanges += try analyzeTargetResources( + oldResources: oldTarget.resources ?? [], + newResources: newTarget.resources ?? [], + oldProjectBasePath: oldProjectBasePath, + newProjectBasePath: newProjectBasePath + ) + + if oldTarget.path != newTarget.path { + listOfChanges += ["Changed path from \"\(oldTarget.path)\" to \"\(newTarget.path)\""] + } + + if oldTarget.type != newTarget.type { + listOfChanges += ["Changed type from `.\(oldTarget.type.description)` to `.\(newTarget.type.description)`"] + } + + guard oldTarget.description != newTarget.description || !listOfChanges.isEmpty else { return [] } + + return [.init( + changeType: .modification( + oldDescription: oldTarget.description, + newDescription: newTarget.description + ), + parentPath: Constants.packageFileName(child: "targets"), + listOfChanges: listOfChanges + )] + + } +} + +// MARK: - SwiftPackageDescription.Target.Resource + +private extension SwiftPackageFileAnalyzer { + + func analyzeDependencies( + oldTarget: SwiftPackageDescription.Target, + newTarget: SwiftPackageDescription.Target + ) -> [String] { + + let oldTargetDependencies = Set(oldTarget.targetDependencies ?? []) + let newTargetDependencies = Set(newTarget.targetDependencies ?? []) + + let addedTargetDependencies = newTargetDependencies.subtracting(oldTargetDependencies) + let removedTargetDependencies = oldTargetDependencies.subtracting(newTargetDependencies) + + let oldProductDependencies = Set(oldTarget.productDependencies ?? []) + let newProductDependencies = Set(newTarget.productDependencies ?? []) + + let addedProductDependencies = newProductDependencies.subtracting(oldProductDependencies) + let removedProductDependencies = oldProductDependencies.subtracting(newProductDependencies) + + var listOfChanges = [String]() + listOfChanges += addedTargetDependencies.map { "Added dependency .target(name: \"\($0)\")" } + listOfChanges += addedProductDependencies.map { "Added dependency .product(name: \"\($0)\", ...)" } + listOfChanges += removedTargetDependencies.map { "Removed dependency .target(name: \"\($0)\")" } + listOfChanges += removedProductDependencies.map { "Removed dependency .product(name: \"\($0)\", ...)" } + return listOfChanges + } + + func analyzeTargetResources( + oldResources: [SwiftPackageDescription.Target.Resource], + newResources: [SwiftPackageDescription.Target.Resource], + oldProjectBasePath: String, + newProjectBasePath: String + ) throws -> [String] { + + logger?.log("Old project base path \(oldProjectBasePath)", from: String(describing: Self.self)) + logger?.log("New project base path \(newProjectBasePath)", from: String(describing: Self.self)) + + let oldResourcePaths = Set(oldResources.map(\.path).map { $0.trimmingPrefix(oldProjectBasePath) }) + let newResourcePaths = Set(newResources.map(\.path).map { $0.trimmingPrefix(newProjectBasePath) }) + + let addedResourcePaths = newResourcePaths.subtracting(oldResourcePaths) + let consistentResourcePaths = oldResourcePaths.intersection(newResourcePaths) + let removedResourcePaths = oldResourcePaths.subtracting(newResourcePaths) + + var listOfChanges = [String]() + + listOfChanges += addedResourcePaths.compactMap { path in + guard let resource = newResources.first(where: { $0.path.trimmingPrefix(newProjectBasePath) == path }) else { return nil } + return "Added resource \(resource.description)" + } + + listOfChanges += consistentResourcePaths.compactMap { path in + guard + let newResource = newResources.first(where: { $0.path.trimmingPrefix(newProjectBasePath) == path }), + let oldResource = oldResources.first(where: { $0.path.trimmingPrefix(oldProjectBasePath) == path }), + newResource.description != oldResource.description + else { return nil } + + return "Changed resource from `\(oldResource.description)` to `\(newResource.description)`" + } + + listOfChanges += removedResourcePaths.compactMap { path in + guard let resource = oldResources.first(where: { $0.path.trimmingPrefix(oldProjectBasePath) == path }) else { return nil } + return "Removed resource \(resource.description)" + } + + return listOfChanges + } +} + +// MARK: - Convenience Extension + +private extension String { + func trimmingPrefix(_ prefix: String) -> String { + var trimmed = self + trimmed.trimPrefix(prefix) + return trimmed + } +} diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift index 889d2fb..07f4e8b 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift @@ -18,9 +18,9 @@ public struct SwiftPackageFileAnalyzer: SwiftPackageFileAnalyzing { private let fileHandler: any FileHandling private let shell: any ShellHandling - private let logger: (any Logging)? + internal let logger: (any Logging)? - private enum Constants { + internal enum Constants { static let packageFileName = "Package.swift" static func packageFileName(child: String) -> String { ".\(child)" @@ -280,145 +280,6 @@ private extension SwiftPackageFileAnalyzer { )] } - // MARK: - Targets - - private func analyzeTargets( - old: [SwiftPackageDescription.Target], - new: [SwiftPackageDescription.Target], - oldProjectBasePath: String, - newProjectBasePath: String - ) throws -> [Change] { - guard old != new else { return [] } - - let oldTargetNames = Set(old.map(\.name)) - let newTargetNames = Set(new.map(\.name)) - - let added = newTargetNames.subtracting(oldTargetNames) - let removed = oldTargetNames.subtracting(newTargetNames) - let consistent = Set(oldTargetNames).intersection(Set(newTargetNames)) - - var changes = [Change]() - - changes += added.compactMap { addition in - guard let addedTarget = new.first(where: { $0.name == addition }) else { return nil } - return .init( - changeType: .addition(description: addedTarget.description), - parentPath: Constants.packageFileName(child: "targets") - ) - } - - try consistent.forEach { productName in - guard - let oldTarget = old.first(where: { $0.name == productName }), - let newTarget = new.first(where: { $0.name == productName }) - else { return } - - changes += try analyzeTarget( - oldTarget: oldTarget, - newTarget: newTarget, - oldProjectBasePath: oldProjectBasePath, - newProjectBasePath: newProjectBasePath - ) - } - - changes += removed.compactMap { removal in - guard let removedTarget = old.first(where: { $0.name == removal }) else { return nil } - return .init( - changeType: .removal(description: removedTarget.description), - parentPath: Constants.packageFileName(child: "targets") - ) - } - - return changes - } - - private func analyzeTarget( - oldTarget: SwiftPackageDescription.Target, - newTarget: SwiftPackageDescription.Target, - oldProjectBasePath: String, - newProjectBasePath: String - ) throws -> [Change] { - guard oldTarget != newTarget else { return [] } - - // MARK: Target Resources - - logger?.log("Old project base path \(oldProjectBasePath)", from: String(describing: Self.self)) - logger?.log("New project base path \(newProjectBasePath)", from: String(describing: Self.self)) - - let oldResourcePaths = Set((oldTarget.resources?.map(\.path) ?? []).map { $0.trimmingPrefix(oldProjectBasePath) }) - let newResourcePaths = Set((newTarget.resources?.map(\.path) ?? []).map { $0.trimmingPrefix(newProjectBasePath) }) - - let addedResourcePaths = newResourcePaths.subtracting(oldResourcePaths) - let consistentResourcePaths = oldResourcePaths.intersection(newResourcePaths) - let removedResourcePaths = oldResourcePaths.subtracting(newResourcePaths) - - // MARK: Target Dependencies - - let oldTargetDependencies = Set(oldTarget.targetDependencies ?? []) - let newTargetDependencies = Set(newTarget.targetDependencies ?? []) - - let addedTargetDependencies = newTargetDependencies.subtracting(oldTargetDependencies) - let removedTargetDependencies = oldTargetDependencies.subtracting(newTargetDependencies) - - // MARK: Product Dependencies - - let oldProductDependencies = Set(oldTarget.productDependencies ?? []) - let newProductDependencies = Set(newTarget.productDependencies ?? []) - - let addedProductDependencies = newProductDependencies.subtracting(oldProductDependencies) - let removedProductDependencies = oldProductDependencies.subtracting(newProductDependencies) - - // MARK: Compiling list of changes - - var listOfChanges = [String]() - - listOfChanges += addedResourcePaths.compactMap { path in - guard let resource = newTarget.resources?.first(where: { $0.path == path }) else { return nil } - return "Added resource \(resource.description)" - } - - listOfChanges += consistentResourcePaths.compactMap { path in - guard - let newResource = newTarget.resources?.first(where: { $0.path == path }), - let oldResource = oldTarget.resources?.first(where: { $0.path == path }) - else { return nil } - - return "Changed resource from `\(oldResource.description)` to `\(newResource.description)`" - } - - listOfChanges += removedResourcePaths.compactMap { path in - guard let resource = oldTarget.resources?.first(where: { $0.path == path }) else { return nil } - return "Removed resource \(resource.description)" - } - - listOfChanges += addedTargetDependencies.map { "Added dependency .target(name: \"\($0)\")" } - listOfChanges += addedProductDependencies.map { "Added dependency .product(name: \"\($0)\", ...)" } - - if oldTarget.path != newTarget.path { - listOfChanges += ["Changed path from \"\(oldTarget.path)\" to \"\(newTarget.path)\""] - } - - if oldTarget.type != newTarget.type { - listOfChanges += ["Changed type from `.\(oldTarget.type.description)` to `.\(newTarget.type.description)`"] - } - - listOfChanges += removedTargetDependencies.map { "Removed dependency .target(name: \"\($0)\")" } - listOfChanges += removedProductDependencies.map { "Removed dependency .product(name: \"\($0)\", ...)" } - - - guard oldTarget.description != newTarget.description || !listOfChanges.isEmpty else { return [] } - - return [.init( - changeType: .modification( - oldDescription: oldTarget.description, - newDescription: newTarget.description - ), - parentPath: Constants.packageFileName(child: "targets"), - listOfChanges: listOfChanges - )] - - } - // MARK: - Dependencies private func analyzeDependencies( @@ -500,11 +361,3 @@ private extension SwiftPackageFileAnalyzer { )] } } - -private extension String { - func trimmingPrefix(_ prefix: String) -> String { - var trimmed = self - trimmed.trimPrefix(prefix) - return trimmed - } -} diff --git a/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift b/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift index 20325a2..36b8636 100644 --- a/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift +++ b/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift @@ -88,7 +88,7 @@ struct XcodeTools { let result = shell.execute(command) let derivedDataPath = "\(projectDirectoryPath)/\(Constants.derivedDataPath)" - logger?.debug(result, from: String(describing: Self.self)) + //logger?.debug(result, from: String(describing: Self.self)) // It might be that the archive failed but the .swiftinterface files are still created // so we have to check outside if they exist. diff --git a/Tests/UnitTests/XcodeToolsTests.swift b/Tests/UnitTests/XcodeToolsTests.swift index dd50017..2ea5659 100644 --- a/Tests/UnitTests/XcodeToolsTests.swift +++ b/Tests/UnitTests/XcodeToolsTests.swift @@ -101,7 +101,7 @@ private extension XcodeToolsTests { ("📦 Archiving SCHEME from PROJECT_DIRECTORY_PATH", "XcodeTools") ] var expectedHandleDebugCalls: [(message: String, subsystem: String)] = [ - (archiveResult, "XcodeTools") + //(archiveResult, "XcodeTools") ] var expectedHandleFileExistsCalls = ["PROJECT_DIRECTORY_PATH/.build"] From 66b7a55b26b497463b5d07c476a7aec56bf5856f Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 16:45:26 +0100 Subject: [PATCH 03/16] debug output --- .../SwiftPackageFileAnalyzer+Targets.swift | 7 ++++--- .../SwiftInterfaceProducer/XcodeTools.swift | 2 +- Tests/UnitTests/XcodeToolsTests.swift | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index f6d4447..f0110d1 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -144,9 +144,6 @@ private extension SwiftPackageFileAnalyzer { newProjectBasePath: String ) throws -> [String] { - logger?.log("Old project base path \(oldProjectBasePath)", from: String(describing: Self.self)) - logger?.log("New project base path \(newProjectBasePath)", from: String(describing: Self.self)) - let oldResourcePaths = Set(oldResources.map(\.path).map { $0.trimmingPrefix(oldProjectBasePath) }) let newResourcePaths = Set(newResources.map(\.path).map { $0.trimmingPrefix(newProjectBasePath) }) @@ -176,6 +173,10 @@ private extension SwiftPackageFileAnalyzer { return "Removed resource \(resource.description)" } + // TODO: Remove this again! + listOfChanges += ["[DEBUG] Old project base path \(oldProjectBasePath)"] + listOfChanges += ["[DEBUG] New project base path \(newProjectBasePath)"] + return listOfChanges } } diff --git a/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift b/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift index 36b8636..20325a2 100644 --- a/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift +++ b/Sources/PublicModules/PADProjectBuilder/SwiftInterfaceProducer/XcodeTools.swift @@ -88,7 +88,7 @@ struct XcodeTools { let result = shell.execute(command) let derivedDataPath = "\(projectDirectoryPath)/\(Constants.derivedDataPath)" - //logger?.debug(result, from: String(describing: Self.self)) + logger?.debug(result, from: String(describing: Self.self)) // It might be that the archive failed but the .swiftinterface files are still created // so we have to check outside if they exist. diff --git a/Tests/UnitTests/XcodeToolsTests.swift b/Tests/UnitTests/XcodeToolsTests.swift index 2ea5659..dd50017 100644 --- a/Tests/UnitTests/XcodeToolsTests.swift +++ b/Tests/UnitTests/XcodeToolsTests.swift @@ -101,7 +101,7 @@ private extension XcodeToolsTests { ("📦 Archiving SCHEME from PROJECT_DIRECTORY_PATH", "XcodeTools") ] var expectedHandleDebugCalls: [(message: String, subsystem: String)] = [ - //(archiveResult, "XcodeTools") + (archiveResult, "XcodeTools") ] var expectedHandleFileExistsCalls = ["PROJECT_DIRECTORY_PATH/.build"] From a92852668fc041672367778fca746ae5c9c76450 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 16:56:41 +0100 Subject: [PATCH 04/16] adapting the path everywhere --- .../SwiftPackageFileAnalyzer+Targets.swift | 26 ++++++++++++++----- .../SwiftPackageDescription.swift | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index f0110d1..66215ab 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -138,14 +138,26 @@ private extension SwiftPackageFileAnalyzer { } func analyzeTargetResources( - oldResources: [SwiftPackageDescription.Target.Resource], - newResources: [SwiftPackageDescription.Target.Resource], + oldResources old: [SwiftPackageDescription.Target.Resource], + newResources new: [SwiftPackageDescription.Target.Resource], oldProjectBasePath: String, newProjectBasePath: String ) throws -> [String] { - let oldResourcePaths = Set(oldResources.map(\.path).map { $0.trimmingPrefix(oldProjectBasePath) }) - let newResourcePaths = Set(newResources.map(\.path).map { $0.trimmingPrefix(newProjectBasePath) }) + let oldResources = old.map { resource in + var updated = resource + updated.path = ".\(updated.path.trimmingPrefix(oldProjectBasePath))" + return updated + } + + let newResources = new.map { resource in + var updated = resource + updated.path = ".\(updated.path.trimmingPrefix(newProjectBasePath))" + return updated + } + + let oldResourcePaths = Set(oldResources.map(\.path)) + let newResourcePaths = Set(newResources.map(\.path)) let addedResourcePaths = newResourcePaths.subtracting(oldResourcePaths) let consistentResourcePaths = oldResourcePaths.intersection(newResourcePaths) @@ -160,8 +172,8 @@ private extension SwiftPackageFileAnalyzer { listOfChanges += consistentResourcePaths.compactMap { path in guard - let newResource = newResources.first(where: { $0.path.trimmingPrefix(newProjectBasePath) == path }), - let oldResource = oldResources.first(where: { $0.path.trimmingPrefix(oldProjectBasePath) == path }), + let newResource = newResources.first(where: { $0.path == path }), + let oldResource = oldResources.first(where: { $0.path == path }), newResource.description != oldResource.description else { return nil } @@ -169,7 +181,7 @@ private extension SwiftPackageFileAnalyzer { } listOfChanges += removedResourcePaths.compactMap { path in - guard let resource = oldResources.first(where: { $0.path.trimmingPrefix(oldProjectBasePath) == path }) else { return nil } + guard let resource = oldResources.first(where: { $0.path == path }) else { return nil } return "Removed resource \(resource.description)" } diff --git a/Sources/Shared/Package/SwiftPackageFileHelperModule/SwiftPackageDescription.swift b/Sources/Shared/Package/SwiftPackageFileHelperModule/SwiftPackageDescription.swift index 8aa5333..52c5db7 100644 --- a/Sources/Shared/Package/SwiftPackageFileHelperModule/SwiftPackageDescription.swift +++ b/Sources/Shared/Package/SwiftPackageFileHelperModule/SwiftPackageDescription.swift @@ -263,7 +263,7 @@ extension SwiftPackageDescription.Target: CustomStringConvertible { package extension SwiftPackageDescription.Target { struct Resource: Codable, Equatable { - package let path: String + package var path: String package let rule: Rule } } From 6620392294fbc172f36807e56a0026e830547c96 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 16:59:49 +0100 Subject: [PATCH 05/16] removing debug code --- .../SwiftPackageFileAnalyzer+Targets.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index 66215ab..b0f9f7a 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -185,10 +185,6 @@ private extension SwiftPackageFileAnalyzer { return "Removed resource \(resource.description)" } - // TODO: Remove this again! - listOfChanges += ["[DEBUG] Old project base path \(oldProjectBasePath)"] - listOfChanges += ["[DEBUG] New project base path \(newProjectBasePath)"] - return listOfChanges } } From 3836fff8707b0260043c3e9bdaf70075cf71a699 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 17:09:15 +0100 Subject: [PATCH 06/16] re-adding debug code --- .../SwiftPackageFileAnalyzer+Targets.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index b0f9f7a..66215ab 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -185,6 +185,10 @@ private extension SwiftPackageFileAnalyzer { return "Removed resource \(resource.description)" } + // TODO: Remove this again! + listOfChanges += ["[DEBUG] Old project base path \(oldProjectBasePath)"] + listOfChanges += ["[DEBUG] New project base path \(newProjectBasePath)"] + return listOfChanges } } From 50ce5aaa5e2b2030a32b762476b67a3c15066091 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Mon, 10 Feb 2025 17:12:29 +0100 Subject: [PATCH 07/16] using current action yml --- action.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 96d042b..f4cb22f 100644 --- a/action.yml +++ b/action.yml @@ -16,7 +16,7 @@ runs: steps: - name: 🍱 Compute prerequisites run: | - echo "VERSION_NUMBER=0.8.2" >> $GITHUB_ENV + echo "VERSION_NUMBER=$(uuidgen)" >> $GITHUB_ENV echo "BINARY_PATH=$(swift build --configuration release --show-bin-path)/public-api-diff" >> $GITHUB_ENV echo "HEAD_GITHUB_REPO=${{github.server_url}}/${{ github.event.pull_request.head.repo.full_name || github.repository}}.git" >> $GITHUB_ENV echo "BASE_GITHUB_REPO=${{github.server_url}}/${{github.repository}}.git" >> $GITHUB_ENV @@ -26,7 +26,6 @@ runs: - uses: actions/checkout@v4 with: repository: "Adyen/adyen-swift-public-api-diff" - ref: ${{ env.VERSION_NUMBER }} - name: 🛻 Restore Binary id: cache-restore From 169c043b8ac9570200e0e05a57000c1379c225ec Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 10:36:33 +0100 Subject: [PATCH 08/16] Removing debug code --- .../SwiftPackageFileAnalyzer+Targets.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index 66215ab..b0f9f7a 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -185,10 +185,6 @@ private extension SwiftPackageFileAnalyzer { return "Removed resource \(resource.description)" } - // TODO: Remove this again! - listOfChanges += ["[DEBUG] Old project base path \(oldProjectBasePath)"] - listOfChanges += ["[DEBUG] New project base path \(newProjectBasePath)"] - return listOfChanges } } From 65586ec9d3257e4c73efddf9c0661e50eeafec12 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 10:50:43 +0100 Subject: [PATCH 09/16] Update detect-api-changes.yml --- .github/workflows/detect-api-changes.yml | 38 +++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index 0363128..56c0b88 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -25,7 +25,7 @@ jobs: - name: Select latest Xcode uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: '15.4' + xcode-version: '16.1' - name: 🚚 Fetch repo uses: actions/checkout@v4 @@ -54,11 +54,35 @@ jobs: target: '${{ github.event.inputs.old || github.event.pull_request.base.ref }}' githubRepo: '${{github.server_url}}/${{github.repository}}.git' noTargetBranch: 'no target branch' + + - name: 🏃 Run Diff + run: | + NEW=${{ inputs.new }} + OLD=${{ inputs.old }} + PLATFORM=${{ inputs.platform }} + PROJECT_FOLDER=${{ github.workspace }} + + swift run public-api-diff project --new "$NEW" --old "$OLD" --platform "$PLATFORM" --output "$PROJECT_FOLDER/api_comparison.md" --log-output "$PROJECT_FOLDER/logs.txt" + cat "$PROJECT_FOLDER/logs.txt" + + if [[ ${{ env.HEAD_GITHUB_REPO != env.BASE_GITHUB_REPO }} ]]; then + echo "---" >> $GITHUB_STEP_SUMMARY + echo "> [!IMPORTANT]" >> $GITHUB_STEP_SUMMARY + echo "> **Commenting on pull requests from forks is not possible** due to insufficient permissions." >> $GITHUB_STEP_SUMMARY + echo "> Once merged, the output will be posted as an auto-updating comment under the pull request." >> $GITHUB_STEP_SUMMARY + echo "---" >> $GITHUB_STEP_SUMMARY + fi + + cat "$PROJECT_FOLDER/api_comparison.md" >> $GITHUB_STEP_SUMMARY + shell: bash - - name: 🔍 Detect Changes - uses: ./ # Uses the action.yml that's at the root of the repository - id: public_api_diff + # We only want to comment if we're in a Pull Request and if the Pull Request is not from a forked Repository + # Forked Repositories have different rights for security reasons and thus it's not possible to comment on PRs without lowering the security + # once the tool is merged the base repo rights apply and the script can comment on PRs as expected. + - if: ${{ github.event.pull_request.base.ref != '' && env.HEAD_GITHUB_REPO == env.BASE_GITHUB_REPO }} + name: 📝 Comment on PR + uses: thollander/actions-comment-pull-request@v3 with: - platform: "macOS" - new: ${{ env.NEW_VERSION }} - old: ${{ env.OLD_VERSION }} + file-path: "${{ github.workspace }}/api_comparison.md" + comment-tag: api_changes + mode: recreate From baabfcebab843d83e9a6e7d3c27c4fce9ec6fca2 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 10:52:15 +0100 Subject: [PATCH 10/16] Update action.yml --- action.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index f4cb22f..5d1c5a7 100644 --- a/action.yml +++ b/action.yml @@ -16,7 +16,7 @@ runs: steps: - name: 🍱 Compute prerequisites run: | - echo "VERSION_NUMBER=$(uuidgen)" >> $GITHUB_ENV + echo "VERSION_NUMBER=0.8.2" >> $GITHUB_ENV echo "BINARY_PATH=$(swift build --configuration release --show-bin-path)/public-api-diff" >> $GITHUB_ENV echo "HEAD_GITHUB_REPO=${{github.server_url}}/${{ github.event.pull_request.head.repo.full_name || github.repository}}.git" >> $GITHUB_ENV echo "BASE_GITHUB_REPO=${{github.server_url}}/${{github.repository}}.git" >> $GITHUB_ENV @@ -26,6 +26,7 @@ runs: - uses: actions/checkout@v4 with: repository: "Adyen/adyen-swift-public-api-diff" + ref: ${{ env.VERSION_NUMBER }} - name: 🛻 Restore Binary id: cache-restore @@ -67,13 +68,13 @@ runs: $BINARY_PATH project --new "$NEW" --old "$OLD" --platform "$PLATFORM" --output "$PROJECT_FOLDER/api_comparison.md" --log-output "$PROJECT_FOLDER/logs.txt" cat "$PROJECT_FOLDER/logs.txt" - # if [[ ${{ env.HEAD_GITHUB_REPO != env.BASE_GITHUB_REPO }} ]]; then + if [[ ${{ env.HEAD_GITHUB_REPO != env.BASE_GITHUB_REPO }} ]]; then echo "---" >> $GITHUB_STEP_SUMMARY echo "> [!IMPORTANT]" >> $GITHUB_STEP_SUMMARY echo "> **Commenting on pull requests from forks is not possible** due to insufficient permissions." >> $GITHUB_STEP_SUMMARY echo "> Once merged, the output will be posted as an auto-updating comment under the pull request." >> $GITHUB_STEP_SUMMARY echo "---" >> $GITHUB_STEP_SUMMARY - # fi + fi cat "$PROJECT_FOLDER/api_comparison.md" >> $GITHUB_STEP_SUMMARY shell: bash From c5165294c02e6cdb2f36c9639b05057ecededa0c Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 11:01:14 +0100 Subject: [PATCH 11/16] Update detect-api-changes.yml --- .github/workflows/detect-api-changes.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index 56c0b88..47ff329 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -54,15 +54,20 @@ jobs: target: '${{ github.event.inputs.old || github.event.pull_request.base.ref }}' githubRepo: '${{github.server_url}}/${{github.repository}}.git' noTargetBranch: 'no target branch' - + + - name: 🧰 Build Swift CLI + run: swift build --configuration release + - name: 🏃 Run Diff run: | - NEW=${{ inputs.new }} - OLD=${{ inputs.old }} + NEW=${{ env.NEW_VERSION }} + OLD=${{ env.OLD_VERSION }} PLATFORM=${{ inputs.platform }} PROJECT_FOLDER=${{ github.workspace }} - - swift run public-api-diff project --new "$NEW" --old "$OLD" --platform "$PLATFORM" --output "$PROJECT_FOLDER/api_comparison.md" --log-output "$PROJECT_FOLDER/logs.txt" + BINARY_PATH=$(swift build --configuration release --show-bin-path)/public-api-diff" + + echo "▶️ Running binary at $BINARY_PATH" + $BINARY_PATH project --new "$NEW" --old "$OLD" --platform "$PLATFORM" --output "$PROJECT_FOLDER/api_comparison.md" --log-output "$PROJECT_FOLDER/logs.txt" cat "$PROJECT_FOLDER/logs.txt" if [[ ${{ env.HEAD_GITHUB_REPO != env.BASE_GITHUB_REPO }} ]]; then @@ -74,7 +79,6 @@ jobs: fi cat "$PROJECT_FOLDER/api_comparison.md" >> $GITHUB_STEP_SUMMARY - shell: bash # We only want to comment if we're in a Pull Request and if the Pull Request is not from a forked Repository # Forked Repositories have different rights for security reasons and thus it's not possible to comment on PRs without lowering the security From 6bc6ff8402f1fe70b52158585f182a76017dabbe Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 11:12:55 +0100 Subject: [PATCH 12/16] Update detect-api-changes.yml --- .github/workflows/detect-api-changes.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index 47ff329..f5620dd 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -62,9 +62,8 @@ jobs: run: | NEW=${{ env.NEW_VERSION }} OLD=${{ env.OLD_VERSION }} - PLATFORM=${{ inputs.platform }} PROJECT_FOLDER=${{ github.workspace }} - BINARY_PATH=$(swift build --configuration release --show-bin-path)/public-api-diff" + BINARY_PATH="$(swift build --configuration release --show-bin-path)/public-api-diff" echo "▶️ Running binary at $BINARY_PATH" $BINARY_PATH project --new "$NEW" --old "$OLD" --platform "$PLATFORM" --output "$PROJECT_FOLDER/api_comparison.md" --log-output "$PROJECT_FOLDER/logs.txt" From c46080f6c00732bb8719bda027f88a0c00917dcd Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 11:19:29 +0100 Subject: [PATCH 13/16] Update detect-api-changes.yml --- .github/workflows/detect-api-changes.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index f5620dd..404f35b 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -62,6 +62,7 @@ jobs: run: | NEW=${{ env.NEW_VERSION }} OLD=${{ env.OLD_VERSION }} + PLATFORM="macOS" PROJECT_FOLDER=${{ github.workspace }} BINARY_PATH="$(swift build --configuration release --show-bin-path)/public-api-diff" From d29d1346d33548feef4586006962150dc017b307 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 11:40:57 +0100 Subject: [PATCH 14/16] using older xcode version --- .github/workflows/detect-api-changes.yml | 2 +- .../SwiftInterfaceParser/SwiftInterfaceParser.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index 404f35b..2c236bc 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -25,7 +25,7 @@ jobs: - name: Select latest Xcode uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: '16.1' + xcode-version: '15.4' - name: 🚚 Fetch repo uses: actions/checkout@v4 diff --git a/Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceParser/SwiftInterfaceParser.swift b/Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceParser/SwiftInterfaceParser.swift index 828bf67..2bfac2d 100644 --- a/Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceParser/SwiftInterfaceParser.swift +++ b/Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceParser/SwiftInterfaceParser.swift @@ -15,10 +15,10 @@ import SwiftSyntax class SwiftInterfaceParser: SyntaxVisitor, SwiftInterfaceParsing { // TODO: Handle (Nice to have) + // - IfConfigClauseListSyntax // - DeinitializerDeclSyntax // - PrecedenceGroupDeclSyntax // - OperatorDeclSyntax - // - IfConfigClauseListSyntax // - ... (There are more but not important right now) private var scope: Scope = .root(elements: []) From 1b114352cf41c9c78ef845f3d61edffe155eece7 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 11:46:26 +0100 Subject: [PATCH 15/16] Update detect-api-changes.yml --- .github/workflows/detect-api-changes.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/detect-api-changes.yml b/.github/workflows/detect-api-changes.yml index 2c236bc..fffb243 100644 --- a/.github/workflows/detect-api-changes.yml +++ b/.github/workflows/detect-api-changes.yml @@ -31,29 +31,28 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - + - name: 👾 Define Diff Versions run: | - NEW="${{ env.source }}~${{ env.githubRepo }}" - if [[ '${{ github.head_ref || env.noTargetBranch }}' == release/* ]] + NEW="${{ env.source }}~${{ env.headGithubRepo }}" + OLD="${{ env.target }}~${{ env.baseGithubRepo }}" + + if [[ '${{ env.targetBranchName || env.noTargetBranch }}' == release/* ]] then LATEST_TAG=$(git describe --tags --abbrev=0) - OLD="$LATEST_TAG~${{ env.githubRepo }}" - else - OLD="${{ env.target }}~${{ env.githubRepo }}" + OLD="$LATEST_TAG~${{ env.baseGithubRepo }}" fi - echo "OLD=$OLD" - echo "NEW=$NEW" - # Providing the output to the environment echo "OLD_VERSION=$OLD" >> $GITHUB_ENV echo "NEW_VERSION=$NEW" >> $GITHUB_ENV env: source: '${{ github.event.inputs.new || github.head_ref }}' target: '${{ github.event.inputs.old || github.event.pull_request.base.ref }}' - githubRepo: '${{github.server_url}}/${{github.repository}}.git' + headGithubRepo: '${{github.server_url}}/${{ github.event.pull_request.head.repo.full_name || github.repository}}.git' + baseGithubRepo: '${{github.server_url}}/${{github.repository}}.git' noTargetBranch: 'no target branch' + targetBranchName: '${{ github.head_ref }}' - name: 🧰 Build Swift CLI run: swift build --configuration release From b7dd50ccbfd5c4cc6b7a831c940cda2e96f314d5 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 11 Feb 2025 12:17:23 +0100 Subject: [PATCH 16/16] reverting path formatting --- .../SwiftPackageFileAnalyzer+Targets.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift index b0f9f7a..f86583f 100644 --- a/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift +++ b/Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer+Targets.swift @@ -146,13 +146,13 @@ private extension SwiftPackageFileAnalyzer { let oldResources = old.map { resource in var updated = resource - updated.path = ".\(updated.path.trimmingPrefix(oldProjectBasePath))" + updated.path = updated.path.trimmingPrefix(oldProjectBasePath) return updated } let newResources = new.map { resource in var updated = resource - updated.path = ".\(updated.path.trimmingPrefix(newProjectBasePath))" + updated.path = updated.path.trimmingPrefix(newProjectBasePath) return updated }