Skip to content

Commit 02abbf8

Browse files
fortmarekclaude
andcommitted
fix: make BuildOperationMetrics fields tolerant of missing keys
Xcode projects using `betaFeature_enableExplicitModules` produce xcactivitylog files where BuildOperationMetrics may not contain all expected keys (e.g. clangCacheHits). This causes a DecodingError when parsing these logs. Add a custom Decodable initializer that uses decodeIfPresent with a default of 0 for each field, so parsing succeeds even when keys are absent. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: fortmarek <marekfort@me.com>
1 parent 5c5b5bd commit 02abbf8

2 files changed

Lines changed: 38 additions & 4 deletions

File tree

Sources/XCLogParser/activityparser/IDEActivityModel.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -780,15 +780,23 @@ public class IDEActivityLogSectionAttachment: Encodable {
780780
public let swiftCacheMisses: Int
781781

782782
public init(
783-
clangCacheHits: Int,
784-
clangCacheMisses: Int,
785-
swiftCacheHits: Int,
786-
swiftCacheMisses: Int
783+
clangCacheHits: Int = 0,
784+
clangCacheMisses: Int = 0,
785+
swiftCacheHits: Int = 0,
786+
swiftCacheMisses: Int = 0
787787
) {
788788
self.clangCacheHits = clangCacheHits
789789
self.clangCacheMisses = clangCacheMisses
790790
self.swiftCacheHits = swiftCacheHits
791791
self.swiftCacheMisses = swiftCacheMisses
792792
}
793+
794+
public init(from decoder: Decoder) throws {
795+
let container = try decoder.container(keyedBy: CodingKeys.self)
796+
clangCacheHits = try container.decodeIfPresent(Int.self, forKey: .clangCacheHits) ?? 0
797+
clangCacheMisses = try container.decodeIfPresent(Int.self, forKey: .clangCacheMisses) ?? 0
798+
swiftCacheHits = try container.decodeIfPresent(Int.self, forKey: .swiftCacheHits) ?? 0
799+
swiftCacheMisses = try container.decodeIfPresent(Int.self, forKey: .swiftCacheMisses) ?? 0
800+
}
793801
}
794802
}

Tests/XCLogParserTests/ActivityParserTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,30 @@ class ActivityParserTests: XCTestCase {
562562
XCTAssertEqual(expectedDVTMemberDocumentLocation, documentMemberLocation)
563563
}
564564

565+
func testBuildOperationMetricsWithMissingKeys() throws {
566+
let json = #"{}"#
567+
let data = json.data(using: .utf8)!
568+
let metrics = try JSONDecoder().decode(
569+
IDEActivityLogSectionAttachment.BuildOperationMetrics.self,
570+
from: data
571+
)
572+
XCTAssertEqual(metrics.clangCacheHits, 0)
573+
XCTAssertEqual(metrics.clangCacheMisses, 0)
574+
XCTAssertEqual(metrics.swiftCacheHits, 0)
575+
XCTAssertEqual(metrics.swiftCacheMisses, 0)
576+
}
577+
578+
func testBuildOperationMetricsWithPartialKeys() throws {
579+
let json = #"{"swiftCacheHits":5,"swiftCacheMisses":3}"#
580+
let data = json.data(using: .utf8)!
581+
let metrics = try JSONDecoder().decode(
582+
IDEActivityLogSectionAttachment.BuildOperationMetrics.self,
583+
from: data
584+
)
585+
XCTAssertEqual(metrics.clangCacheHits, 0)
586+
XCTAssertEqual(metrics.clangCacheMisses, 0)
587+
XCTAssertEqual(metrics.swiftCacheHits, 5)
588+
XCTAssertEqual(metrics.swiftCacheMisses, 3)
589+
}
590+
565591
}

0 commit comments

Comments
 (0)