Skip to content

Commit efac16c

Browse files
authored
Adding change breakdown to markdown output (#77)
1 parent 6dfca73 commit efac16c

File tree

10 files changed

+119
-70
lines changed

10 files changed

+119
-70
lines changed

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/PublicModules/PADOutputGenerator/MarkdownOutputGenerator.swift

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public struct MarkdownOutputGenerator: OutputGenerating {
3131
if let oldVersionName, let newVersionName {
3232
lines += [Self.repoInfo(oldVersionName: oldVersionName, newVersionName: newVersionName)]
3333
}
34+
35+
if !changes.isEmpty {
36+
lines += [Self.totalChangesBreakdown(changesPerTarget: changesPerTarget)]
37+
}
3438

3539
lines += [separator]
3640

@@ -62,8 +66,29 @@ private extension MarkdownOutputGenerator {
6266
return "# ✅ No changes detected"
6367
}
6468

65-
let totalChangeCount = changesPerTarget.totalChangeCount
66-
return "# 👀 \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected"
69+
let totalChangeCount = changesPerTarget.totalCount(for: .allChanges)
70+
71+
if changesPerTarget.potentiallyBreakingChangesCount > 0 {
72+
return "# ⚠️ \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected ⚠️"
73+
} else {
74+
return "# 👀 \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected"
75+
}
76+
}
77+
78+
static func totalChangesBreakdown(changesPerTarget: [String: [Change]]) -> String {
79+
80+
let additions = changesPerTarget.totalCount(for: .additions)
81+
let changes = changesPerTarget.totalCount(for: .modifications)
82+
let removals = changesPerTarget.totalCount(for: .removals)
83+
84+
guard additions + changes + removals > 0 else { return "" }
85+
86+
var breakdown = "<table>"
87+
if additions > 0 { breakdown += "<tr><td>❇️</td><td><b>\(additions) \(additions == 1 ? "Addition" : "Additions")</b></td></tr>" }
88+
if changes > 0 { breakdown += "<tr><td>🔀</td><td><b>\(changes) \(changes == 1 ? "Modification" : "Modifications")</b></td></tr>" }
89+
if removals > 0 { breakdown += "<tr><td>❌</td><td><b>\(removals) \(removals == 1 ? "Removal" : "Removals")</b></td></tr>" }
90+
breakdown += "</table>"
91+
return breakdown
6792
}
6893

6994
static func repoInfo(oldVersionName: String, newVersionName: String) -> String {
@@ -106,11 +131,11 @@ private extension MarkdownOutputGenerator {
106131
changes: changes.filter(\.changeType.isAddition)
107132
)
108133
let changeLines = changeSectionLines(
109-
title: "#### 🔀 Changed",
110-
changes: changes.filter(\.changeType.isChange)
134+
title: "#### 🔀 Modified",
135+
changes: changes.filter(\.changeType.isModification)
111136
)
112137
let removalLines = changeSectionLines(
113-
title: "#### 😶‍🌫️ Removed",
138+
title: "#### Removed",
114139
changes: changes.filter(\.changeType.isRemoval)
115140
)
116141

@@ -157,18 +182,38 @@ private extension MarkdownOutputGenerator {
157182
return description
158183
case let .removal(description):
159184
return description
160-
case let .change(before, after):
185+
case let .modification(before, after):
161186
return "// From\n\(before)\n\n// To\n\(after)"
162187
}
163188
}
164189
}
165190

166191
private extension [String: [Change]] {
167192

168-
var totalChangeCount: Int {
193+
enum ChangeCountType {
194+
case allChanges
195+
case additions
196+
case modifications
197+
case removals
198+
}
199+
200+
var potentiallyBreakingChangesCount: Int {
201+
return totalCount(for: .modifications) + totalCount(for: .removals)
202+
}
203+
204+
func totalCount(for countType: ChangeCountType) -> Int {
169205
var totalChangeCount = 0
170206
keys.forEach { targetName in
171-
totalChangeCount += self[targetName]?.count ?? 0
207+
switch countType {
208+
case .allChanges:
209+
totalChangeCount += self[targetName]?.count ?? 0
210+
case .additions:
211+
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isAddition ? 1 : 0) }) ?? 0
212+
case .modifications:
213+
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isModification ? 1 : 0) }) ?? 0
214+
case .removals:
215+
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isRemoval ? 1 : 0) }) ?? 0
216+
}
172217
}
173218
return totalChangeCount
174219
}

