Repository: cpisciotta/xcbeautify (swift)

Issue:
[New Output] Support SwiftDriverJobDiscovery Output
### What's the uncaptured output?

```
SwiftDriverJobDiscovery normal arm64 Compiling _AsyncTimerSequence.swift (in target 'Clocks' from project 'swift-clocks')
```
```
SwiftDriverJobDiscovery normal i386 Compiling _AsyncTimerSequence.swift (in target 'Clocks' from project 'swift-clocks')
```
```
SwiftDriverJobDiscovery normal x86_64 Compiling _AsyncTimerSequence.swift (in target 'Clocks' from project 'swift-clocks')
```

### Suggested Regex

_No response_

### Suggested Output

_No response_

### Additional Context

_No response_

Pull request description:
## Changes

Add a concrete `CaptureGroup` for `SwiftDriverJobDiscovery` output. At this time, don't format it, since it's likely uninformative to a developer.

## Testing

- Added new unit tests
- Performance regression tests showed notably positive improvements
- No unexpectedly missed output in the formatted log

Patch:
diff --git a/Sources/XcbeautifyLib/CaptureGroups.swift b/Sources/XcbeautifyLib/CaptureGroups.swift
index 96be7510..30537c24 100644
--- a/Sources/XcbeautifyLib/CaptureGroups.swift
+++ b/Sources/XcbeautifyLib/CaptureGroups.swift
@@ -1797,3 +1797,36 @@ struct SwiftDriverJobDiscoveryEmittingModuleCaptureGroup: CaptureGroup {
 
     init?(groups: [String]) { }
 }
