Bryan V
Bryan V

Reputation: 537

Regex for SwiftLint custom rule not matching

I've created regex to determine if a class has an empty line following it. When searching in xcode, this works perfectly. However, swiftlint does not seem to work properly.

Rule is:

custom_rules:
  space_after_class:
    name: "No Space After Class"
    message: "Empty line required after class declarations"
    regex: '(^(open|internal|private|public)*class\s(?!func).*\{$\n(?!^\s*$))'
    severity: error

This works fine when searching in xcode/sublime/whatever, but for some reason in swiftlint all class declarations are returned (even those with a new line)

Example of search: enter image description here

Example of rule (notice the blank line- this is not found by the same regex using ctrl+f): enter image description here

What is different about the swiftlint regex that causes this?

Upvotes: 1

Views: 1157

Answers (2)

Cihat Gündüz
Cihat Gündüz

Reputation: 21478

Creating custom rules with SwiftLint is hard as there's no level of validation, like there is with tests for "normal" rules. Try out AnyLint instead which is written exactly to solve this issue. It's written in Swift, but works for any language as it's Regex-based.

Your use case would look like this in AnyLint (I fixed your regex):

// MARK: SpaceAfterClass
try Lint.checkFileContents(
    checkInfo: "SpaceAfterClass: Empty line required after class declarations.",
    regex: #"^((?:open |internal |private |public )?(?:final )?class (?!func)[^\n]+\{\n)(?!\s*\n)"#,
    matchingExamples: ["class MyClass {\n  let", "public final class MyClass {\n  let"],
    nonMatchingExamples: ["class MyClass {\n\n  let", "public final class MyClass {\n\n  let"],
    includeFilters: [#".*\.swift"#]
)

With AnyLint, you could even provide an autocorrectReplacement for autocorrection like so:

// MARK: SpaceAfterClass
try Lint.checkFileContents(
    checkInfo: ... // same parameters as above, plus:
    autoCorrectReplacement: "$1\n",
    autoCorrectExamples: [
        ["before": "class MyClass {\n  let", "class MyClass {\n  let"],
        ["before": "class MyClass {\n  let", "class MyClass {\n\n  let"],
    ]
)

I hope this helps.

Upvotes: 0

Lukas
Lukas

Reputation: 2535

Your yml file needs to be formated correctly. Try validating it with any yaml validators online. Seems your regex needs quotation marks " instead of `.

Upvotes: 0

Related Questions