diff --git a/Sources/XCLogParser/activityparser/ActivityParser.swift b/Sources/XCLogParser/activityparser/ActivityParser.swift index 79c8492..fb23e68 100644 --- a/Sources/XCLogParser/activityparser/ActivityParser.swift +++ b/Sources/XCLogParser/activityparser/ActivityParser.swift @@ -98,6 +98,9 @@ public class ActivityParser { // swiftlint:disable:next function_body_length public func parseIDEActivityLogSection(iterator: inout IndexingIterator<[Token]>) throws -> IDEActivityLogSection { + guard let logVersion else { + throw XCLogParserError.parseError("Log version not parsed before parsing IDEActivityLogSection") + } let sectionType = Int8(try parseAsInt(token: iterator.next())) let domainType = try parseAsString(token: iterator.next()) let title = try parseAsString(token: iterator.next()) @@ -114,6 +117,7 @@ public class ActivityParser { } let text = try parseAsString(token: textToken) let messages = try parseMessages(iterator: &iterator) + let resultCode = logVersion >= 13 ? try parseAsInt(token: iterator.next()) : nil let wasCancelled = try parseBoolean(token: iterator.next()) let isQuiet = try parseBoolean(token: iterator.next()) let wasFetchedFromCache = try parseBoolean(token: iterator.next()) @@ -134,8 +138,8 @@ public class ActivityParser { let localizedResultString = try parseAsString(token: iterator.next()) let xcbuildSignature = try parseAsString(token: iterator.next()) let attachments = try parseIDEActivityLogSectionAttachments(iterator: &iterator) - if unknown == nil { - unknown = isCommandLineLog ? Int(try parseAsInt(token: iterator.next())) : 0 + if logVersion >= 13 || (unknown == nil && isCommandLineLog) { + unknown = Int(try parseAsInt(token: iterator.next())) } return IDEActivityLogSection( @@ -148,6 +152,7 @@ public class ActivityParser { subSections: subSections, text: text, messages: messages, + resultCode: resultCode, wasCancelled: wasCancelled, isQuiet: isQuiet, wasFetchedFromCache: wasFetchedFromCache, diff --git a/Sources/XCLogParser/activityparser/IDEActivityModel.swift b/Sources/XCLogParser/activityparser/IDEActivityModel.swift index a2bd441..eeac77b 100644 --- a/Sources/XCLogParser/activityparser/IDEActivityModel.swift +++ b/Sources/XCLogParser/activityparser/IDEActivityModel.swift @@ -40,6 +40,7 @@ public class IDEActivityLogSection: Encodable { public var subSections: [IDEActivityLogSection] public let text: String public let messages: [IDEActivityLogMessage] + public let resultCode: UInt64? public let wasCancelled: Bool public let isQuiet: Bool public var wasFetchedFromCache: Bool @@ -61,6 +62,7 @@ public class IDEActivityLogSection: Encodable { subSections: [IDEActivityLogSection], text: String, messages: [IDEActivityLogMessage], + resultCode: UInt64?, wasCancelled: Bool, isQuiet: Bool, wasFetchedFromCache: Bool, @@ -81,6 +83,7 @@ public class IDEActivityLogSection: Encodable { self.subSections = subSections self.text = text self.messages = messages + self.resultCode = resultCode self.wasCancelled = wasCancelled self.isQuiet = isQuiet self.wasFetchedFromCache = wasFetchedFromCache @@ -146,6 +149,7 @@ public class IDEActivityLogUnitTestSection: IDEActivityLogSection { subSections: subSections, text: text, messages: messages, + resultCode: nil, wasCancelled: wasCancelled, isQuiet: isQuiet, wasFetchedFromCache: wasFetchedFromCache, @@ -439,6 +443,7 @@ public class DBGConsoleLog: IDEActivityLogSection { subSections: subSections, text: text, messages: messages, + resultCode: nil, wasCancelled: wasCancelled, isQuiet: isQuiet, wasFetchedFromCache: wasFetchedFromCache, diff --git a/Sources/XCLogParser/parser/IDEActivityLogSection+Builders.swift b/Sources/XCLogParser/parser/IDEActivityLogSection+Builders.swift index fd04da3..5e5598e 100644 --- a/Sources/XCLogParser/parser/IDEActivityLogSection+Builders.swift +++ b/Sources/XCLogParser/parser/IDEActivityLogSection+Builders.swift @@ -31,6 +31,7 @@ extension IDEActivityLogSection { subSections: self.subSections, text: self.text, messages: newMessages, + resultCode: self.resultCode, wasCancelled: self.wasCancelled, isQuiet: self.isQuiet, wasFetchedFromCache: self.wasFetchedFromCache, diff --git a/Sources/XCLogParser/parser/IDEActivityLogSection+Parsing.swift b/Sources/XCLogParser/parser/IDEActivityLogSection+Parsing.swift index 189a1eb..77e8d78 100644 --- a/Sources/XCLogParser/parser/IDEActivityLogSection+Parsing.swift +++ b/Sources/XCLogParser/parser/IDEActivityLogSection+Parsing.swift @@ -146,6 +146,7 @@ extension IDEActivityLogSection { subSections: [IDEActivityLogSection](), text: "", messages: [IDEActivityLogMessage](), + resultCode: nil, wasCancelled: section.wasCancelled, isQuiet: section.isQuiet, wasFetchedFromCache: section.wasFetchedFromCache, diff --git a/Tests/XCLogParserTests/ActivityParserTests.swift b/Tests/XCLogParserTests/ActivityParserTests.swift index 6829862..1c7987a 100644 --- a/Tests/XCLogParserTests/ActivityParserTests.swift +++ b/Tests/XCLogParserTests/ActivityParserTests.swift @@ -232,10 +232,10 @@ class ActivityParserTests: XCTestCase { Token.classNameRef("IDEActivityLogMessage"), ] let logMessageTokens = IDEActivityLogMessageTokens - let endTokens = [Token.int(1), + let endTokens = [Token.int(1), // resultCode + Token.int(0), Token.int(0), Token.int(1), - Token.int(42), Token.string("subtitle"), Token.null, Token.string("commandDetailDesc"), @@ -243,10 +243,40 @@ class ActivityParserTests: XCTestCase { Token.string("localizedResultString"), Token.string("xcbuildSignature"), Token.list(0), // attachments + Token.int(7), ] return startTokens + logMessageTokens + endTokens }() + lazy var IDEActivityLogSectionTokensWithSubSectionsXcode270: [Token] = { + let startTokens = [Token.int(2), + Token.string("com.apple.dt.IDE.BuildLogSection"), + Token.string("Prepare build"), + Token.string("Prepare build"), + Token.double(575479851.278759), + Token.double(575479851.778325), + Token.list(2), + ] + let subSectionTokens = [Token.classNameRef("IDEActivityLogSection")] + IDEActivityLogSectionTokensXcode270 + let endTokens = [Token.int(0), + Token.string("note: Using legacy build system"), + Token.null, + Token.int(1), + Token.int(0), + Token.int(0), + Token.int(1), + Token.string("subtitle"), + Token.null, + Token.string("commandDetailDesc"), + Token.string("501796C4-6BE4-4F80-9F9D-3269617ECC17"), + Token.string("localizedResultString"), + Token.string("xcbuildSignature"), + Token.list(0), + Token.int(8), + ] + return startTokens + subSectionTokens + subSectionTokens + endTokens + }() + let IDEConsoleItemTokens: [Token] = [ Token.className("IDEConsoleItem"), Token.classNameRef("IDEConsoleItem"), @@ -460,6 +490,7 @@ class ActivityParserTests: XCTestCase { } XCTAssertEqual(logSection.attachments[2].metrics?.wcDuration, 1) XCTAssertEqual(0, logSection.unknown) + XCTAssertNil(logSection.resultCode) } func testParseIDEActivityLogSection_version10() throws { @@ -488,6 +519,7 @@ class ActivityParserTests: XCTestCase { XCTAssertEqual("xcbuildSignature", logSection.xcbuildSignature) XCTAssertEqual(0, logSection.attachments.count) XCTAssertEqual(0, logSection.unknown) + XCTAssertNil(logSection.resultCode) } func testParseIDEActivityLogSectionXcode262() throws { @@ -566,7 +598,7 @@ class ActivityParserTests: XCTestCase { XCTAssertEqual(0, logSection.subSections.count) XCTAssertEqual("note: Using legacy build system", logSection.text) XCTAssertEqual(1, logSection.messages.count) - XCTAssertTrue(logSection.wasCancelled) + XCTAssertFalse(logSection.wasCancelled) XCTAssertFalse(logSection.isQuiet) XCTAssertTrue(logSection.wasFetchedFromCache) XCTAssertEqual("subtitle", logSection.subtitle) @@ -577,7 +609,32 @@ class ActivityParserTests: XCTestCase { XCTAssertEqual("localizedResultString", logSection.localizedResultString) XCTAssertEqual("xcbuildSignature", logSection.xcbuildSignature) XCTAssertEqual(0, logSection.attachments.count) - XCTAssertEqual(42, logSection.unknown) + XCTAssertEqual(7, logSection.unknown) + XCTAssertEqual(1, logSection.resultCode) + XCTAssertNil(iterator.next()) + } + + func testParseNestedIDEActivityLogSectionsXcode270() throws { + parser.logVersion = 13 + let tokens = IDEActivityLogSectionTokensWithSubSectionsXcode270 + var iterator = tokens.makeIterator() + let logSection = try parser.parseIDEActivityLogSection(iterator: &iterator) + XCTAssertEqual(2, logSection.subSections.count) + XCTAssertEqual([7, 7], logSection.subSections.map(\.unknown)) + XCTAssertEqual(8, logSection.unknown) + XCTAssertNil(iterator.next()) + } + + func testParseNestedIDEActivityLogSectionsXcode270CommandLine() throws { + parser.logVersion = 13 + parser.isCommandLineLog = true + let tokens = IDEActivityLogSectionTokensWithSubSectionsXcode270 + var iterator = tokens.makeIterator() + let logSection = try parser.parseIDEActivityLogSection(iterator: &iterator) + XCTAssertEqual(2, logSection.subSections.count) + XCTAssertEqual([7, 7], logSection.subSections.map(\.unknown)) + XCTAssertEqual(8, logSection.unknown) + XCTAssertNil(iterator.next()) } func testParseActivityLog() throws { diff --git a/Tests/XCLogParserTests/ClangCompilerParserTests.swift b/Tests/XCLogParserTests/ClangCompilerParserTests.swift index 1a87e02..991c80c 100644 --- a/Tests/XCLogParserTests/ClangCompilerParserTests.swift +++ b/Tests/XCLogParserTests/ClangCompilerParserTests.swift @@ -86,6 +86,7 @@ class ClangCompilerParserTests: XCTestCase { subSections: [], text: text, messages: [], + resultCode: nil, wasCancelled: false, isQuiet: false, wasFetchedFromCache: false, diff --git a/Tests/XCLogParserTests/ParserTests.swift b/Tests/XCLogParserTests/ParserTests.swift index 5c01c54..345c908 100644 --- a/Tests/XCLogParserTests/ParserTests.swift +++ b/Tests/XCLogParserTests/ParserTests.swift @@ -54,6 +54,7 @@ class ParserTests: XCTestCase { subSections: [], text: "", messages: [], + resultCode: nil, wasCancelled: false, isQuiet: false, wasFetchedFromCache: false, @@ -251,6 +252,7 @@ note: use 'updatedDoSomething' instead\r doSomething()\r ^~~~~~~~~~~\r subSections: [], text: "", messages: [], + resultCode: nil, wasCancelled: false, isQuiet: false, wasFetchedFromCache: false, @@ -303,6 +305,7 @@ note: use 'updatedDoSomething' instead\r doSomething()\r ^~~~~~~~~~~\r subSections: [], text: text, messages: messages, + resultCode: nil, wasCancelled: false, isQuiet: true, wasFetchedFromCache: true, @@ -573,6 +576,7 @@ CompileSwift normal x86_64 (in target 'Alamofire' from project 'Pods') subSections: [], text: "", messages: [], + resultCode: nil, wasCancelled: false, isQuiet: true, wasFetchedFromCache: true, diff --git a/Tests/XCLogParserTests/SwiftCompilerParserTests.swift b/Tests/XCLogParserTests/SwiftCompilerParserTests.swift index 686a117..956e837 100644 --- a/Tests/XCLogParserTests/SwiftCompilerParserTests.swift +++ b/Tests/XCLogParserTests/SwiftCompilerParserTests.swift @@ -118,6 +118,7 @@ class SwiftCompilerParserTests: XCTestCase { subSections: [], text: text, messages: [], + resultCode: nil, wasCancelled: false, isQuiet: false, wasFetchedFromCache: false, diff --git a/Tests/XCLogParserTests/XCTestManifests.swift b/Tests/XCLogParserTests/XCTestManifests.swift index e18faed..a7daa75 100644 --- a/Tests/XCLogParserTests/XCTestManifests.swift +++ b/Tests/XCLogParserTests/XCTestManifests.swift @@ -15,6 +15,8 @@ extension ActivityParserTests { ("testParseIDEActivityLogMessage", testParseIDEActivityLogMessage), ("testParseIDEActivityLogSection", testParseIDEActivityLogSection), ("testParseIDEActivityLogSectionXcode270", testParseIDEActivityLogSectionXcode270), + ("testParseNestedIDEActivityLogSectionsXcode270", testParseNestedIDEActivityLogSectionsXcode270), + ("testParseNestedIDEActivityLogSectionsXcode270CommandLine", testParseNestedIDEActivityLogSectionsXcode270CommandLine), ("testParseXcode3ProjectLocation", testParseXcode3ProjectLocation), ] }