Repository: cpisciotta/xcbeautify (swift)

Issue:
Codesigning error lost
Origin log:

```text
/Users/xxxxx/Example/Pods/Pods.xcodeproj: warning: The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 9.0, but the range of supported deployment target versions is 11.0 to 16.0.99. (in target 'XXPay' from project 'Pods')
/Users/xxxxx/Example/AAAA.xcodeproj: warning: The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 9.0, but the range of supported deployment target versions is 11.0 to 16.0.99. (in target 'AAAA_Example' from project 'AAAA')
/Users/xxxxx/Example/AAAA.xcodeproj: error: The file "/Users/xxxxx/AAAA/Example/configs/domestic/ueaws/app.entitlements" could not be opened. Verify the value of the CODE_SIGN_ENTITLEMENTS build setting for target "AAAA_Example" is correct and that the file exists on disk. (in target 'AAAA_Example' from project 'AAAA')
```

But no error show me from xcbeautify

Pull request:
Closes #93

## Summary

I've noticed lately that certain types errors are being masked by xcbeautify. I'm calling them "xcodeproj" errors, because they contain the path to the xcodeproj first, followed by "error:".

This change adds a matcher for those types of errors, as well as a test to verify it's functioning correctly.

## Changes

- Adds an `xcodeprojError` case to the `Pattern` enum
- Adds a test for the new error type

Patch:
diff --git a/Sources/XcbeautifyLib/Matcher.swift b/Sources/XcbeautifyLib/Matcher.swift
index e20ea175..09007566 100644
--- a/Sources/XcbeautifyLib/Matcher.swift
+++ b/Sources/XcbeautifyLib/Matcher.swift
@@ -80,4 +80,5 @@ struct Matcher {
     static let writeAuxiliaryFilesMatcher = Regex(pattern: .writeAuxiliaryFiles)
     static let writeFileMatcher = Regex(pattern: .writeFile)
     static let xcodebuildErrorMatcher = Regex(pattern: .xcodebuildError)
+    static let xcodeprojErrorMatcher = Regex(pattern: .xcodeprojError)
 }
diff --git a/Sources/XcbeautifyLib/Parser.swift b/Sources/XcbeautifyLib/Parser.swift
index 516280ae..9f763f97 100644
--- a/Sources/XcbeautifyLib/Parser.swift
+++ b/Sources/XcbeautifyLib/Parser.swift
@@ -89,6 +89,7 @@ public class Parser {
         innerParser(Matcher.packageGraphResolvingEnded, outputType: .task),
         innerParser(Matcher.packageGraphResolvedItem, outputType: .task),
         innerParser(Matcher.xcodebuildErrorMatcher, outputType: .error),
+        innerParser(Matcher.xcodeprojErrorMatcher, outputType: .error),
         innerParser(Matcher.duplicateLocalizedStringKey, outputType: .warning)
     ]
     
diff --git a/Sources/XcbeautifyLib/Pattern.swift b/Sources/XcbeautifyLib/Pattern.swift
index 8d63d0f4..a1bb4f57 100644
--- a/Sources/XcbeautifyLib/Pattern.swift
+++ b/Sources/XcbeautifyLib/Pattern.swift
@@ -413,9 +413,13 @@ enum Pattern: String {
     /// $1 = package name
     /// $2 = package url
     /// $3 = package version
-    case packageGraphResolvedItem = #"^\s*([^\s:]+):\s([^ ]+)\s@\s(\d+\.\d+\.\d+)"#;
+    case packageGraphResolvedItem = #"^\s*([^\s:]+):\s([^ ]+)\s@\s(\d+\.\d+\.\d+)"#
     
     /// Regular expression captured groups:
     /// $1 = whole error
-    case xcodebuildError = #"^(xcodebuild: error:.*)$"#;
+    case xcodebuildError = #"^(xcodebuild: error:.*)$"#
+
+    /// Regular expression captured groups:
+    /// $1 = whole error, excluding the path to the .xcodeproj file
+    case xcodeprojError = #".*.xcodeproj: (error:.*)$"#
 }
diff --git a/Sources/XcbeautifyLib/String+Beautify.swift b/Sources/XcbeautifyLib/String+Beautify.swift
index 62f1e595..f8e97202 100644
--- a/Sources/XcbeautifyLib/String+Beautify.swift
+++ b/Sources/XcbeautifyLib/String+Beautify.swift
@@ -118,7 +118,8 @@ extension String {
              .ldError,
              .podsError,
              .moduleIncludesError,
-             .xcodebuildError:
+             .xcodebuildError,
+             .xcodeprojError:
             return formatError(pattern: pattern)
         case .compileError:
             return formatCompileError(pattern: pattern, additionalLines: additionalLines)


Test patch:
diff --git a/Tests/XcbeautifyLibTests/XcbeautifyLibTests.swift b/Tests/XcbeautifyLibTests/XcbeautifyLibTests.swift
index c6a0688f..cc2597ea 100644
--- a/Tests/XcbeautifyLibTests/XcbeautifyLibTests.swift
+++ b/Tests/XcbeautifyLibTests/XcbeautifyLibTests.swift
@@ -542,6 +542,19 @@ final class XcbeautifyLibTests: XCTestCase {
         XCTAssertEqual(formatted, "[x] xcodebuild: error: Existing file at -resultBundlePath \"/output/file.xcresult\"")
     }
 
+    func testXcodeprojError() {
+        // Given
+        let errorText = #"/path/to/project.xcodeproj: error: No signing certificate "iOS Distribution" found: No "iOS Distribution" signing certificate matching team ID "xxxxx" with a private key was found. (in target 'target' from project 'project')"#
+        let expectedFormatted = #"[x] error: No signing certificate "iOS Distribution" found: No "iOS Distribution" signing certificate matching team ID "xxxxx" with a private key was found. (in target 'target' from project 'project')"#
+
+        // When
+        let actualFormatted = noColoredFormatted(errorText)
+
+        // Then
+        XCTAssertEqual(actualFormatted, expectedFormatted)
+        XCTAssertEqual(parser.outputType, .error)
+    }
+
     func testDuplicateLocalizedStringKey() {
         let formatted = noColoredFormatted(#"2022-12-07 16:26:40 --- WARNING: Key "duplicate" used with multiple values. Value "First" kept. Value "Second" ignored."#)
         XCTAssertEqual(formatted, #"[!] Key "duplicate" used with multiple values. Value "First" kept. Value "Second" ignored."#)