Skip to content

Commit 8a5ab86

Browse files
authored
Update Regex Pattern Matching (#378)
- Enforce case sensitivity - Enforce regex anchors - Find first match instead of all matches
1 parent 7e56906 commit 8a5ab86

8 files changed

+30
-21
lines changed

Sources/XcbeautifyLib/CaptureGroups.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ struct GenerateCoverageDataCaptureGroup: CaptureGroup {
779779

780780
/// Regular expression captured groups:
781781
/// $1 = coverage report file path
782-
static let regex = XCRegex(pattern: #"^generating\s+coverage\s+data\.*"#)
782+
static let regex = XCRegex(pattern: #"^Generating\s+coverage\s+data\.*$"#)
783783

784784
private init() { }
785785

@@ -791,7 +791,7 @@ struct GenerateCoverageDataCaptureGroup: CaptureGroup {
791791

792792
struct GeneratedCoverageReportCaptureGroup: CaptureGroup {
793793
static let outputType: OutputType = .task
794-
static let regex = XCRegex(pattern: #"^generated\s+coverage\s+report:\s+(.+)"#)
794+
static let regex = XCRegex(pattern: #"^Generated\s+coverage\s+report:\s+(.+)"#)
795795

796796
let coverageReportFilePath: String
797797

@@ -1139,7 +1139,7 @@ struct ParallelTestSuiteStartedCaptureGroup: CaptureGroup {
11391139
/// Regular expression captured groups:
11401140
/// $1 = suite
11411141
/// $2 = device
1142-
static let regex = XCRegex(pattern: #"^\s*Test\s+Suite\s+'(.*)'\s+started\s+on\s+'(.*)'"#)
1142+
static let regex = XCRegex(pattern: #"^\s*Test\s+suite\s+'(.*)'\s+started\s+on\s+'(.*)'"#)
11431143

11441144
let suite: String
11451145
let device: String
@@ -1335,7 +1335,7 @@ struct RegisterExecutionPolicyExceptionCaptureGroup: CaptureGroup {
13351335
struct ScanDependenciesCaptureGroup: CaptureGroup {
13361336
static let outputType: OutputType = .task
13371337

1338-
static let regex = XCRegex(pattern: #"ScanDependencies .* normal (arm64|arm64_32|armv7k|i386|x86_64) .* \(in target '(.*)' from project '(.*)'\)$"#)
1338+
static let regex = XCRegex(pattern: #"^ScanDependencies .* normal (arm64|arm64_32|armv7k|i386|x86_64) .* \(in target '(.*)' from project '(.*)'\)$"#)
13391339

13401340
let arch: Architecture
13411341
let target: String
@@ -1866,7 +1866,7 @@ struct SymbolReferencedFromCaptureGroup: CaptureGroup {
18661866
/// Regular expression captured groups:
18671867
/// $1 = wholeError
18681868
/// $2 = reference
1869-
static let regex = XCRegex(pattern: #"(\s+\"(.*)\", referenced from:)$"#)
1869+
static let regex = XCRegex(pattern: #"^(\s+\"(.*)\", referenced from:)$"#)
18701870

18711871
let wholeError: String
18721872
let reference: String
@@ -1901,7 +1901,7 @@ struct UndefinedSymbolLocationCaptureGroup: CaptureGroup {
19011901
/// $1 = whole warning
19021902
/// $2 = target
19031903
/// $3 = filename
1904-
static let regex = XCRegex(pattern: #"(.+ in (.+)\((.+)\.o\))$"#)
1904+
static let regex = XCRegex(pattern: #"^(.+ in (.+)\((.+)\.o\))$"#)
19051905

19061906
let wholeWarning: String
19071907
let target: String
@@ -2031,7 +2031,7 @@ struct CompilationResultCaptureGroup: CaptureGroup {
20312031
struct SwiftDriverJobDiscoveryEmittingModuleCaptureGroup: CaptureGroup {
20322032
static let outputType: OutputType = .task
20332033

2034-
static let regex = XCRegex(pattern: #"SwiftDriverJobDiscovery \w+ \w+ Emitting module for .* \(in target '.*' from project '.*'\)"#)
2034+
static let regex = XCRegex(pattern: #"^SwiftDriverJobDiscovery \w+ \w+ Emitting module for .* \(in target '.*' from project '.*'\)"#)
20352035

20362036
init?(groups: [String]) { }
20372037
}

Sources/XcbeautifyLib/Renderers/OutputRendering.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ extension OutputRendering {
136136
}
137137

138138
func formatCheckDependencies() -> String {
139-
colored ? "Check Dependencies".style.Bold : "Check Dependencies"
139+
colored ? "Check dependencies".style.Bold : "Check dependencies"
140140
}
141141

142142
func formatCleanRemove(group: CleanRemoveCaptureGroup) -> String {

Sources/XcbeautifyLib/XCRegex.swift

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ package final class XCRegex: @unchecked Sendable {
1515
private let pattern: String
1616

1717
private lazy var regex: NSRegularExpression? = {
18-
let regex = try? NSRegularExpression(pattern: "^" + pattern, options: [.caseInsensitive])
18+
let regex = try? NSRegularExpression(pattern: pattern, options: [.anchorsMatchLines])
1919
assert(regex != nil)
2020
return regex
2121
}()
@@ -27,10 +27,7 @@ package final class XCRegex: @unchecked Sendable {
2727
func captureGroups(for line: String) -> [String]? {
2828
assert(regex != nil)
2929

30-
guard
31-
let matches = regex?.matches(in: line, range: NSRange(location: 0, length: line.utf16.count)),
32-
let match = matches.first
33-
else {
30+
guard let match = regex?.firstMatch(in: line, options: .anchored, range: NSRange(location: 0, length: line.utf16.count)) else {
3431
return nil
3532
}
3633

Tests/XcbeautifyLibTests/ParserTests.swift

+16-4
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,9 @@ final class ParserTests: XCTestCase {
384384
func testMatchNote() throws {
385385
let inputs = [
386386
("note:", "Building targets in dependency order"),
387-
("Note:", "Building targets in dependency order"),
388387
("note:", "Metadata extraction skipped. No AppIntents.framework dependency found. (in target 'Target' from project 'Project')"),
389-
("Note:", "Metadata extraction skipped. No AppIntents.framework dependency found. (in target 'Target' from project 'Project')"),
390388
("note:", #"Run script build phase 'SomeRunScriptBuildPhase' will be run during every build because the option to run the script phase "Based on dependency analysis" is unchecked. (in target 'Target' from project 'Project')"#),
391-
("Note:", #"Run script build phase 'SomeRunScriptBuildPhase' will be run during every build because the option to run the script phase "Based on dependency analysis" is unchecked. (in target 'Target' from project 'Project')"#),
392389
("note:", "Target dependency graph (12 targets)"),
393-
("Note:", "Target dependency graph (12 targets)"),
394390
]
395391

396392
for (keyword, note) in inputs {
@@ -400,6 +396,22 @@ final class ParserTests: XCTestCase {
400396
}
401397
}
402398

399+
// Note Output expects a lowercase n.
400+
func testNegativeMatchNote() {
401+
let inputs = [
402+
#"Note: Building targets in dependency order"#,
403+
#"Note: Metadata extraction skipped. No AppIntents.framework dependency found. (in target 'Target' from project 'Project')"#,
404+
#"Note: Run script build phase 'SomeRunScriptBuildPhase' will be run during every build because the option to run the script phase "Based on dependency analysis" is unchecked. (in target 'Target' from project 'Project')"#,
405+
#"Note: Target dependency graph (12 targets)"#,
406+
]
407+
408+
XCTAssertTrue(
409+
inputs.allSatisfy { input in
410+
parser.parse(line: input) == nil
411+
}
412+
)
413+
}
414+
403415
func testNotMatchNote() throws {
404416
let inputs = [
405417
"in the note middle",

Tests/XcbeautifyLibTests/RendererTests/AzureDevOpsPipelinesRendererTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ final class AzureDevOpsPipelinesRendererTests: XCTestCase {
5656
func testCheckDependenciesErrors() { }
5757

5858
func testCheckDependencies() {
59-
let command = "Check Dependencies"
59+
let command = "Check dependencies"
6060
let formatted = logFormatted(command)
6161
XCTAssertEqual(formatted, command)
6262
}

Tests/XcbeautifyLibTests/RendererTests/GitHubActionsRendererTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ final class GitHubActionsRendererTests: XCTestCase {
5454
func testCheckDependenciesErrors() { }
5555

5656
func testCheckDependencies() {
57-
let command = "Check Dependencies"
57+
let command = "Check dependencies"
5858
let formatted = logFormatted(command)
5959
XCTAssertEqual(formatted, command)
6060
}

Tests/XcbeautifyLibTests/RendererTests/TeamCityRendererTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ final class TeamCityRendererTests: XCTestCase {
5454
func testCheckDependenciesErrors() { }
5555

5656
func testCheckDependencies() {
57-
let command = "Check Dependencies"
57+
let command = "Check dependencies"
5858
let formatted = noColoredFormatted(command)
5959
XCTAssertEqual(formatted, command)
6060
}

Tests/XcbeautifyLibTests/RendererTests/TerminalRendererTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ final class TerminalRendererTests: XCTestCase {
5454
func testCheckDependenciesErrors() { }
5555

5656
func testCheckDependencies() {
57-
let command = "Check Dependencies"
57+
let command = "Check dependencies"
5858
let formatted = noColoredFormatted(command)
5959
XCTAssertEqual(formatted, command)
6060
}

0 commit comments

Comments
 (0)