Skip to content

Commit

Permalink
.swiftinterface file support (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
goergisn authored Oct 15, 2024
1 parent 661743d commit c138ff1
Show file tree
Hide file tree
Showing 143 changed files with 5,624 additions and 157,701 deletions.
8 changes: 8 additions & 0 deletions Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// File.swift
// public-api-diff
//
// Created by Alexander Guretzki on 11/10/2024.
//

import Foundation
31 changes: 29 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,40 @@
"version" : "1.5.0"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64",
"version" : "1.4.3"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-syntax",
"state" : {
"revision" : "cb53fa1bd3219b0b23ded7dfdd3b2baff266fd25",
"version" : "600.0.0"
}
},
{
"identity" : "swiftformat",
"kind" : "remoteSourceControl",
"location" : "https://github.com/nicklockwood/SwiftFormat",
"state" : {
"revision" : "c6680dd33c013abdd18266538e302f6323fa130e",
"version" : "0.54.4"
"revision" : "86ed20990585f478c0daf309af645c2a528b59d8",
"version" : "0.54.6"
}
}
],
Expand Down
119 changes: 111 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,131 @@ let package = Package(
platforms: [
.macOS(.v13)
],
products: [
.executable(
name: "public-api-diff",
targets: ["public-api-diff"]
),
.library(
name: "SwiftInterfaceDiff",
targets: [
"PADSwiftInterfaceDiff",
"PADOutputGenerator"
]
),
.library(
name: "PublicApiDiff",
targets: [
"PADProjectBuilder",
"PADPackageFileAnalyzer",
"PADSwiftInterfaceDiff",
"PADOutputGenerator"
]
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.5.0"),
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.6")
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.0"),
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.6"),
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.

// MARK: - Executable Targets

.executableTarget(
name: "public-api-diff",
dependencies: [
"PADProjectBuilder",
"PADSwiftInterfaceDiff",
"PADOutputGenerator",
"PADPackageFileAnalyzer",
.product(name: "ArgumentParser", package: "swift-argument-parser")
],
path: "Sources"
path: "Sources/ExecutableTargets/CommandLineTool"
),

// MARK: - Public Modules

.target(
name: "PADSwiftInterfaceDiff",
dependencies: [
"PADCore",
"PADLogging",
"FileHandlingModule",
.product(name: "SwiftSyntax", package: "swift-syntax"),
.product(name: "SwiftParser", package: "swift-syntax"),
],
path: "Sources/PublicModules/PADSwiftInterfaceDiff"
),
.target(
name: "PADPackageFileAnalyzer",
dependencies: [
"PADCore",
"PADLogging",
"FileHandlingModule",
"ShellModule",
"SwiftPackageFileHelperModule"
],
path: "Sources/PublicModules/PADPackageFileAnalyzer"
),
.target(
name: "PADProjectBuilder",
dependencies: [
"PADCore",
"PADLogging",
"FileHandlingModule",
"ShellModule",
"SwiftPackageFileHelperModule"
],
path: "Sources/PublicModules/PADProjectBuilder"
),
.target(
name: "PADOutputGenerator",
dependencies: ["PADCore"],
path: "Sources/PublicModules/PADOutputGenerator"
),

// MARK: - Shared/Public

.target(
name: "PADCore",
path: "Sources/Shared/Public/PADCore"
),
.target(
name: "PADLogging",
dependencies: ["FileHandlingModule"],
path: "Sources/Shared/Public/PADLogging"
),

// MARK: - Shared/Package

.target(
name: "FileHandlingModule",
path: "Sources/Shared/Package/FileHandlingModule"
),
.target(
name: "ShellModule",
path: "Sources/Shared/Package/ShellModule"
),
.target(
name: "SwiftPackageFileHelperModule",
dependencies: ["FileHandlingModule", "ShellModule", "PADLogging"],
path: "Sources/Shared/Package/SwiftPackageFileHelperModule"
),

// MARK: - Test Targets

.testTarget(
name: "UnitTests",
dependencies: ["public-api-diff"],
dependencies: [
"public-api-diff"
],
resources: [
// Copy Tests/ExampleTests/Resources directories as-is.
// Use to retain directory structure.
// Will be at top level in bundle.
.copy("Resources/dummy.abi.json"),
.copy("Resources/dummi-abi-flat-definition.md")
.copy("Resources/expected-reference-changes.md")
]
),
.testTarget(
Expand All @@ -40,7 +142,8 @@ let package = Package(
// Copy Tests/ExampleTests/Resources directories as-is.
// Use to retain directory structure.
// Will be at top level in bundle.
.copy("Resources/expected-reference-changes.md")
.copy("Resources/expected-reference-changes-swift-interface-private.md"),
.copy("Resources/expected-reference-changes-swift-interface-public.md")
]
)
]
Expand Down
96 changes: 52 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,52 @@
# Swift Public API diff

This tool allows comparing 2 versions of a swift package project and lists all changes in a human readable way.

It makes use of `xcrun swift-api-digester -dump-sdk` to create a dump of the public api of your swift package and then runs it through a custom parser to process them.

Alternatively you could use `xcrun swift-api-digester -diagnose-sdk` and pass the abi dumps into it.

## How it works

![image](https://github.com/user-attachments/assets/cc04d21a-06f6-42bc-8e73-4aef7af21d7a)


### Project Builder

Builds the swift package project which is required for the next step to run the `xcrun swift-api-digester -dump-sdk`

### ABIGenerator

Makes use of `xcrun swift-api-digester -dump-sdk` to "dump" the public interface into an abi.json file.

### SDKDumpGenerator

Parses the abi.json files into an `SDKDump` object

### SDKDumpAnalyzer

Analyzes 2 `SDKDump` objects and detects `addition`s & `removal`s.

### ChangeConsolidator

The `ChangeConsolidator` takes 2 independent changes (`addition` & `removal`) and tries to match them based on the name, declKind and parent.

| Match |
| --- |
| ![image](https://github.com/user-attachments/assets/f057c160-f85d-45af-b08f-203b89e43b41) |

| No Match | Potentially false positive |
| --- | --- |
| ![image](https://github.com/user-attachments/assets/5ae3b624-b32a-41cc-9026-8ba0117cec57) | ![image](https://github.com/user-attachments/assets/a7e60605-fc1c-49ef-a203-d6a5466a6fda) |

### OutputGenerator

Receives a list of `Change`s and processes them into a human readable format.
[![🧪 Run Tests](https://github.com/Adyen/adyen-swift-public-api-diff/actions/workflows/run-tests.yml/badge.svg)](https://github.com/Adyen/adyen-swift-public-api-diff/actions/workflows/run-tests.yml)

# Swift Public API diff

This tool allows comparing 2 versions of a swift (sdk) project and lists all changes in a human readable way.

It makes use of `.swiftinterface` files that get produced during the archiving of a swift project and parses them using [`swift-syntax`](https://github.com/swiftlang/swift-syntax).

## Usage

```
USAGE: public-api-diff --new <new> --old <old> [--output <output>] [--log-output <log-output>] [--scheme <scheme>]
OPTIONS:
--new <new> Specify the updated version to compare to
--old <old> Specify the old version to compare to
--output <output> Where to output the result (File path)
--log-output <log-output>
Where to output the logs (File path)
--scheme <scheme> Which scheme to build (Needed when comparing 2 xcode projects)
-h, --help Show help information.
```

### Run as debug build
```
swift run public-api-diff
--new "some/local/path"
--old "develop~https://github.com/some/repository"
--output "path/to/output.md"
```

### How to create a release build
```
swift build --configuration release
```

### Run release build
```
./public-api-diff
--new "some/local/path"
--old "develop~https://github.com/some/repository"
--output "path/to/output.md"
```

# Alternatives
- **swift-api-digester**
- `xcrun swift-api-digester -dump-sdk`
- `xcrun swift-api-digester -diagnose-sdk`

# Inspiration
- https://github.com/sdidla/Hatch/blob/main/Sources/Hatch/SymbolParser.swift
- For parsing swift files using [swift-syntax](https://github.com/swiftlang/swift-syntax)'s [`SyntaxVisitor`](https://github.com/swiftlang/swift-syntax/blob/main/Sources/SwiftSyntax/generated/SyntaxVisitor.swift)
Loading

0 comments on commit c138ff1

Please sign in to comment.