Skip to content

Conversation

lapfelix
Copy link

@lapfelix lapfelix commented Jun 8, 2025

C++ warnings with severity 1 were being classified as errors based solely on categoryIdent (e.g. "Parse Issue"), ignoring the severity field. Now uses severity to distinguish warnings (severity 1) from errors (severity 2+) for all ambiguous categories.

Added a test to cover this case.

To cover these warnings (which Xcode considered warnings in my build):
Screenshot 2025-06-07 at 9 09 37 PM

 C++ warnings with severity 1 were being classified as errors based solely on categoryIdent (e.g. "Parse Issue"), ignoring the severity field. Now uses severity to distinguish warnings (severity
  1) from errors (severity 2+) for all ambiguous categories.

Signed-off-by: lapfelix <felix@lapal.me>
lapfelix and others added 3 commits June 21, 2025 21:45
- Add support for 'SwiftCompile' signature pattern in BuildStep.swift
- Enhance subsection parsing in ParserBuildSteps.swift to check Swift compilation subsections for errors/warnings
- Relax location filtering in Notice+Parser.swift to allow errors from subsections with different document URLs
- Add support for 'No-usage' warnings to be correctly classified as Swift warnings
- Add RealTests directory with comprehensive testing framework for real build logs
- Test suite now correctly detects errors and warnings that were previously missed

Fixes issues where:
1. Swift compilation errors in subsections were not detected (e.g. type not found errors)
2. Swift warnings like unused variables were classified as notes instead of warnings
3. Different Swift compilation signature patterns were not recognized

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
lapfelix and others added 2 commits June 23, 2025 14:00
…ions

- Classify high-severity (2+) notes as errors in NoticeType.fromTitleAndSeverity()
- Fixes validation mismatches where Update Signing logs expected 2 errors but XCLogParser reported 0
- Provisioning errors like "No Account for Team" were being classified as notes despite severity 2+

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…uracy

- Add collectAndDeduplicateNotices() method to remove duplicate warnings/errors across build tree
- Fixes validation mismatches where identical warnings in multiple build targets were counted separately
- Improved validation accuracy from 67% to 91% (24 percentage point improvement)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@pepicrft pepicrft requested a review from Copilot June 25, 2025 15:10
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes the misclassification of C++ warnings as errors by incorporating severity into the log message parsing logic. Key changes include:

  • Updated tests in ParserTests.swift to verify that messages with severity 1 are handled as warnings and those with severity 2+ as errors.
  • Enhanced parsing logic in ParserBuildSteps.swift and Notice+Parser.swift to deduplicate and correctly merge notices, along with adjustments in NoticeType.swift and BuildStep.swift.
  • Added exit-code handling in CommandHandler.swift based on the build status.

Reviewed Changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Tests/XCLogParserTests/ParserTests.swift Added tests for ambiguous category message classification and Swift compilation error in subsections.
Sources/XCLogParser/parser/ParserBuildSteps.swift Updated notice deduplication and merge logic to account for subsection notices.
Sources/XCLogParser/parser/NoticeType.swift Added severity-based classification logic and a new case for “No-usage”.
Sources/XCLogParser/parser/Notice+Parser.swift Adjusted notice creation to utilize severity for determining notice type.
Sources/XCLogParser/parser/BuildStep.swift Added support for the new “SwiftCompile” prefix in build step type detection.
Sources/XCLogParser/commands/CommandHandler.swift Introduced exit-code handling to signal build failures appropriately.

Comment on lines +177 to +193
if let parentWarnings = notices?["warnings"], let subWarnings = subNotices["warnings"] {
notices?["warnings"] = parentWarnings + subWarnings
} else if let subWarnings = subNotices["warnings"] {
notices?["warnings"] = subWarnings
}

if let parentErrors = notices?["errors"], let subErrors = subNotices["errors"] {
notices?["errors"] = parentErrors + subErrors
} else if let subErrors = subNotices["errors"] {
notices?["errors"] = subErrors
}

if let parentNotes = notices?["notes"], let subNotes = subNotices["notes"] {
notices?["notes"] = parentNotes + subNotes
} else if let subNotes = subNotices["notes"] {
notices?["notes"] = subNotes
}
Copy link

Copilot AI Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merging logic for 'warnings', 'errors', and 'notes' is repeated for each key. Consider extracting this duplication into a helper function to improve code maintainability.

Suggested change
if let parentWarnings = notices?["warnings"], let subWarnings = subNotices["warnings"] {
notices?["warnings"] = parentWarnings + subWarnings
} else if let subWarnings = subNotices["warnings"] {
notices?["warnings"] = subWarnings
}
if let parentErrors = notices?["errors"], let subErrors = subNotices["errors"] {
notices?["errors"] = parentErrors + subErrors
} else if let subErrors = subNotices["errors"] {
notices?["errors"] = subErrors
}
if let parentNotes = notices?["notes"], let subNotes = subNotices["notes"] {
notices?["notes"] = parentNotes + subNotes
} else if let subNotes = subNotices["notes"] {
notices?["notes"] = subNotes
}
notices = mergeNotices(parentNotices: notices, subNotices: subNotices, key: "warnings")
notices = mergeNotices(parentNotices: notices, subNotices: subNotices, key: "errors")
notices = mergeNotices(parentNotices: notices, subNotices: subNotices, key: "notes")

Copilot uses AI. Check for mistakes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good advice. I'd also extract the logic into a method since the method is getting very deeply nested.

}
}

private func shouldExitWithFailureCode(buildSteps: BuildStep) -> Bool {
Copy link

Copilot AI Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The exit logic based on a lowercased build status string may be brittle if more status values are introduced. Consider clarifying or centralizing build status definitions to make the check more robust.

Copilot uses AI. Check for mistakes.

@lapfelix
Copy link
Author

Oh woops I forgot I had this PR open and kept committing more fixes I needed to my master branch

Copy link
Collaborator

@pepicrft pepicrft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I'm new to the repository though, so I'd appreciate an extra 👀 . @AvdLee perhaps?

/// Collects all warnings and errors from a BuildStep tree and deduplicates them
/// - parameter buildStep: The root BuildStep to collect notices from
/// - returns: A tuple of (warnings, errors) arrays with duplicates removed
private func collectAndDeduplicateNotices(from buildStep: BuildStep) -> ([Notice], [Notice]) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not obvious from the caller what the items in the tuple represent:

Suggested change
private func collectAndDeduplicateNotices(from buildStep: BuildStep) -> ([Notice], [Notice]) {
private func collectAndDeduplicateNotices(from buildStep: BuildStep) -> (warnings: [Notice], errors: [Notice]) {

Comment on lines +177 to +193
if let parentWarnings = notices?["warnings"], let subWarnings = subNotices["warnings"] {
notices?["warnings"] = parentWarnings + subWarnings
} else if let subWarnings = subNotices["warnings"] {
notices?["warnings"] = subWarnings
}

if let parentErrors = notices?["errors"], let subErrors = subNotices["errors"] {
notices?["errors"] = parentErrors + subErrors
} else if let subErrors = subNotices["errors"] {
notices?["errors"] = subErrors
}

if let parentNotes = notices?["notes"], let subNotes = subNotices["notes"] {
notices?["notes"] = parentNotes + subNotes
} else if let subNotes = subNotices["notes"] {
notices?["notes"] = subNotes
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good advice. I'd also extract the logic into a method since the method is getting very deeply nested.


# Xcode 11
.swiftpm/
RealTests/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'll remove it. What I did is I gathered a few hundred xcactivitylogs from DerivedData, put them in that RealTests folder, along with their LogStoreManifest.plist. Then had a script that ran XCLogParser on them and compared the # of warnings and errors. I then iterated on that to get it to match as much as possible. I'd need to check the xcactivitylogs to see if there's private info in there (like my global env vars). It started with 80% match and I got to 99.1% match.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't manually reviewed the code yet like I did for this PR (I had Claude Code iterate on that loop to increase the % of matching), but I just pushed the changes done to reach 99.1% on my local xcactivitylogs here: master...lapfelix:XCLogParser:feature/fine-tuned-warnings-to-match-xcode

I can review and clean up what's in there, but I do think there's value in testing real xcactivitylogs against what's in LogStoreManifest.plist.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'll remove it. What I did is I gathered a few hundred xcactivitylogs from DerivedData, put them in that RealTests folder, along with their LogStoreManifest.plist. Then had a script that ran XCLogParser on them and compared the # of warnings and errors. I then iterated on that to get it to match as much as possible. I'd need to check the xcactivitylogs to see if there's private info in there (like my global env vars). It started with 80% match and I got to 99.1% match.

If we just had a standardized machine-readable format from Apple... 🤦🏼

I haven't manually reviewed the code yet like I did for this PR (I had Claude Code iterate on that loop to increase the % of matching), but I just pushed the changes done to reach 99.1% on my local xcactivitylogs here: master...lapfelix:XCLogParser:feature/fine-tuned-warnings-to-match-xcode

That sounds fair! I trust you. I'd do a bit of clean up of the code and get an extra review and I'd say we are ready to merge.

Copy link
Collaborator

@AvdLee AvdLee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, great job!

@AvdLee
Copy link
Collaborator

AvdLee commented Sep 11, 2025

@lapfelix I'm ready to merge this in, but the checks are failing. Would you see a moment to check and solve accordingly? 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants