diff --git a/Package.swift b/Package.swift index 4ccb4ae9..451a3e4d 100644 --- a/Package.swift +++ b/Package.swift @@ -36,6 +36,13 @@ let package = Package( "XMLCoder", ] ), + .executableTarget( + name: "ParsingCheck", + dependencies: [ + "XcbeautifyLib", + .product(name: "ArgumentParser", package: "swift-argument-parser"), + ] + ), .testTarget( name: "XcbeautifyLibTests", dependencies: ["XcbeautifyLib"], diff --git a/Sources/ParsingCheck/ParsingCheck.swift b/Sources/ParsingCheck/ParsingCheck.swift new file mode 100644 index 00000000..30596f86 --- /dev/null +++ b/Sources/ParsingCheck/ParsingCheck.swift @@ -0,0 +1,48 @@ +import ArgumentParser +import Darwin +import Foundation +import XcbeautifyLib + +@main +struct ParsingCheck: ParsableCommand { + + @Option + var filePath: String + + @Option + var uncapturedOutput: Int + + enum ParsingCheckError: Error { + case dataReadError + case noData + case regression(Int) + } + + func run() throws { + guard let data = FileManager.default.contents(atPath: filePath) else { + throw ParsingCheckError.noData + } + + guard !data.isEmpty else { + throw ParsingCheckError.noData + } + + var buildLog: [String] = String(decoding: data, as: UTF8.self) + .components(separatedBy: .newlines) + + let parser = Parser() + + var uncapturedOutput = 0 + + while !buildLog.isEmpty { + let line = buildLog.removeFirst() + if !line.isEmpty, parser.parse(line: line) == nil { + uncapturedOutput += 1 + } + } + + guard self.uncapturedOutput == uncapturedOutput else { + throw ParsingCheckError.regression(uncapturedOutput) + } + } +}