Files
2024-04-13 05:49:57 -04:00

76 lines
2.6 KiB
Swift

import Foundation
import SourceKittenFramework
/// To some tools (i.e. Datadog), code quality findings are reported in the SARIF format:
/// - Full Spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html
/// - Samples: https://github.com/microsoft/sarif-tutorials/blob/main/samples/
/// - JSON Validator: https://sarifweb.azurewebsites.net/Validation
struct SARIFReporter: Reporter {
// MARK: - Reporter Conformance
static let identifier = "sarif"
static let isRealtime = false
static let description = "Reports violations in the Static Analysis Results Interchange Format (SARIF)"
static let swiftlintVersion = "https://github.com/realm/SwiftLint/blob/\(Version.current.value)/README.md"
static func generateReport(_ violations: [StyleViolation]) -> String {
let SARIFJson = [
"version": "2.1.0",
"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/cos02/schemas/sarif-schema-2.1.0.json",
"runs": [
[
"tool": [
"driver": [
"name": "SwiftLint",
"semanticVersion": Version.current.value,
"informationUri": swiftlintVersion
]
],
"results": violations.map(dictionary(for:))
]
]
] as [String: Any]
return toJSON(SARIFJson)
}
// MARK: - Private
private static func dictionary(for violation: StyleViolation) -> [String: Any] {
return [
"level": violation.severity.rawValue,
"ruleId": violation.ruleIdentifier,
"message": [
"text": violation.reason
],
"locations": [
dictionary(for: violation.location)
]
]
}
private static func dictionary(for location: Location) -> [String: Any] {
// According to SARIF specification JSON1008, minimum value for line is 1
if let line = location.line, line > 0 {
return [
"physicalLocation": [
"artifactLocation": [
"uri": location.file ?? ""
],
"region": [
"startLine": line,
"startColumn": location.character ?? "1"
]
]
]
}
return [
"physicalLocation": [
"artifactLocation": [
"uri": location.file ?? ""
]
]
]
}
}