Sources/PublicModules/PADPackageFileAnalyzer/SwiftPackageFileAnalyzer.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private extension SwiftPackageFileAnalyzer {
124124
guard let new, let old else { return [] }
125125

126126
return [.init(
127-
changeType: .change(
127+
changeType: .modification(
128128
oldDescription: "\(keyName): \"\(old)\"",
129129
newDescription: "\(keyName): \"\(new)\""
130130
),
@@ -143,7 +143,7 @@ private extension SwiftPackageFileAnalyzer {
143143
let keyName = "name"
144144

145145
return [.init(
146-
changeType: .change(
146+
changeType: .modification(
147147
oldDescription: "\(keyName): \"\(old)\"",
148148
newDescription: "\(keyName): \"\(new)\""
149149
),
@@ -191,7 +191,7 @@ private extension SwiftPackageFileAnalyzer {
191191
let newPlatformsString = new.map { "\($0.description)" }.joined(separator: ", ")
192192

193193
return [.init(
194-
changeType: .change(
194+
changeType: .modification(
195195
oldDescription: "platforms: [\(oldPlatformsString)]",
196196
newDescription: "platforms: [\(newPlatformsString)]"
197197
),
@@ -265,7 +265,7 @@ private extension SwiftPackageFileAnalyzer {
265265
listOfChanges += removed.map { "Removed target \"\($0)\"" }
266266

267267
return [.init(
268-
changeType: .change(
268+
changeType: .modification(
269269
oldDescription: oldProduct.description,
270270
newDescription: newProduct.description
271271
),
@@ -360,7 +360,7 @@ private extension SwiftPackageFileAnalyzer {
360360
listOfChanges += removedProductDependencies.map { "Removed dependency .product(name: \"\($0)\", ...)" }
361361

362362
return [.init(
363-
changeType: .change(
363+
changeType: .modification(
364364
oldDescription: oldTarget.description,
365365
newDescription: newTarget.description
366366
),
@@ -425,7 +425,7 @@ private extension SwiftPackageFileAnalyzer {
425425
guard oldDependency != newDependency else { return [] }
426426

427427
return [.init(
428-
changeType: .change(
428+
changeType: .modification(
429429
oldDescription: oldDependency.description,
430430
newDescription: newDependency.description
431431
),
@@ -443,7 +443,7 @@ private extension SwiftPackageFileAnalyzer {
443443
guard old != new else { return [] }
444444

445445
return [.init(
446-
changeType: .change(
446+
changeType: .modification(
447447
oldDescription: "// swift-tools-version: \(old)",
448448
newDescription: "// swift-tools-version: \(new)"
449449
),

Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceAnalyzer/SwiftInterfaceChangeConsolidator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct SwiftInterfaceChangeConsolidator: SwiftInterfaceChangeConsolidating {
5858

5959
consolidatedChanges.append(
6060
.init(
61-
changeType: .change(
61+
changeType: .modification(
6262
oldDescription: oldDescription,
6363
newDescription: newDescription
6464
),

Sources/PublicModules/PADSwiftInterfaceDiff/SwiftInterfaceParser/SwiftInterfaceElement/SwiftInterfaceElement+DiffHelper.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extension SwiftInterfaceElement {
3131
}
3232

3333
switch changeType {
34-
case let .change(old, new):
34+
case let .modification(old, new):
3535
diffDescription += " from `\(old)` to `\(new)`"
3636
case let .removal(string):
3737
diffDescription += " `\(string)`"
@@ -74,21 +74,21 @@ extension SwiftInterfaceElement {
7474

7575
/// File-private helper to produce detailed descriptions
7676
private enum ChangeType {
77-
case change(old: String, new: String)
77+
case modification(old: String, new: String)
7878
case removal(String)
7979
case addition(String)
8080

8181
var title: String {
8282
switch self {
83-
case .change: "Changed"
83+
case .modification: "Modified"
8484
case .removal: "Removed"
8585
case .addition: "Added"
8686
}
8787
}
8888

8989
static func `for`(oldValue: String?, newValue: String?) -> Self? {
9090
if oldValue == newValue { return nil }
91-
if let oldValue, let newValue { return .change(old: oldValue, new: newValue) }
91+
if let oldValue, let newValue { return .modification(old: oldValue, new: newValue) }
9292
if let oldValue { return .removal(oldValue) }
9393
if let newValue { return .addition(newValue) }
9494
return nil

Sources/Shared/Public/PADCore/Change.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public struct Change: Equatable {
1111
public enum ChangeType: Equatable {
1212
case addition(description: String)
1313
case removal(description: String)
14-
case change(oldDescription: String, newDescription: String)
14+
case modification(oldDescription: String, newDescription: String)
1515
}
1616

1717
public private(set) var changeType: ChangeType
@@ -38,7 +38,7 @@ extension Change.ChangeType {
3838
return true
3939
case .removal:
4040
return false
41-
case .change:
41+
case .modification:
4242
return false
4343
}
4444
}
@@ -49,18 +49,18 @@ extension Change.ChangeType {
4949
return false
5050
case .removal:
5151
return true
52-
case .change:
52+
case .modification:
5353
return false
5454
}
5555
}
5656

57-
public var isChange: Bool {
57+
public var isModification: Bool {
5858
switch self {
5959
case .addition:
6060
return false
6161
case .removal:
6262
return false
63-
case .change:
63+
case .modification:
6464
return true
6565
}
6666
}

0 commit comments

Comments
 (0)