0

SwiftLint - How to allow one line guard conditionals like this:

guard let x = true else { return false }

and keep conditional_returns_on_newline functionality for other cases?

Edit:

As far as I know SwiftLint defines rules of violations so I have to write regex that scans lines through in search for:

if[...]{[...]}

Please be also aware of the cases like these:

if array1.sorted(by: { $0 > $1 }).first! > 0, array2.isEmpty { x = 1 }
Kaktusiarz
  • 415
  • 7
  • 22

3 Answers3

2

SwifLint rule conditional_returns_on_newline is Disabled by default. So,

  1. First of all enable conditional_returns_on_newline rule.
  2. Set the if_only to true

No need to write any custom rules

.swiftlint.yml configuration:

opt_in_rules: # some rules are only opt-in
    - conditional_returns_on_newline

conditional_returns_on_newline:
    if_only: true  

Here is the rule link:

https://realm.github.io/SwiftLint/conditional_returns_on_newline.html

MilanPanchal
  • 2,943
  • 1
  • 19
  • 37
1

There are two ways to achieve it.

  1. You can disable the conditional_returns_on_newline rule. You can disable it at the code blocks level, source file level, or at the project level by updating the rules file which is kept inside your project code folder. Doing so will disable the rule for each such statements (depends on the disabling scope) like if true { return } or if true { return "YES" } else { return "NO" } etc. Here is the explanation and I think you don't want to do it.

  2. The second is to write your own regex rules. You can define your custom regex-based rules in your configuration here is the detail explaination

EDIT

High-level implementation for point 2, follow the below steps.

  1. Open the .swiftlint.yml and disable the given rule conditional_returns_on_newline at the project level.
  2. Write your own custom rule that will only validate each conditional returns on the new line except the one line guard return.
  3. Add the custom rule (that I named ks_conditional_returns_on_newline) to your .swiftlint.yml file, You can decide the rule name, message, severity, and included etc parameters as per your need.

Example

custom_rules:
  ks_conditional_returns_on_newline:
    included: ".*\\.swift"
    name: "Custom Conditional Returns On New Line"
    regex: "(if)[^\n]*return"
    message: "Hey look at the the conditional returns on newline for if else"
    severity: error

I have validated the rule regex with Xcode and it worked fine. Though, I have not verified adding it to .swiftlint.yml. But I am hopeful it will work.

enter image description here

Kamar Shad
  • 6,089
  • 1
  • 29
  • 56
  • 1
    Only point 2 is acceptable in my case but how to construct it to handle all other conditional cases? – Kaktusiarz May 15 '20 at 19:16
  • @Kaktusiarz Thanks, I got your point. The high-level implementation, first of all, I will disable `conditional_returns_on_newline` rule. I will write a new custom rule `custom_conditional_returns_on_newline` in which will validate `if`, `else` conditional returns on newline except for guard. I will have to form a regex accordingly. Once I am done with regex formation I will update my answer. – Kamar Shad May 15 '20 at 19:50
  • @Kaktusiarz In the meantime, you can take an idea from this https://github.com/realm/SwiftLint/issues/2988 – Kamar Shad May 15 '20 at 19:51
  • @Kaktusiarz check the edit you can form the regex and define the custom rule accordingly. – Kamar Shad May 15 '20 at 20:15
  • Thank you for your answer bu unfortunately it is not so easy. Please look at my updated question. – Kaktusiarz May 15 '20 at 22:52
  • @Kaktusiarz I can see the edit but it's just not another use case. It's an add on to what you have asked in the 1st part of the question. You just wanted a `conditional_returns_on_newline` rule which should not validate the `guard` having `return` in the same line but should validate the rest of the cases. – Kamar Shad May 16 '20 at 12:18
1

I think I was able to find a satisfactory solution:

  1. Disable build-in rule - conditional_returns_on_newline.
  2. Define new custom rule for conditionals:
custom_rules:
  custom_conditional_returns_on_newline:
    name: "Conditional returns on new line"
    regex: '^[\h]*(if|else|while)[^\n]*\}$'
    message: "If/else and while constructions should not be defined in one line"
    severity: warning
  1. Add custom_rules to whitelist_rules.
Kaktusiarz
  • 415
  • 7
  • 22