Created
August 24, 2019 14:59
-
-
Save CoBug92/2275cea4ecd0fccb2c84d661a27b0d90 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###################################################################### | |
# Rule whitelist | |
###################################################################### | |
# Let's use a whitelist policy: only rules from following list | |
# are enabled at the moment. So each rule should be enabled implicitly | |
# by adding to this list. | |
whitelist_rules: | |
# Closing brace with closing parenthesis should not | |
# have any whitespaces in the middle. | |
# Correct: find(where: { true }) | |
# Wrong: find(where: { true } ) | |
- closing_brace | |
# Closure end should have the same indentation as the line | |
# that started it. | |
# Correct: foo(abc, 123) { _ in } | |
# Correct: foo(abc, 123) { _ in | |
# true | |
# } | |
# Wrong: foo(abc, 123) { _ in | |
# true | |
# } | |
- closure_end_indentation | |
# Closure parameters should be on the same line as opening brace. | |
# Correct: | |
# foo(abc, 123) { x, y, z in | |
# return x * y * z | |
# } | |
# Wrong: | |
# foo(abc, 123) { | |
# x, y, z in | |
# return x * y * z | |
# } | |
# Wrong: | |
# foo(abc, 123) { | |
# x, y, z in return x * y * z | |
# } | |
- closure_parameter_position | |
# Expressions using curly braces should have a single space | |
# inside each brace. | |
# Correct: get { return refreshable?.isRefreshEnabled ?? false } | |
# Wrong: get { return refreshable?.isRefreshEnabled ?? false} | |
- closure_spacing | |
# Colons should be next to the identifier when specifying a type. | |
# Correct: let abc: Int | |
# Wrong: let abc:Int | |
# Wrong: let abc :Int | |
# Wrong: let abc : Int | |
- colon | |
# There should be no spaces before comma and exactly one space | |
# after it (unless it is the last character on the line). | |
# Correct: func abc(a: String, b: String) { } | |
# Wrong: func abc(a: String ,b: String) { } | |
# Wrong: func abc(a: String,b: String) { } | |
- comma | |
# if, for, while, do statements | |
# shouldn't wrap their conditionals in parentheses. | |
# Correct: if condition { | |
# Wrong: if (condition) { | |
- control_statement | |
# Arguments can be omitted when matching enums | |
# with associated types if they are not used. | |
# Correct: case .success: | |
# Wrong: case .success(_): | |
- empty_enum_arguments | |
# Prefer `() -> ` over `Void -> `. | |
# Correct: () -> Int | |
# Wrong: Void -> Int | |
# Wrong: (Void) -> Int | |
- empty_parameters | |
# When using trailing closures, empty parentheses | |
# should be avoided after the method name. | |
# Correct: [1, 2].map { $0 + 1 } | |
# Wrong: [1, 2].map() { $0 + 1 } | |
- empty_parentheses_with_trailing_closure | |
# Explicitly calling .init() should be avoided. | |
# Correct: [1].flatMap(String.init) | |
# Correct: [String.self].map { $0.init(1) } | |
# Wrong: [1].flatMap { String.init($0) } | |
- explicit_init | |
# Files should not span too many lines. | |
- file_length | |
# Prefer using `.first(where:)` over `.filter { }.first` in collections. | |
# Correct: myList.first(where: { $0 % 2 == 0 }) | |
# Wrong: myList.filter { $0 % 2 == 0 }.first | |
- first_where | |
# Force casts should be avoided. | |
# Correct: NSNumber() as? Int | |
# Wrong: NSNumber() as! Int | |
- force_cast | |
# Force tries should be avoided. | |
# Correct: func a() throws {}; do { try a() } catch {} | |
# Wrong: func a() throws {}; try! a() | |
- force_try | |
# Force unwrapping should be avoided. | |
# Correct: if let url = NSURL(string: query) | |
# Wrong: let url = NSURL(string: query)! | |
- force_unwrapping | |
# Computed read-only properties should avoid using the get keyword. | |
# Correct: | |
# var foo: Int { | |
# return 20 | |
# } | |
# Wrong: | |
# var foo: Int { | |
# get { return 20 } | |
# } | |
- implicit_getter | |
# Prefer implicit returns in closures. | |
# Correct: let b = str.characters.contains { $0 == 'c' } | |
# Wrong: let b = str.characters.contains { return $0 == 'c' } | |
- implicit_return | |
# Files should not contain leading whitespace. | |
- leading_whitespace | |
# Struct-scoped constants are preferred over legacy global constants. | |
# Correct: CGPoint.zero | |
# Wrong: CGPointZero | |
- legacy_constant | |
# Swift constructors are preferred over legacy convenience functions. | |
# Correct: CGSize(width: 10, height: 10) | |
# Wrong: CGSizeMake(10, 10) | |
- legacy_constructor | |
# Lines should not span too many characters. | |
# See details below in a rule configuration section. | |
- line_length | |
# MARK comment should be in valid format. | |
# e.g. '// MARK: ...' or '// MARK: - ...' | |
# Correct: // MARK: good | |
# Correct: // MARK: - good | |
# Wrong: //MARK: bad | |
# Wrong: // MARK:bad | |
# Wrong: // MARK: bad | |
- mark | |
# Types should be nested at most 1 level deep, and | |
# statements should be nested at most 5 levels deep. | |
- nesting | |
# Opening braces should be preceded by a single space and on the same line | |
# as the declaration. | |
# Correct: func abc() {} | |
# Wrong: func abc(){} | |
- opening_brace | |
# Operators should be surrounded by a single whitespace | |
# when they are being used. | |
# Correct: let a = b * c | |
# Wrong: let a = b* c | |
# Wrong: let a = b *c | |
# Wrong: let a = b*c | |
- operator_usage_whitespace | |
# Some overridden methods should always call super. | |
# Correct: | |
# open override | |
# func viewDidLoad() { | |
# super.viewDidLoad() | |
# ... | |
# } | |
# Wrong: | |
# open override | |
# func viewDidLoad() { | |
# ... // no super.viewDidLoad() call throughout the method | |
# } | |
- overridden_super_call | |
# Some methods should not call super. | |
# Correct: | |
# open override | |
# func loadView() { | |
# ... // no super.loadView() call throughout the method | |
# } | |
# Wrong: | |
# open override | |
# func loadView() { | |
# ... | |
# super.loadView() | |
# } | |
- prohibited_super_call | |
# Prefer `_ = foo()` over `let _ = foo()` when discarding a result | |
# from a function. | |
# Correct: _ = foo() | |
# Wrong: let _ = foo() | |
- redundant_discardable_let | |
# Coalescing operator with nil as rhs is redundant. | |
# Correct: | |
# var n1: Int? = nil | |
# var n2 = n1 | |
# Wrong: | |
# var n1: Int? = nil | |
# var n2 = n1 ?? nil | |
- redundant_nil_coalescing | |
# Initializing an optional variable with nil is redundant. | |
# Correct: var n: Int? | |
# Wrong: var n: Int? = nil | |
- redundant_optional_initialization | |
# String enum values can be omitted when | |
# they are equal to the enumcase name. | |
# Correct: | |
# enum SomeEnum: String { | |
# case one | |
# case two | |
# } | |
# Wrong: | |
# enum SomeEnum: String { | |
# case one = "one" | |
# case two = "two" | |
# } | |
- redundant_string_enum_value | |
# Returning Void in a function declaration is redundant. | |
# Correct: func someFunc() { ... } | |
# Wrong: func someFunc() -> Void { ... } | |
- redundant_void_return | |
# Return arrow and return type should be separated by a single space or on a | |
# separate line. | |
# Correct: func abc() -> Int {} | |
# Wrong: func abc()->Int {} | |
- return_arrow_whitespace | |
# Prefer shorthand operators (+=, -=, *=, /=) | |
# over doing the operation and assigning. | |
# Correct: n += 42 | |
# Wrong: n = n + 42 | |
- shorthand_operator | |
# Imports should be sorted. | |
# Correct: | |
# import AAA | |
# import BBB | |
# import CCC | |
# Wrong: | |
# import AAA | |
# import CCC | |
# import BBB | |
- sorted_imports | |
# Else and catch should be on the same line, one space after the previous | |
# declaration. | |
# Correct: } else if { | |
# Correct: } catch { | |
# Wrong: }else if { | |
# Wrong: } | |
# catch { | |
- statement_position | |
# Cases inside a switch should always be on a newline. | |
# Correct: | |
# switch self { | |
# | |
# case .hue: | |
# return "hue" | |
# case .red: | |
# return "red" | |
# case .green: | |
# return "green" | |
# | |
# } | |
# Wrong: | |
# switch self { | |
# | |
# case .hue: return "hue" | |
# case .red: return "red" | |
# case .green: return "green" | |
# | |
# } | |
- switch_case_on_newline | |
# Shorthand syntactic sugar should be used, | |
# i.e. [Int] instead of Array<Int>, | |
# [String: Int] instead of Dictionary<String, Int>, | |
# Int? instead of Optional<Int>, | |
# Int! instead of ImplicitlyUnwrappedOptional<Int> | |
# Correct: let n: Int? = 42 | |
# Wrong: let n: Optional<Int> = 42 | |
- syntactic_sugar | |
# TODOs and FIXMEs should be avoided. | |
- todo | |
# Files should have a single trailing newline. | |
- trailing_newline | |
# Lines should not have trailing semicolons. | |
# Correct: let a = 0 | |
# Wrong: let a = 0; | |
- trailing_semicolon | |
# Lines should not have trailing whitespace. | |
- trailing_whitespace | |
# Type name should only contain alphanumeric characters, start with an | |
# uppercase character. Max and min limits are configured in Rule | |
# Configuration section. | |
# Correct: class MyType {} | |
# Wrong: class myType {} | |
# Wrong: class _MyType {} | |
- type_name | |
# Unused parameter in a closure should be replaced with _. | |
# Correct: { _ in return x * 42 } | |
# Wrong: { n in return x * 42 } | |
- unused_closure_parameter | |
# When the index or the item is not used, | |
# `.enumerated()` can be removed. | |
# Correct: | |
# for el in [1, 2, 3] { | |
# print(el) | |
# } | |
# Wrong: | |
# for (_, el) in [1, 2, 3].enumerated() { | |
# print(el) | |
# } | |
- unused_enumerated | |
# Use `if ... != nil` instead `if let _ = ...` | |
# Correct: | |
# if view != nil { | |
# view.addSubview(someSubview) | |
# } | |
# Wrong: | |
# if let _ = view { | |
# view.addSubview(someSubview) | |
# } | |
- unused_optional_binding | |
# Limit vertical whitespace to a single empty line. | |
# Correct: | |
# let n1 = 42 | |
# | |
# let n2 = 43 | |
# Wrong: | |
# let n1 = 42 | |
# | |
# | |
# let n2 = 43 | |
- vertical_whitespace | |
# Prefer `-> Void` over `-> ()`. | |
# Correct: func someFunc(fooParam: () -> Void) { ... } | |
# Wrong: func someFunc(fooParam: () -> ())) { ... } | |
- void_return | |
# Enables enforcing custom rules (see custom rules below) | |
- custom_rules | |
###################################################################### | |
# Rule configuration | |
###################################################################### | |
# Closing brace | |
closing_brace: | |
severity: error | |
# Closure end indentation | |
closure_end_indentation: | |
severity: error | |
# Spaces aroung curly braces | |
closure_spacing: | |
severity: error | |
# Closure parameter position (on the same line with opening brace) | |
closure_parameter_position: | |
severity: error | |
# Colon | |
colon: | |
severity: error | |
# Comma | |
comma: | |
severity: error | |
# Control statement (no parentheses after control statement) | |
control_statement: | |
severity: error | |
# Don't introduce unused enum associated values | |
empty_enum_arguments: | |
severity: error | |
# Prefer `() -> ` over `Void -> ` | |
empty_parameters: | |
severity: error | |
# No empty parentheses just before trailing closure | |
empty_parentheses_with_trailing_closure: | |
severity: error | |
# Use explicit init call only when necessary | |
explicit_init: | |
severity: error | |
# File length limitation | |
file_length: | |
warning: 300 | |
error: 400 | |
# Prefer using `.first(where:)` over `.filter { }.first` in collections | |
first_where: | |
severity: error | |
# Force casts | |
force_cast: | |
severity: error | |
# Force tries | |
force_try: | |
severity: error | |
# Force unwrapping | |
force_unwrapping: | |
severity: error | |
# Don't use get keyword for computed read-only properties | |
implicit_getter: | |
severity: error | |
# Prefer implicit returns in closures | |
implicit_return: | |
severity: error | |
# Files should not contain leading whitespace | |
leading_whitespace: | |
severity: error | |
# Maximum line length | |
line_length: | |
warning: 120 | |
error: 120 | |
# MARK comment format | |
mark: | |
severity: error | |
# Nesting | |
nesting: | |
severity: error | |
# Avoid legacy constants like CGSizeZero | |
legacy_constant: | |
severity: error | |
# Avoid legacy convenience functions like CGSizeMake | |
legacy_constructor: | |
severity: error | |
# Opening braces | |
opening_brace: | |
severity: error | |
# Whitespaces around operator usage | |
operator_usage_whitespace: | |
severity: error | |
# Required super call override | |
overridden_super_call: | |
severity: error | |
# Prohibited super call | |
prohibited_super_call: | |
severity: error | |
# Redundant discardable let | |
redundant_discardable_let: | |
severity: error | |
# Redundant nil coalescing | |
redundant_nil_coalescing: | |
severity: error | |
# No need to initialize optional with nil | |
redundant_optional_initialization: | |
severity: error | |
# Redundant explicit raw values for string enums | |
redundant_string_enum_value: | |
severity: error | |
# No need to declare returning void from functions | |
redundant_void_return: | |
severity: error | |
# Whitespaces around return arrow | |
return_arrow_whitespace: | |
severity: error | |
# Use shorthand math operators when possible | |
shorthand_operator: | |
severity: error | |
# Import statements should be sorted | |
sorted_imports: | |
severity: error | |
# else and catch keyword positions | |
statement_position: | |
severity: error | |
# Switch cases should be on separate lines | |
switch_case_on_newline: | |
severity: error | |
# [Int] preferred to Array<Int>, ? instead Optional etc | |
syntactic_sugar: | |
severity: error | |
# TODOs and FIXMEs | |
todo: | |
severity: warning | |
# Single trailing newline | |
trailing_newline: | |
severity: error | |
# No trailing semicolons | |
trailing_semicolon: | |
severity: error | |
# Trailing whitespaces | |
trailing_whitespace: | |
severity: error | |
# Type naming rule | |
type_name: | |
# Minimum limit is 0 so types can have very short names like X, Y | |
min_length: | |
warning: 0 | |
error: 0 | |
# Limit type name length to reasonable value so they should stay | |
# readable | |
max_length: | |
warning: 30 | |
error: 50 | |
# use _ instead of unused closure parameter | |
unused_closure_parameter: | |
severity: error | |
# Use enumerated() only when you need index | |
unused_enumerated: | |
severity: error | |
# Use `if ... != nil` instead `if let _ = ...` | |
unused_optional_binding: | |
severity: error | |
# Limit vertical whitespace to a single empty line | |
vertical_whitespace: | |
severity: error | |
# Use `-> Void` instead of `-> ()` in closures | |
void_return: | |
severity: error | |
###################################################################### | |
# Custom rules | |
###################################################################### | |
custom_rules: | |
# Wrong: | |
# func abc(a: String, b: String) { } | |
# Wrong: | |
# func abc(a: String, b: String) { } | |
# Wrong: | |
# func abc(a: String, b: String) { } | |
# Correct: | |
# func abc(a: String, b: String) { } | |
indentation_custom_rule: | |
name: "Indentation Rule" | |
regex: "\ | |
^\\h{1,3}\\H|\ | |
^\\h{5,7}\\H|\ | |
^\\h{9,11}\\H|\ | |
^\\h{13,15}\\H|\ | |
^\\h{17,19}\\H|\ | |
^\\h{21,23}\\H|\ | |
^\\h{25,}?\\H" | |
match_kinds: | |
- argument | |
- attribute.builtin | |
- attribute.id | |
- comment | |
- comment.mark | |
- comment.url | |
- identifier | |
- keyword | |
- number | |
- objectliteral | |
- parameter | |
- placeholder | |
- typeidentifier | |
message: "Number of initial line whitespaces should be 0 or | |
divisible by 4 and shouldn't be greater than 24." | |
severity: error | |
# Wrong: | |
# case BMP = "bmp" | |
# case TIFF = "tiff" | |
# Correct: | |
# case BMP = "bmp" | |
# case TIFF = "tiff" | |
# Known issues: | |
# Following line is linted successfully for some reason: | |
# let blue = CGFloat( ( hex & 0x0000FF) >> 0) / 0xFF | |
# It looks like it has something to do with parentheses and slashes, | |
# maybe it's a side effect of other rules. | |
duplicated_spaces_custom_rule: | |
name: "Duplicated spaces rule" | |
regex: '\S\h{2,}?\S' | |
match_kinds: | |
- argument | |
- identifier | |
- keyword | |
- number | |
- objectliteral | |
- parameter | |
- placeholder | |
- typeidentifier | |
message: "There should be no multiple consecutive spaces in a line | |
(except indentation spaces in a beginning of a line)." | |
severity: error | |
# Wrong: | |
# override public | |
# Correct: | |
# public override | |
access_control_custom_rule: | |
name: "Access control rule" | |
regex: '(^|\h)\w+\h+(open|public|internal|fileprivate|private)(?!\(set\))' | |
match_kinds: | |
- attribute.builtin | |
message: "Access control modifier should precede other modifiers." | |
severity: error | |
# Wrong: | |
# func abc(a:"a") { } | |
# Correct: | |
# func abc(a: "a") { } | |
space_after_colon_custom_rule: | |
name: "Space after colon rule" | |
regex: '\w:[^\s)]' | |
match_kinds: | |
- identifier | |
- typeidentifier | |
message: "Colon should be followed by whitespace." | |
severity: error | |
excluded: | |
- Carthage | |
- Pods | |
- Etalon2.0/Resources/Storyboards | |
- Etalon2.0/Resources/Generated |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment