Skip to content

Commit

Permalink
Adding change breakdown to markdown output (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
goergisn authored Jan 2, 2025
1 parent 6dfca73 commit efac16c
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 70 deletions.
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/nicklockwood/SwiftFormat",
"state" : {
"revision" : "2d5a2b6bde636c1feae2c852ab9a50f221e98c66",
"version" : "0.55.3"
"revision" : "4e92b81311f528cfdca8015d629c650d0aff94ce",
"version" : "0.55.4"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public struct MarkdownOutputGenerator: OutputGenerating {
if let oldVersionName, let newVersionName {
lines += [Self.repoInfo(oldVersionName: oldVersionName, newVersionName: newVersionName)]
}

if !changes.isEmpty {
lines += [Self.totalChangesBreakdown(changesPerTarget: changesPerTarget)]
}

lines += [separator]

Expand Down Expand Up @@ -62,8 +66,29 @@ private extension MarkdownOutputGenerator {
return "# ✅ No changes detected"
}

let totalChangeCount = changesPerTarget.totalChangeCount
return "# 👀 \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected"
let totalChangeCount = changesPerTarget.totalCount(for: .allChanges)

if changesPerTarget.potentiallyBreakingChangesCount > 0 {
return "# ⚠️ \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected ⚠️"
} else {
return "# 👀 \(totalChangeCount) public \(totalChangeCount == 1 ? "change" : "changes") detected"
}
}

static func totalChangesBreakdown(changesPerTarget: [String: [Change]]) -> String {

let additions = changesPerTarget.totalCount(for: .additions)
let changes = changesPerTarget.totalCount(for: .modifications)
let removals = changesPerTarget.totalCount(for: .removals)

guard additions + changes + removals > 0 else { return "" }

var breakdown = "<table>"
if additions > 0 { breakdown += "<tr><td>❇️</td><td><b>\(additions) \(additions == 1 ? "Addition" : "Additions")</b></td></tr>" }
if changes > 0 { breakdown += "<tr><td>🔀</td><td><b>\(changes) \(changes == 1 ? "Modification" : "Modifications")</b></td></tr>" }
if removals > 0 { breakdown += "<tr><td>❌</td><td><b>\(removals) \(removals == 1 ? "Removal" : "Removals")</b></td></tr>" }
breakdown += "</table>"
return breakdown
}

static func repoInfo(oldVersionName: String, newVersionName: String) -> String {
Expand Down Expand Up @@ -106,11 +131,11 @@ private extension MarkdownOutputGenerator {
changes: changes.filter(\.changeType.isAddition)
)
let changeLines = changeSectionLines(
title: "#### 🔀 Changed",
changes: changes.filter(\.changeType.isChange)
title: "#### 🔀 Modified",
changes: changes.filter(\.changeType.isModification)
)
let removalLines = changeSectionLines(
title: "#### 😶‍🌫️ Removed",
title: "#### Removed",
changes: changes.filter(\.changeType.isRemoval)
)

Expand Down Expand Up @@ -157,18 +182,38 @@ private extension MarkdownOutputGenerator {
return description
case let .removal(description):
return description
case let .change(before, after):
case let .modification(before, after):
return "// From\n\(before)\n\n// To\n\(after)"
}
}
}

private extension [String: [Change]] {

var totalChangeCount: Int {
enum ChangeCountType {
case allChanges
case additions
case modifications
case removals
}

var potentiallyBreakingChangesCount: Int {
return totalCount(for: .modifications) + totalCount(for: .removals)
}

func totalCount(for countType: ChangeCountType) -> Int {
var totalChangeCount = 0
keys.forEach { targetName in
totalChangeCount += self[targetName]?.count ?? 0
switch countType {
case .allChanges:
totalChangeCount += self[targetName]?.count ?? 0
case .additions:
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isAddition ? 1 : 0) }) ?? 0
case .modifications:
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isModification ? 1 : 0) }) ?? 0
case .removals:
totalChangeCount += self[targetName]?.reduce(0, { $0 + ($1.changeType.isRemoval ? 1 : 0) }) ?? 0
}
}
return totalChangeCount
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private extension SwiftPackageFileAnalyzer {
guard let new, let old else { return [] }

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: "\(keyName): \"\(old)\"",
newDescription: "\(keyName): \"\(new)\""
),
Expand All @@ -143,7 +143,7 @@ private extension SwiftPackageFileAnalyzer {
let keyName = "name"

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: "\(keyName): \"\(old)\"",
newDescription: "\(keyName): \"\(new)\""
),
Expand Down Expand Up @@ -191,7 +191,7 @@ private extension SwiftPackageFileAnalyzer {
let newPlatformsString = new.map { "\($0.description)" }.joined(separator: ", ")

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: "platforms: [\(oldPlatformsString)]",
newDescription: "platforms: [\(newPlatformsString)]"
),
Expand Down Expand Up @@ -265,7 +265,7 @@ private extension SwiftPackageFileAnalyzer {
listOfChanges += removed.map { "Removed target \"\($0)\"" }

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: oldProduct.description,
newDescription: newProduct.description
),
Expand Down Expand Up @@ -360,7 +360,7 @@ private extension SwiftPackageFileAnalyzer {
listOfChanges += removedProductDependencies.map { "Removed dependency .product(name: \"\($0)\", ...)" }

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: oldTarget.description,
newDescription: newTarget.description
),
Expand Down Expand Up @@ -425,7 +425,7 @@ private extension SwiftPackageFileAnalyzer {
guard oldDependency != newDependency else { return [] }

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: oldDependency.description,
newDescription: newDependency.description
),
Expand All @@ -443,7 +443,7 @@ private extension SwiftPackageFileAnalyzer {
guard old != new else { return [] }

return [.init(
changeType: .change(
changeType: .modification(
oldDescription: "// swift-tools-version: \(old)",
newDescription: "// swift-tools-version: \(new)"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct SwiftInterfaceChangeConsolidator: SwiftInterfaceChangeConsolidating {

consolidatedChanges.append(
.init(
changeType: .change(
changeType: .modification(
oldDescription: oldDescription,
newDescription: newDescription
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension SwiftInterfaceElement {
}

switch changeType {
case let .change(old, new):
case let .modification(old, new):
diffDescription += " from `\(old)` to `\(new)`"
case let .removal(string):
diffDescription += " `\(string)`"
Expand Down Expand Up @@ -74,21 +74,21 @@ extension SwiftInterfaceElement {

/// File-private helper to produce detailed descriptions
private enum ChangeType {
case change(old: String, new: String)
case modification(old: String, new: String)
case removal(String)
case addition(String)

var title: String {
switch self {
case .change: "Changed"
case .modification: "Modified"
case .removal: "Removed"
case .addition: "Added"
}
}

static func `for`(oldValue: String?, newValue: String?) -> Self? {
if oldValue == newValue { return nil }
if let oldValue, let newValue { return .change(old: oldValue, new: newValue) }
if let oldValue, let newValue { return .modification(old: oldValue, new: newValue) }
if let oldValue { return .removal(oldValue) }
if let newValue { return .addition(newValue) }
return nil
Expand Down
10 changes: 5 additions & 5 deletions Sources/Shared/Public/PADCore/Change.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public struct Change: Equatable {
public enum ChangeType: Equatable {
case addition(description: String)
case removal(description: String)
case change(oldDescription: String, newDescription: String)
case modification(oldDescription: String, newDescription: String)
}

public private(set) var changeType: ChangeType
Expand All @@ -38,7 +38,7 @@ extension Change.ChangeType {
return true
case .removal:
return false
case .change:
case .modification:
return false
}
}
Expand All @@ -49,18 +49,18 @@ extension Change.ChangeType {
return false
case .removal:
return true
case .change:
case .modification:
return false
}
}

public var isChange: Bool {
public var isModification: Bool {
switch self {
case .addition:
return false
case .removal:
return false
case .change:
case .modification:
return true
}
}
Expand Down
Loading

0 comments on commit efac16c

Please sign in to comment.