import Foundation public struct CheckstyleReporter: Reporter { public static let identifier = "checkstyle" public static let isRealtime = false public var description: String { return "Reports violations as Checkstyle XML." } public static func generateReport(_ violations: [StyleViolation]) -> String { return [ "\n", violations .group(by: { ($0.location.file ?? "").escapedForXML() }) .sorted(by: { $0.key < $1.key }) .map(generateForViolationFile).joined(), "\n" ].joined() } private static func generateForViolationFile(_ file: String, violations: [StyleViolation]) -> String { return [ "\n\t\n", violations.map(generateForSingleViolation).joined(), "\t" ].joined() } private static func generateForSingleViolation(_ violation: StyleViolation) -> String { let line: Int = violation.location.line ?? 0 let col: Int = violation.location.character ?? 0 let severity: String = violation.severity.rawValue let reason: String = violation.reason.escapedForXML() let identifier: String = violation.ruleDescription.identifier let source: String = "swiftlint.rules.\(identifier)".escapedForXML() return [ "\t\t\n" ].joined() } }