+
+struct SwiftDriverJobDiscoveryCompilingCaptureGroup: CaptureGroup {
+    static let outputType: OutputType = .task
+
+    // Examples:
+    //  - SwiftDriverJobDiscovery normal arm64 Compiling BackyardBirdsPassOfferCard.swift (in target 'BackyardBirdsUI' from project 'BackyardBirdsUI')
+    //  - SwiftDriverJobDiscovery normal arm64 Compiling BackyardSkyView.swift, BackyardSupplyGauge.swift (in target 'BackyardBirdsUI' from project 'BackyardBirdsUI')
+    //  - SwiftDriverJobDiscovery normal x86_64 Compiling resource_bundle_accessor.swift, Account+DataGeneration.swift, Backyard.swift (in target 'SomeTarget' from project 'SomeProject')
+    //
+    // Regular expression captured groups:
+    // $1 = state
+    // $2 = architecture
+    // $3 = filenames
+    // $4 = target
+    // $5 = project
+    static let regex = Regex(pattern: #"^SwiftDriverJobDiscovery (\S+) (\S+) Compiling ((?:\S|(?>, )|(?<=\\) )+) \(in target '(.*)' from project '(.*)'\)"#)
+
+    let state: String // Currently, the only expected/known value is `normal`
+    let architecture: String
+    let filenames: [String]
+    let target: String
+    let project: String
+
+    init?(groups: [String]) {
+        assert(groups.count == 5)
+        guard let state = groups[safe: 0], let architecture = groups[safe: 1], let filenamesGroup = groups[safe: 2], let target = groups[safe: 3], let project = groups[safe: 4] else { return nil }
+        self.state = state
+        self.architecture = architecture
+        filenames = filenamesGroup.components(separatedBy: ", ")
+        self.target = target
+        self.project = project
+    }
+}
diff --git a/Sources/XcbeautifyLib/Formatter.swift b/Sources/XcbeautifyLib/Formatter.swift
index b79296b7..54d82f81 100644
--- a/Sources/XcbeautifyLib/Formatter.swift
+++ b/Sources/XcbeautifyLib/Formatter.swift
@@ -206,6 +206,8 @@ package struct Formatter {
             return renderer.formatError(group: group)
         case let group as SwiftDriverJobDiscoveryEmittingModuleCaptureGroup:
             return renderer.formatSwiftDriverJobDiscoveryEmittingModule(group: group)
+        case let group as SwiftDriverJobDiscoveryCompilingCaptureGroup:
+            return renderer.formatSwiftDriverJobDiscoveryCompiling(group: group)
         default:
             assertionFailure()
             return nil
diff --git a/Sources/XcbeautifyLib/Parser.swift b/Sources/XcbeautifyLib/Parser.swift
index 46848fb2..daad0c7d 100644
--- a/Sources/XcbeautifyLib/Parser.swift
+++ b/Sources/XcbeautifyLib/Parser.swift
@@ -90,6 +90,7 @@ package final class Parser {
         PackageGraphResolvedItemCaptureGroup.self,
         DuplicateLocalizedStringKeyCaptureGroup.self,
         SwiftDriverJobDiscoveryEmittingModuleCaptureGroup.self,
+        SwiftDriverJobDiscoveryCompilingCaptureGroup.self,
         ExecutedWithoutSkippedCaptureGroup.self,
         ExecutedWithSkippedCaptureGroup.self,
         TestSuiteAllTestsPassedCaptureGroup.self,
diff --git a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
index 1b8bd6e6..3bfa47ef 100644
--- a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
+++ b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
@@ -82,6 +82,7 @@ protocol OutputRendering {
     func formatWriteAuxiliaryFile(group: WriteAuxiliaryFileCaptureGroup) -> String?
     func formatWriteFile(group: WriteFileCaptureGroup) -> String?
     func formatSwiftDriverJobDiscoveryEmittingModule(group: SwiftDriverJobDiscoveryEmittingModuleCaptureGroup) -> String?
+    func formatSwiftDriverJobDiscoveryCompiling(group: SwiftDriverJobDiscoveryCompilingCaptureGroup) -> String?
 }
 
 extension OutputRendering {
@@ -348,6 +349,10 @@ extension OutputRendering {
         nil
     }
 
+    func formatSwiftDriverJobDiscoveryCompiling(group: SwiftDriverJobDiscoveryCompilingCaptureGroup) -> String? {
+        nil
+    }
+
     func formatFailingTest(group: FailingTestCaptureGroup) -> String {
         let testCase = group.testCase
         let failingReason = group.reason


Test patch:
diff --git a/Tests/XcbeautifyLibTests/ParserTests.swift b/Tests/XcbeautifyLibTests/ParserTests.swift
index fc25fdd1..85c3c5c9 100644
--- a/Tests/XcbeautifyLibTests/ParserTests.swift
+++ b/Tests/XcbeautifyLibTests/ParserTests.swift
@@ -40,4 +40,24 @@ final class ParserTests: XCTestCase {
         XCTAssertEqual(captureGroup.secondFilename, "Backyard_Birds.abi.json")
         XCTAssertEqual(captureGroup.target, "Backyard Birds")
     }
+
+    func testMatchSwiftDriverJobDiscoveryCompilingCaptureGroupOneFile() throws {
+        let input = #"SwiftDriverJobDiscovery normal arm64 Compiling resource_bundle_accessor.swift (in target 'Some Target' from project 'Some Project')"#
+        let captureGroup = try XCTUnwrap(parser.parse(line: input) as? SwiftDriverJobDiscoveryCompilingCaptureGroup)
+        XCTAssertEqual(captureGroup.state, "normal")
+        XCTAssertEqual(captureGroup.architecture, "arm64")
+        XCTAssertEqual(captureGroup.filenames, ["resource_bundle_accessor.swift"])
+        XCTAssertEqual(captureGroup.target, "Some Target")
+        XCTAssertEqual(captureGroup.project, "Some Project")
+    }
+
+    func testMatchSwiftDriverJobDiscoveryCompilingCaptureGroupMultipleFiles() throws {
+        let input = #"SwiftDriverJobDiscovery normal x86_64 Compiling BackyardVisitorEvent+DataGeneration.swift, BackyardVisitors\ &\ Events.swift, Bird+DataGeneration.swift, Bird.swift (in target 'BackyardBirdsDataTarget' from project 'BackyardBirdsDataProject')"#
+        let captureGroup = try XCTUnwrap(parser.parse(line: input) as? SwiftDriverJobDiscoveryCompilingCaptureGroup)
+        XCTAssertEqual(captureGroup.state, "normal")
+        XCTAssertEqual(captureGroup.architecture, "x86_64")
+        XCTAssertEqual(captureGroup.filenames, ["BackyardVisitorEvent+DataGeneration.swift", #"BackyardVisitors\ &\ Events.swift"#, "Bird+DataGeneration.swift", "Bird.swift"])
+        XCTAssertEqual(captureGroup.target, "BackyardBirdsDataTarget")
+        XCTAssertEqual(captureGroup.project, "BackyardBirdsDataProject")
+    }
 }
diff --git a/Tests/XcbeautifyLibTests/ParsingTests/ParsingTests.swift b/Tests/XcbeautifyLibTests/ParsingTests/ParsingTests.swift
index 6b00460d..50d5949f 100644
--- a/Tests/XcbeautifyLibTests/ParsingTests/ParsingTests.swift
+++ b/Tests/XcbeautifyLibTests/ParsingTests/ParsingTests.swift
@@ -26,9 +26,9 @@ final class ParsingTests: XCTestCase {
         // Update this magic number whenever `uncapturedOutput` is less than the current magic number.
         // There's a regression whenever `uncapturedOutput` is greater than the current magic number.
         #if os(macOS)
-        XCTAssertEqual(uncapturedOutput, 381)
+        XCTAssertEqual(uncapturedOutput, 289)
         #else
-        XCTAssertEqual(uncapturedOutput, 397)
+        XCTAssertEqual(uncapturedOutput, 305)
         #endif
     }
 
@@ -56,9 +56,9 @@ final class ParsingTests: XCTestCase {
         // Update this magic number whenever `uncapturedOutput` is less than the current magic number.
         // There's a regression whenever `uncapturedOutput` is greater than the current magic number.
         #if os(macOS)
-        XCTAssertEqual(uncapturedOutput, 12938)
+        XCTAssertEqual(uncapturedOutput, 9639)
         #else
-        XCTAssertEqual(uncapturedOutput, 13506)
+        XCTAssertEqual(uncapturedOutput, 10207)
         #endif
     }
 }