Add a `reporters` subcommand (#4836)
This commit is contained in:
parent
ca43d2359b
commit
7dad240ea7
|
@ -0,0 +1,7 @@
|
|||
|
||||
/// The reporters list containing all the reporters built into SwiftLint.
|
||||
public let reportersList: [Reporter.Type] = [
|
||||
{% for reporter in types.structs where reporter.name|hasSuffix:"Reporter" %}
|
||||
{{ reporter.name }}.self{% if not forloop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
|
@ -133,6 +133,11 @@
|
|||
of each rule in a text table.
|
||||
[Martin Redington](https://github.com/mildm8nnered)
|
||||
|
||||
* Adds a new `reporters` subcommand, to improve discoverability of
|
||||
reporters.
|
||||
[Martin Redington](https://github.com/mildm8nnered)
|
||||
[#4819](https://github.com/realm/SwiftLint/issues/4819)
|
||||
|
||||
#### Bug Fixes
|
||||
|
||||
* Report violations in all `<scope>_length` rules when the error threshold is
|
||||
|
|
6
Makefile
6
Makefile
|
@ -30,12 +30,16 @@ VERSION_STRING=$(shell ./tools/get-version)
|
|||
|
||||
all: build
|
||||
|
||||
sourcery: Source/SwiftLintFramework/Models/PrimaryRuleList.swift Tests/GeneratedTests/GeneratedTests.swift
|
||||
sourcery: Source/SwiftLintFramework/Models/PrimaryRuleList.swift Source/SwiftLintFramework/Models/ReportersList.swift Tests/GeneratedTests/GeneratedTests.swift
|
||||
|
||||
Source/SwiftLintFramework/Models/PrimaryRuleList.swift: Source/SwiftLintFramework/Rules/**/*.swift .sourcery/PrimaryRuleList.stencil
|
||||
sourcery --sources Source/SwiftLintFramework/Rules --templates .sourcery/PrimaryRuleList.stencil --output .sourcery
|
||||
mv .sourcery/PrimaryRuleList.generated.swift Source/SwiftLintFramework/Models/PrimaryRuleList.swift
|
||||
|
||||
Source/SwiftLintFramework/Models/ReportersList.swift: Source/SwiftLintFramework/Reporters/*.swift .sourcery/ReportersList.stencil
|
||||
sourcery --sources Source/SwiftLintFramework/Reporters --templates .sourcery/ReportersList.stencil --output .sourcery
|
||||
mv .sourcery/ReportersList.generated.swift Source/SwiftLintFramework/Models/ReportersList.swift
|
||||
|
||||
Tests/GeneratedTests/GeneratedTests.swift: Source/SwiftLintFramework/Rules/**/*.swift .sourcery/GeneratedTests.stencil
|
||||
sourcery --sources Source/SwiftLintFramework/Rules --templates .sourcery/GeneratedTests.stencil --output .sourcery
|
||||
mv .sourcery/GeneratedTests.generated.swift Tests/GeneratedTests/GeneratedTests.swift
|
||||
|
|
|
@ -313,6 +313,7 @@ SUBCOMMANDS:
|
|||
docs Open SwiftLint documentation website in the default web browser
|
||||
generate-docs Generates markdown documentation for all rules
|
||||
lint (default) Print lint warnings and errors
|
||||
reporters Display the list of reporters and their identifiers
|
||||
rules Display the list of rules and their identifiers
|
||||
version Display the current version of SwiftLint
|
||||
|
||||
|
@ -554,7 +555,7 @@ identifier_name:
|
|||
- id
|
||||
- URL
|
||||
- GlobalAPIKey
|
||||
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)
|
||||
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging, summary)
|
||||
```
|
||||
|
||||
You can also use environment variables in your configuration file,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Generated using Sourcery 2.0.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
/// The rule list containing all available rules built into SwiftLint.
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
|
||||
/// The reporters list containing all the reporters built into SwiftLint.
|
||||
public let reportersList: [Reporter.Type] = [
|
||||
CSVReporter.self,
|
||||
CheckstyleReporter.self,
|
||||
CodeClimateReporter.self,
|
||||
EmojiReporter.self,
|
||||
GitHubActionsLoggingReporter.self,
|
||||
GitLabJUnitReporter.self,
|
||||
HTMLReporter.self,
|
||||
JSONReporter.self,
|
||||
JUnitReporter.self,
|
||||
MarkdownReporter.self,
|
||||
RelativePathReporter.self,
|
||||
SonarQubeReporter.self,
|
||||
SummaryReporter.self,
|
||||
XcodeReporter.self
|
||||
]
|
|
@ -7,6 +7,12 @@ public protocol Reporter: CustomStringConvertible {
|
|||
/// collected before generating the report.
|
||||
static var isRealtime: Bool { get }
|
||||
|
||||
/// A more detailed description of the reporter's output.
|
||||
static var description: String { get }
|
||||
|
||||
/// For CustomStringConvertible conformance.
|
||||
var description: String { get }
|
||||
|
||||
/// Return a string with the report for the specified violations.
|
||||
///
|
||||
/// - parameter violations: The violations to report.
|
||||
|
@ -15,43 +21,20 @@ public protocol Reporter: CustomStringConvertible {
|
|||
static func generateReport(_ violations: [StyleViolation]) -> String
|
||||
}
|
||||
|
||||
public extension Reporter {
|
||||
/// For CustomStringConvertible conformance.
|
||||
var description: String { Self.description }
|
||||
}
|
||||
|
||||
/// Returns the reporter with the specified identifier. Traps if the specified identifier doesn't correspond to any
|
||||
/// known reporters.
|
||||
///
|
||||
/// - parameter identifier: The identifier corresponding to the reporter.
|
||||
///
|
||||
/// - returns: The reporter type.
|
||||
public func reporterFrom(identifier: String) -> Reporter.Type { // swiftlint:disable:this cyclomatic_complexity
|
||||
switch identifier {
|
||||
case XcodeReporter.identifier:
|
||||
return XcodeReporter.self
|
||||
case JSONReporter.identifier:
|
||||
return JSONReporter.self
|
||||
case CSVReporter.identifier:
|
||||
return CSVReporter.self
|
||||
case CheckstyleReporter.identifier:
|
||||
return CheckstyleReporter.self
|
||||
case JUnitReporter.identifier:
|
||||
return JUnitReporter.self
|
||||
case HTMLReporter.identifier:
|
||||
return HTMLReporter.self
|
||||
case EmojiReporter.identifier:
|
||||
return EmojiReporter.self
|
||||
case SonarQubeReporter.identifier:
|
||||
return SonarQubeReporter.self
|
||||
case MarkdownReporter.identifier:
|
||||
return MarkdownReporter.self
|
||||
case GitHubActionsLoggingReporter.identifier:
|
||||
return GitHubActionsLoggingReporter.self
|
||||
case GitLabJUnitReporter.identifier:
|
||||
return GitLabJUnitReporter.self
|
||||
case CodeClimateReporter.identifier:
|
||||
return CodeClimateReporter.self
|
||||
case RelativePathReporter.identifier:
|
||||
return RelativePathReporter.self
|
||||
case SummaryReporter.identifier:
|
||||
return SummaryReporter.self
|
||||
default:
|
||||
public func reporterFrom(identifier: String) -> Reporter.Type {
|
||||
guard let reporter = reportersList.first(where: { $0.identifier == identifier }) else {
|
||||
queuedFatalError("no reporter with identifier '\(identifier)' available.")
|
||||
}
|
||||
return reporter
|
||||
}
|
||||
|
|
|
@ -6,10 +6,7 @@ public struct CSVReporter: Reporter {
|
|||
|
||||
public static let identifier = "csv"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as a newline-separated string of comma-separated values (CSV)."
|
||||
}
|
||||
public static let description = "Reports violations as a newline-separated string of comma-separated values (CSV)."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
let keys = [
|
||||
|
|
|
@ -5,10 +5,7 @@ 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 let description = "Reports violations as Checkstyle XML."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return [
|
||||
|
|
|
@ -10,10 +10,7 @@ public struct CodeClimateReporter: Reporter {
|
|||
|
||||
public static let identifier = "codeclimate"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as a JSON array in Code Climate format."
|
||||
}
|
||||
public static let description = "Reports violations as a JSON array in Code Climate format."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return toJSON(violations.map(dictionary(for:)))
|
||||
|
|
|
@ -4,10 +4,7 @@ public struct EmojiReporter: Reporter {
|
|||
|
||||
public static let identifier = "emoji"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations in the format that's both fun and easy to read."
|
||||
}
|
||||
public static let description = "Reports violations in the format that's both fun and easy to read."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
violations
|
||||
|
|
|
@ -4,10 +4,8 @@ public struct GitHubActionsLoggingReporter: Reporter {
|
|||
|
||||
public static let identifier = "github-actions-logging"
|
||||
public static let isRealtime = true
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations in the format GitHub-hosted virtual machine for Actions can recognize as messages."
|
||||
}
|
||||
public static let description = "Reports violations in the format GitHub-hosted virtual " +
|
||||
"machine for Actions can recognize as messages."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return violations.map(generateForSingleViolation).joined(separator: "\n")
|
||||
|
|
|
@ -4,10 +4,7 @@ public struct GitLabJUnitReporter: Reporter {
|
|||
|
||||
public static let identifier = "gitlab"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as JUnit XML supported by GitLab."
|
||||
}
|
||||
public static let description = "Reports violations as JUnit XML supported by GitLab."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<testsuites><testsuite>" +
|
||||
|
|
|
@ -12,10 +12,7 @@ public struct HTMLReporter: Reporter {
|
|||
|
||||
public static let identifier = "html"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as HTML."
|
||||
}
|
||||
public static let description = "Reports violations as HTML."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return generateReport(violations, swiftlintVersion: Version.current.value,
|
||||
|
|
|
@ -7,10 +7,7 @@ public struct JSONReporter: Reporter {
|
|||
|
||||
public static let identifier = "json"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as a JSON array."
|
||||
}
|
||||
public static let description: String = "Reports violations as a JSON array."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return toJSON(violations.map(dictionary(for:)))
|
||||
|
|
|
@ -4,10 +4,7 @@ public struct JUnitReporter: Reporter {
|
|||
|
||||
public static let identifier = "junit"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as JUnit XML."
|
||||
}
|
||||
public static let description = "Reports violations as JUnit XML."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
let warningCount = violations.filter({ $0.severity == .warning }).count
|
||||
|
|
|
@ -6,10 +6,7 @@ public struct MarkdownReporter: Reporter {
|
|||
|
||||
public static let identifier = "markdown"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations as markdown formated (with tables)."
|
||||
}
|
||||
public static let description = "Reports violations as markdown formated (with tables)."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
let keys = [
|
||||
|
|
|
@ -4,10 +4,7 @@ public struct RelativePathReporter: Reporter {
|
|||
|
||||
public static let identifier = "relative-path"
|
||||
public static let isRealtime = true
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations with relative paths."
|
||||
}
|
||||
public static let description = "Reports violations with relative paths."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return violations.map(generateForSingleViolation).joined(separator: "\n")
|
||||
|
|
|
@ -6,10 +6,7 @@ public struct SonarQubeReporter: Reporter {
|
|||
|
||||
public static let identifier = "sonarqube"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations in SonarQube import format."
|
||||
}
|
||||
public static let description = "Reports violations in SonarQube import format."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return toJSON(["issues": violations.map(dictionary(for:))])
|
||||
|
|
|
@ -8,9 +8,7 @@ public struct SummaryReporter: Reporter {
|
|||
public static let identifier = "summary"
|
||||
public static let isRealtime = false
|
||||
|
||||
public var description: String {
|
||||
return "Reports a summary table of all violations."
|
||||
}
|
||||
public static let description = "Reports a summary table of all violations."
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
TextTable(violations: violations).renderWithExtraSeparator()
|
||||
|
|
|
@ -4,10 +4,7 @@ public struct XcodeReporter: Reporter {
|
|||
|
||||
public static let identifier = "xcode"
|
||||
public static let isRealtime = true
|
||||
|
||||
public var description: String {
|
||||
return "Reports violations in the format Xcode uses to display in the IDE. (default)"
|
||||
}
|
||||
public static let description = "Reports violations in the format Xcode uses to display in the IDE. (default)"
|
||||
|
||||
public static func generateReport(_ violations: [StyleViolation]) -> String {
|
||||
return violations.map(generateForSingleViolation).joined(separator: "\n")
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import ArgumentParser
|
||||
import SwiftLintFramework
|
||||
import SwiftyTextTable
|
||||
|
||||
extension SwiftLint {
|
||||
struct Reporters: ParsableCommand {
|
||||
static let configuration = CommandConfiguration(abstract: "Display the list of reporters and their identifiers")
|
||||
|
||||
func run() throws {
|
||||
print(TextTable(reporters: reportersList).render())
|
||||
ExitHelper.successfullyExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SwiftyTextTable
|
||||
|
||||
private extension TextTable {
|
||||
init(reporters: [Reporter.Type]) {
|
||||
let columns = [
|
||||
TextTableColumn(header: "identifier"),
|
||||
TextTableColumn(header: "description")
|
||||
]
|
||||
self.init(columns: columns)
|
||||
for reporter in reporters {
|
||||
addRow(values: [
|
||||
reporter.identifier,
|
||||
reporter.description
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ struct SwiftLint: AsyncParsableCommand {
|
|||
Docs.self,
|
||||
GenerateDocs.self,
|
||||
Lint.self,
|
||||
Reporters.self,
|
||||
Rules.self,
|
||||
Version.self
|
||||
],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// Generated using Sourcery 2.0.0 — https://github.com/krzysztofzablocki/Sourcery
|
||||
// DO NOT EDIT
|
||||
@_spi(TestHelper)
|
||||
@testable import SwiftLintFramework
|
||||
|
|
|
@ -5,23 +5,7 @@ import XCTest
|
|||
|
||||
class ReporterTests: XCTestCase {
|
||||
func testReporterFromString() {
|
||||
let reporters: [Reporter.Type] = [
|
||||
CheckstyleReporter.self,
|
||||
CodeClimateReporter.self,
|
||||
CSVReporter.self,
|
||||
EmojiReporter.self,
|
||||
GitHubActionsLoggingReporter.self,
|
||||
GitLabJUnitReporter.self,
|
||||
HTMLReporter.self,
|
||||
JSONReporter.self,
|
||||
JUnitReporter.self,
|
||||
MarkdownReporter.self,
|
||||
RelativePathReporter.self,
|
||||
SonarQubeReporter.self,
|
||||
SummaryReporter.self,
|
||||
XcodeReporter.self
|
||||
]
|
||||
for reporter in reporters {
|
||||
for reporter in reportersList {
|
||||
XCTAssertEqual(reporter.identifier, reporterFrom(identifier: reporter.identifier).identifier)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue