diff --git a/CHANGELOG.md b/CHANGELOG.md index 210f123a94..cb8adffa6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,10 @@ ##### Enhancements -* None. +* Add `checkstyle` reporter to generate XML reports in the Checkstyle 4.3 + format. + [JP Simard](https://github.com/jpsim) + [#277](https://github.com/realm/SwiftLint/issues/277) ##### Bug Fixes diff --git a/README.md b/README.md index 1532081f93..392e64cc18 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ variable_name_max_length: variable_name_min_length: - 3 # warning - 2 # error -reporter: "csv" # reporter type (xcode, json, csv) +reporter: "csv" # reporter type (xcode, json, csv, checkstyle) ``` ### Auto-correct diff --git a/Source/SwiftLintFramework/Models/Configuration.swift b/Source/SwiftLintFramework/Models/Configuration.swift index 0e3b2b0c28..b80f12e7ec 100644 --- a/Source/SwiftLintFramework/Models/Configuration.swift +++ b/Source/SwiftLintFramework/Models/Configuration.swift @@ -25,7 +25,7 @@ public struct Configuration { public let disabledRules: [String] // disabled_rules public let included: [String] // included public let excluded: [String] // excluded - public let reporter: String // reporter (xcode, json, csv) + public let reporter: String // reporter (xcode, json, csv, checkstyle) public let rules: [Rule] public var reporterFromString: Reporter.Type { @@ -36,6 +36,8 @@ public struct Configuration { return JSONReporter.self case CSVReporter.identifier: return CSVReporter.self + case CheckstyleReporter.identifier: + return CheckstyleReporter.self default: fatalError("no reporter with identifier '\(reporter)' available.") } diff --git a/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift b/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift new file mode 100644 index 0000000000..ae68015a55 --- /dev/null +++ b/Source/SwiftLintFramework/Reporters/CheckstyleReporter.swift @@ -0,0 +1,33 @@ +// +// CheckstyleReporter.swift +// SwiftLint +// +// Created by JP Simard on 12/25/15. +// Copyright © 2015 Realm. All rights reserved. +// + +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 { + var report = "\n" + report += violations.map { violation in + let fileName = violation.location.file ?? "" + return "\n\t\n" + + "\t\t\n" + + "\t" + }.joinWithSeparator("") + report += "\n" + return report + } +} diff --git a/Source/SwiftLintFrameworkTests/ReporterTests.swift b/Source/SwiftLintFrameworkTests/ReporterTests.swift index dd98a8bed5..66c66762ae 100644 --- a/Source/SwiftLintFrameworkTests/ReporterTests.swift +++ b/Source/SwiftLintFrameworkTests/ReporterTests.swift @@ -65,4 +65,16 @@ class ReporterTests: XCTestCase { "filename,1,2,Error,Line Length,Violation Reason.,line_length" ) } + + func testCheckstyleReporter() { + XCTAssertEqual( + CheckstyleReporter.generateReport(generateViolations()), + "\n\n" + + "\t\n\t\t\n\t\n" + + "\t\n\t\t\n\t\n" + + "" + ) + } } diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj index ef5318c893..b26e74ff8c 100644 --- a/SwiftLint.xcodeproj/project.pbxproj +++ b/SwiftLint.xcodeproj/project.pbxproj @@ -88,6 +88,7 @@ E8C0DFCD1AD349DB007EE3D4 /* SWXMLHash.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */; }; E8C0DFCE1AD349E5007EE3D4 /* SWXMLHash.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E8C164C21BEA9EDA00177258 /* ASTRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8BB8F991B17DDB200199606 /* ASTRuleTests.swift */; }; + E8EA41171C2D1DBE004F9930 /* CheckstyleReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8EA41161C2D1DBE004F9930 /* CheckstyleReporter.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -235,6 +236,7 @@ E8BB8F991B17DDB200199606 /* ASTRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASTRuleTests.swift; sourceTree = ""; }; E8BB8F9B1B17DE3B00199606 /* StringRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringRuleTests.swift; sourceTree = ""; }; E8C0DFCC1AD349DB007EE3D4 /* SWXMLHash.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SWXMLHash.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E8EA41161C2D1DBE004F9930 /* CheckstyleReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckstyleReporter.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -450,6 +452,7 @@ E86396C31BADAC0D002C9E88 /* Reporters */ = { isa = PBXGroup; children = ( + E8EA41161C2D1DBE004F9930 /* CheckstyleReporter.swift */, E86396CA1BADB519002C9E88 /* CSVReporter.swift */, E86396C81BADB2B9002C9E88 /* JSONReporter.swift */, E86396C41BADAC15002C9E88 /* XcodeReporter.swift */, @@ -725,6 +728,7 @@ E88198531BEA944400333A11 /* LineLengthRule.swift in Sources */, E88198441BEA93D200333A11 /* ColonRule.swift in Sources */, E809EDA11B8A71DF00399043 /* Configuration.swift in Sources */, + E8EA41171C2D1DBE004F9930 /* CheckstyleReporter.swift in Sources */, E88DEA731B0984C400A66CB0 /* String+SwiftLint.swift in Sources */, E88198591BEA95F100333A11 /* LeadingWhitespaceRule.swift in Sources */, 24E17F721B14BB3F008195BE /* File+Cache.swift in Sources */,