Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Sources/XCLogParser/parser/ParserBuildSteps.swift
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ public final class ParserBuildSteps {
private func addCompilationTimesToTarget(_ target: BuildStep) -> BuildStep {

let lastCompilationStep = target.subSteps
.filter { $0.isCompilationStep() && $0.fetchedFromCache == false }
.filter { $0.isCompilationStep() && $0.fetchedFromCache == false &&
$0.compilationEndTimestamp >= target.startTimestamp }
.max { $0.compilationEndTimestamp < $1.compilationEndTimestamp }
guard let lastStep = lastCompilationStep else {
return target.with(newCompilationEndTimestamp: target.startTimestamp, andCompilationDuration: 0.0)
Expand All @@ -385,7 +386,8 @@ public final class ParserBuildSteps {

private func addCompilationTimesToApp(_ app: BuildStep) -> BuildStep {
let lastCompilationStep = app.subSteps
.filter { $0.compilationDuration > 0 && $0.fetchedFromCache == false }
.filter { $0.compilationDuration > 0 && $0.fetchedFromCache == false &&
$0.compilationEndTimestamp >= app.startTimestamp }
.max { $0.compilationEndTimestamp < $1.compilationEndTimestamp }
guard let lastStep = lastCompilationStep else {
return app.with(newCompilationEndTimestamp: app.startTimestamp,
Expand Down
25 changes: 25 additions & 0 deletions Tests/XCLogParserTests/ParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,31 @@ note: use 'updatedDoSomething' instead\r doSomething()\r ^~~~~~~~~~~\r
XCTAssertEqual(expectedCompilationDuration, targetStep.compilationDuration)
}

func testParseTargetCompilationTimesIgnoresStaleSubsteps() {
// For incremental builds, Xcode reuses substep entries from previous build sessions for
// files that didn't need recompilation. Those substeps keep their original (older)
// timestamps and are not flagged `wasFetchedFromCache`. The target's compilationDuration
// must remain non-negative; substeps that ended before the target started belong to a
// prior session and should be ignored.
let now = Date().timeIntervalSince1970
let staleCompileEnd = now - 1000
let staleStep = makeFakeBuildStep(title: "Stale Compile",
type: .detail,
detailStepType: .cCompilation,
startTimestamp: now - 1010,
fetchedFromCache: false)
.with(newCompilationEndTimestamp: staleCompileEnd, andCompilationDuration: 10)
var targetStep = makeFakeBuildStep(title: "Build Target",
type: .target,
detailStepType: .none,
startTimestamp: now,
fetchedFromCache: false).with(subSteps: [staleStep])

targetStep = parser.addCompilationTimes(step: targetStep)
XCTAssertEqual(targetStep.startTimestamp, targetStep.compilationEndTimestamp)
XCTAssertEqual(0.0, targetStep.compilationDuration)
}

func testParseAppCompilationTimes() {
let expectedCompilationDuration = 50.0
let now = Date().timeIntervalSince1970
Expand Down
Loading