Skip to content

Commit

Permalink
Merge pull request #9 from sunshinejr/inline
Browse files Browse the repository at this point in the history
Inline mode
  • Loading branch information
sunshinejr authored Apr 2, 2018
2 parents f746ef1 + 3250187 commit 590a160
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 19 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Next

- Nothing yet!
- Added `inline` option to `SwiftLint.lint()`. This will trigger an inline comment instead of gathering all violations in a big main comment. For more details about inline mode, see [this docs in Danger JS](https://github.com/danger/danger-js/blob/master/CHANGELOG.md#340).

## 0.2.1

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ SwiftLint.lint()

That will lint the created and modified files

#### Inline mode

If you want the lint result shows in diff instead of comment, you can use inline_mode option. Violations that out of the diff will show in danger's fail or warn section.

```swift
SwiftLint.lint(inline: true)
```

# Contributing

If you find a bug, please [open an issue](https://github.com/ashfurrow/danger-swiftlint/issues/new)! Or a pull request :wink:
Expand Down
51 changes: 37 additions & 14 deletions Sources/DangerSwiftLint/DangerSwiftLint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ public struct SwiftLint {
/// This is the main entry point for linting Swift in PRs using Danger-Swift.
/// Call this function anywhere from within your Dangerfile.swift.
@discardableResult
public static func lint(directory: String? = nil, configFile: String? = nil) -> [Violation] {
public static func lint(inline: Bool = false, directory: String? = nil, configFile: String? = nil) -> [Violation] {
// First, for debugging purposes, print the working directory.
print("Working directory: \(shellExecutor.execute("pwd"))")
return self.lint(danger: danger, shellExecutor: shellExecutor, directory: directory, configFile: configFile)
return self.lint(danger: danger, shellExecutor: shellExecutor, inline: inline, directory: directory, configFile: configFile)
}
}

Expand All @@ -20,10 +20,13 @@ internal extension SwiftLint {
static func lint(
danger: DangerDSL,
shellExecutor: ShellExecutor,
inline: Bool = false,
directory: String? = nil,
configFile: String? = nil,
markdown: (String) -> Void = markdown,
fail: (String) -> Void = fail) -> [Violation] {
markdownAction: (String) -> Void = markdown,
failAction: (String) -> Void = fail,
failInlineAction: (String, String, Int) -> Void = fail,
warnInlineAction: (String, String, Int) -> Void = warn) -> [Violation] {
// Gathers modified+created files, invokes SwiftLint on each, and posts collected errors+warnings to Danger.

var files = danger.git.createdFiles + danger.git.modifiedFiles
Expand All @@ -38,22 +41,42 @@ internal extension SwiftLint {
}
let outputJSON = shellExecutor.execute("swiftlint", arguments: arguments)
do {
return try decoder.decode([Violation].self, from: outputJSON.data(using: String.Encoding.utf8)!)
var violations = try decoder.decode([Violation].self, from: outputJSON.data(using: String.Encoding.utf8)!)
// Workaround for a bug that SwiftLint returns absolute path
violations = violations.map { violation in
var newViolation = violation
newViolation.update(file: file)

return newViolation
}

return violations
} catch let error {
fail("Error deserializing SwiftLint JSON response (\(outputJSON)): \(error)")
failAction("Error deserializing SwiftLint JSON response (\(outputJSON)): \(error)")
return []
}
}

if !violations.isEmpty {
var markdownMessage = """
### SwiftLint found issues
| Severity | File | Reason |
| -------- | ---- | ------ |\n
"""
markdownMessage += violations.map { $0.toMarkdown() }.joined(separator: "\n")
markdown(markdownMessage)
if inline {
violations.forEach { violation in
switch violation.severity {
case .error:
failInlineAction(violation.reason, violation.file, violation.line)
case .warning:
warnInlineAction(violation.reason, violation.file, violation.line)
}
}
} else {
var markdownMessage = """
### SwiftLint found issues
| Severity | File | Reason |
| -------- | ---- | ------ |\n
"""
markdownMessage += violations.map { $0.toMarkdown() }.joined(separator: "\n")
markdownAction(markdownMessage)
}
}

return violations
Expand Down
7 changes: 6 additions & 1 deletion Sources/DangerSwiftLint/Violation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ public struct Violation: Codable {
let reason: String
let line: Int
let character: Int?
let file: String
let severity: Severity
let type: String

private(set) var file: String

enum CodingKeys: String, CodingKey {
case ruleID = "rule_id"
Expand All @@ -32,6 +33,10 @@ public struct Violation: Codable {
let formattedFile = file.split(separator: "/").last! + ":\(line)"
return "\(severity.rawValue) | \(formattedFile) | \(reason) |"
}

mutating func update(file: String) {
self.file = file
}
}


Expand Down
18 changes: 15 additions & 3 deletions Tests/DangerSwiftLintTests/DangerSwiftLintTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ class DangerSwiftLintTests: XCTestCase {
XCTAssertNotEqual(executor.invocations.dropFirst().count, 0)
}

func testExecuteSwiftLintInInlineMode() {
mockViolationJSON()
var warns = [(String, String, Int)]()
let warnAction: (String, String, Int) -> Void = { warns.append(($0, $1, $2)) }

_ = SwiftLint.lint(danger: danger, shellExecutor: executor, inline: true, warnInlineAction: warnAction)

XCTAssertTrue(warns.first?.0 == "Opening braces should be preceded by a single space and on the same line as the declaration.")
XCTAssertTrue(warns.first?.1 == "SomeFile.swift")
XCTAssertTrue(warns.first?.2 == 8)
}

func testExecutesSwiftLintWithConfigWhenPassed() {
let configFile = "/Path/to/config/.swiftlint.yml"

Expand Down Expand Up @@ -58,13 +70,13 @@ class DangerSwiftLintTests: XCTestCase {

func testViolations() {
mockViolationJSON()
let violations = SwiftLint.lint(danger: danger, shellExecutor: executor, markdown: writeMarkdown)
let violations = SwiftLint.lint(danger: danger, shellExecutor: executor, markdownAction: writeMarkdown)
XCTAssertEqual(violations.count, 2) // Two files, one (identical oops) violation returned for each.
}

func testMarkdownReporting() {
mockViolationJSON()
_ = SwiftLint.lint(danger: danger, shellExecutor: executor, markdown: writeMarkdown)
_ = SwiftLint.lint(danger: danger, shellExecutor: executor, markdownAction: writeMarkdown)
XCTAssertNotNil(markdownMessage)
XCTAssertTrue(markdownMessage!.contains("SwiftLint found issues"))
}
Expand Down Expand Up @@ -92,7 +104,7 @@ class DangerSwiftLintTests: XCTestCase {
"rule_id" : "opening_brace",
"reason" : "Opening braces should be preceded by a single space and on the same line as the declaration.",
"character" : 39,
"file" : "/Users/ash/bin/Harvey/Sources/Harvey/Harvey.swift",
"file" : "/Users/ash/bin/SomeFile.swift",
"severity" : "Warning",
"type" : "Opening Brace Spacing",
"line" : 8
Expand Down

0 comments on commit 590a160

Please sign in to comment.