Repository: cpisciotta/xcbeautify
Pull request #390 (2025-02-22 20:48:45)

Add ValidateEmbeddedBinaryCaptureGroup

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/cpisciotta/xcbeautify/pull/390?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 91.39%. Comparing base [(`3385de2`)](https://app.codecov.io/gh/cpisciotta/xcbeautify/commit/3385de2d61b72bbf095106b4bf79b0a7a352386f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta) to head [(`9c49e87`)](https://app.codecov.io/gh/cpisciotta/xcbeautify/commit/9c49e8786953c40f6be70df7308137c456e95564?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #390      +/-   ##
==========================================
- Coverage   91.49%   91.39%   -0.11%     
==========================================
  Files          18       18              
  Lines        2529     2545      +16     
==========================================
+ Hits         2314     2326      +12     
- Misses        215      219       +4     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/cpisciotta/xcbeautify/pull/390?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Charles+Pisciotta).


Patch:
diff --git a/Sources/XcbeautifyLib/CaptureGroups.swift b/Sources/XcbeautifyLib/CaptureGroups.swift
index 4377575..0b2fd0b 100644
--- a/Sources/XcbeautifyLib/CaptureGroups.swift
+++ b/Sources/XcbeautifyLib/CaptureGroups.swift
@@ -1483,6 +1483,26 @@ struct ValidateCaptureGroup: CaptureGroup {
     }
 }
 
+struct ValidateEmbeddedBinaryCaptureGroup: CaptureGroup {
+    static var outputType: OutputType = .task
+
+    static var regex = XCRegex(pattern: #"^ValidateEmbeddedBinary (.+) \(in target '(.*)' from project '(.*)'\)$"#)
+
+    let filePath: String
+    let filename: String
+    let target: String
+    let project: String
+
+    init?(groups: [String]) {
+        assert(groups.count == 3)
+        guard let filePath = groups[safe: 0], let target = groups[safe: 1], let project = groups[safe: 2] else { return nil }
+        self.filePath = filePath
+        filename = filePath.lastPathComponent
+        self.target = target
+        self.project = project
+    }
+}
+
 struct WriteFileCaptureGroup: CaptureGroup {
     static let outputType: OutputType = .task
 
diff --git a/Sources/XcbeautifyLib/Formatter.swift b/Sources/XcbeautifyLib/Formatter.swift
index 56aaf93..08180a9 100644
--- a/Sources/XcbeautifyLib/Formatter.swift
+++ b/Sources/XcbeautifyLib/Formatter.swift
@@ -230,6 +230,8 @@ package struct Formatter {
             return renderer.formatWriteFile(group: group)
         case let group as ValidateCaptureGroup:
             return renderer.formatValidate(group: group)
+        case let group as ValidateEmbeddedBinaryCaptureGroup:
+            return renderer.formatValidateEmbeddedBinary(group: group)
         case let group as XcodebuildErrorCaptureGroup:
             return renderer.formatError(group: group)
         case let group as SwiftDriverJobDiscoveryEmittingModuleCaptureGroup:
diff --git a/Sources/XcbeautifyLib/Parser.swift b/Sources/XcbeautifyLib/Parser.swift
index 008eab6..cd4ebfb 100644
--- a/Sources/XcbeautifyLib/Parser.swift
+++ b/Sources/XcbeautifyLib/Parser.swift
@@ -58,6 +58,7 @@ package final class Parser {
         TIFFutilCaptureGroup.self,
         TouchCaptureGroup.self,
         ValidateCaptureGroup.self,
+        ValidateEmbeddedBinaryCaptureGroup.self,
         WriteFileCaptureGroup.self,
         WriteAuxiliaryFileCaptureGroup.self,
         ParallelTestCasePassedCaptureGroup.self,
diff --git a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
index a1d6912..0bc118c 100644
--- a/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
+++ b/Sources/XcbeautifyLib/Renderers/OutputRendering.swift
@@ -90,6 +90,7 @@ protocol OutputRendering {
     func formatUIFailingTest(group: UIFailingTestCaptureGroup) -> String
     func formatUndefinedSymbolLocation(group: UndefinedSymbolLocationCaptureGroup) -> String
     func formatValidate(group: ValidateCaptureGroup) -> String
+    func formatValidateEmbeddedBinary(group: ValidateEmbeddedBinaryCaptureGroup) -> String
     func formatWarning(group: GenericWarningCaptureGroup) -> String
     func formatWillNotBeCodesignWarning(group: WillNotBeCodeSignedCaptureGroup) -> String
     func formatWriteAuxiliaryFile(group: WriteAuxiliaryFileCaptureGroup) -> String?
@@ -427,6 +428,12 @@ extension OutputRendering {
         return colored ? "[\(target.f.Cyan)] \("Validate".s.Bold) \(filename)" : "[\(target)] Validate \(filename)"
     }
 
+    func formatValidateEmbeddedBinary(group: ValidateEmbeddedBinaryCaptureGroup) -> String {
+        let target = group.target
+        let filename = group.filename
+        return colored ? "[\(target.f.Cyan)] \("Validate Embedded Binary".s.Bold) \(filename)" : "[\(target)] Validate Embedded Binary \(filename)"
+    }
+
     func formatWriteAuxiliaryFile(group: WriteAuxiliaryFileCaptureGroup) -> String? {
         let filename = group.filename
         let target = group.target


Test patch:
diff --git a/Tests/XcbeautifyLibTests/CaptureGroupTests.swift b/Tests/XcbeautifyLibTests/CaptureGroupTests.swift
index 22ff96d..02cee1c 100644
--- a/Tests/XcbeautifyLibTests/CaptureGroupTests.swift
+++ b/Tests/XcbeautifyLibTests/CaptureGroupTests.swift
@@ -169,6 +169,15 @@ final class CaptureGroupTests: XCTestCase {
         XCTAssertEqual(groups[2], "Project")
     }
 
+    func testValidateEmbeddedBinary() throws {
+        let input = #"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds Target' from project 'Backyard Birds Project')"#
+        let groups = try XCTUnwrap(ValidateEmbeddedBinaryCaptureGroup.regex.captureGroups(for: input))
+        XCTAssertEqual(groups.count, 3)
+        XCTAssertEqual(groups[0], #"/Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex"#)
+        XCTAssertEqual(groups[1], "Backyard Birds Target")
+        XCTAssertEqual(groups[2], "Backyard Birds Project")
+    }
+
     func testIndentedShellCommand() throws {
         let input = #"    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-macos14.0 -dynamiclib -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -O0 -L/Backyard-Birds/Build/Intermediates.noindex/EagerLinkingTBDs/Debug -L/Backyard-Birds/Build/Products/Debug -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib -F/Backyard-Birds/Build/Intermediates.noindex/EagerLinkingTBDs/Debug -F/Backyard-Birds/Build/Products/Debug/PackageFrameworks -F/Backyard-Birds/Build/Products/Debug -F/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -filelist /Backyard-Birds/Build/Intermediates.noindex/BackyardBirdsData.build/Debug/BackyardBirdsData\ product.build/Objects-normal/arm64/BackyardBirdsData.LinkFileList -install_name @rpath/BackyardBirdsData.framework/Versions/A/BackyardBirdsData -Xlinker -rpath -Xlinker /Backyard-Birds/Build/Products/Debug/PackageFrameworks -Xlinker -object_path_lto -Xlinker /Backyard-Birds/Build/Intermediates.noindex/BackyardBirdsData.build/Debug/BackyardBirdsData\ product.build/Objects-normal/arm64/BackyardBirdsData_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -fobjc-link-runtime -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -L/usr/lib/swift -Wl,-no_warn_duplicate_libraries -Xlinker -dependency_info -Xlinker /Backyard-Birds/Build/Intermediates.noindex/BackyardBirdsData.build/Debug/BackyardBirdsData\ product.build/Objects-normal/arm64/BackyardBirdsData_dependency_info.dat -o /Backyard-Birds/Build/Intermediates.noindex/BackyardBirdsData.build/Debug/BackyardBirdsData\ product.build/Objects-normal/arm64/Binary/BackyardBirdsData -Xlinker -add_ast_path -Xlinker /Backyard-Birds/Build/Intermediates.noindex/BackyardBirdsData.build/Debug/BackyardBirdsData.build/Objects-normal/arm64/BackyardBirdsData.swiftmodule"#
         let groups = try XCTUnwrap(NonPCHClangCommandCaptureGroup.regex.captureGroups(for: input))
diff --git a/Tests/XcbeautifyLibTests/ParserTests.swift b/Tests/XcbeautifyLibTests/ParserTests.swift
index 4ec9a85..fd900cf 100644
--- a/Tests/XcbeautifyLibTests/ParserTests.swift
+++ b/Tests/XcbeautifyLibTests/ParserTests.swift
@@ -410,4 +410,13 @@ final class ParserTests: XCTestCase {
         XCTAssertEqual(captureGroup.target, "Backyard Birds Target")
         XCTAssertEqual(captureGroup.project, "Backyard Birds")
     }
+
+    func testValidateEmbeddedBinary() throws {
+        let input = #"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds Target' from project 'Backyard Birds Project')"#
+        let captureGroup = try XCTUnwrap(parser.parse(line: input) as? ValidateEmbeddedBinaryCaptureGroup)
+        XCTAssertEqual(captureGroup.filePath, #"/Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex"#)
+        XCTAssertEqual(captureGroup.filename, "Widgets.appex")
+        XCTAssertEqual(captureGroup.target, "Backyard Birds Target")
+        XCTAssertEqual(captureGroup.project, "Backyard Birds Project")
+    }
 }
diff --git a/Tests/XcbeautifyLibTests/ParsingTests.swift b/Tests/XcbeautifyLibTests/ParsingTests.swift
index f3dd75a..08e8829 100644
--- a/Tests/XcbeautifyLibTests/ParsingTests.swift
+++ b/Tests/XcbeautifyLibTests/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, 46)
+        XCTAssertEqual(uncapturedOutput, 45)
         #else
-        XCTAssertEqual(uncapturedOutput, 62)
+        XCTAssertEqual(uncapturedOutput, 61)
         #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, 1540)
+        XCTAssertEqual(uncapturedOutput, 1508)
         #else
-        XCTAssertEqual(uncapturedOutput, 2108)
+        XCTAssertEqual(uncapturedOutput, 2076)
         #endif
     }
 
diff --git a/Tests/XcbeautifyLibTests/RendererTests/AzureDevOpsPipelinesRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/AzureDevOpsPipelinesRendererTests.swift
index 18ec480..a99c200 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/AzureDevOpsPipelinesRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/AzureDevOpsPipelinesRendererTests.swift
@@ -558,6 +558,11 @@ final class AzureDevOpsPipelinesRendererTests: XCTestCase {
         XCTAssertEqual(formatted, "[Target] Validate some.app")
     }
 
+    func testValidateEmbeddedBinary() {
+        let formatted = logFormatted(#"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds' from project 'Backyard Birds')"#)
+        XCTAssertEqual(formatted, "[Backyard Birds] Validate Embedded Binary Widgets.appex")
+    }
+
     func testWillNotBeCodeSigned() {
         let input = "FrameworkName will not be code signed because its settings don't specify a development team."
         let output = "##vso[task.logissue type=warning]FrameworkName will not be code signed because its settings don't specify a development team."
diff --git a/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
index e1335d3..db081cc 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift
@@ -263,6 +263,11 @@ final class GitHubActionsRendererTests: XCTestCase {
         XCTAssertEqual(formatted, #"[Backyard Birds Target] Validate Backyard\ Birds.app"#)
     }
 
+    func testValidateEmbeddedBinary() {
+        let formatted = logFormatted(#"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds' from project 'Backyard Birds')"#)
+        XCTAssertEqual(formatted, "[Backyard Birds] Validate Embedded Binary Widgets.appex")
+    }
+
     func testFatalError() {
         let input = "fatal error: malformed or corrupted AST file: 'could not find file '/path/file.h' referenced by AST file' note: after modifying system headers, please delete the module cache at '/path/DerivedData/ModuleCache/M5WJ0FYE7N06'"
         let output = "::error ::fatal error: malformed or corrupted AST file: 'could not find file '/path/file.h' referenced by AST file' note: after modifying system headers, please delete the module cache at '/path/DerivedData/ModuleCache/M5WJ0FYE7N06'"
diff --git a/Tests/XcbeautifyLibTests/RendererTests/TeamCityRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/TeamCityRendererTests.swift
index 45e912e..f5c48cf 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/TeamCityRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/TeamCityRendererTests.swift
@@ -576,6 +576,11 @@ final class TeamCityRendererTests: XCTestCase {
         XCTAssertEqual(formatted, "[Target] Validate some.app")
     }
 
+    func testValidateEmbeddedBinary() {
+        let formatted = noColoredFormatted(#"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds' from project 'Backyard Birds')"#)
+        XCTAssertEqual(formatted, "[Backyard Birds] Validate Embedded Binary Widgets.appex")
+    }
+
     func testWillNotBeCodeSigned() {
         let input = "FrameworkName will not be code signed because its settings don't specify a development team."
         let output = "##teamcity[message text=\'Codesign error|n|[!|] FrameworkName will not be code signed because its settings don|\'t specify a development team.\' status=\'WARNING\']\nCodesign error"
diff --git a/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift b/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
index 900e54e..2bf8afa 100644
--- a/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
+++ b/Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift
@@ -555,6 +555,11 @@ final class TerminalRendererTests: XCTestCase {
         XCTAssertEqual(formatted, #"[Backyard Birds Target] Validate Backyard\ Birds.app"#)
     }
 
+    func testValidateEmbeddedBinary() {
+        let formatted = noColoredFormatted(#"ValidateEmbeddedBinary /Backyard-Birds/Build/Products/Debug/Backyard\ Birds.app/Contents/PlugIns/Widgets.appex (in target 'Backyard Birds' from project 'Backyard Birds')"#)
+        XCTAssertEqual(formatted, "[Backyard Birds] Validate Embedded Binary Widgets.appex")
+    }
+
     func testWillNotBeCodeSigned() {
         let input = "FrameworkName will not be code signed because its settings don't specify a development team."
         let output = "[!] FrameworkName will not be code signed because its settings don't specify a development team."