-
Notifications
You must be signed in to change notification settings - Fork 1
/
.swiftlint.yml
410 lines (398 loc) · 15.2 KB
/
.swiftlint.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# Basic Configuration
opt_in_rules:
- array_init
- attributes
- closure_end_indentation
- closure_spacing
- conditional_returns_on_newline
- contains_over_first_not_nil
- convenience_type
- empty_count
- empty_string
- empty_xctest_method
- explicit_init
- explicit_type_interface
- fallthrough
- fatal_error_message
- file_header
- file_name
# - file_types_order
- first_where
- function_default_parameter_at_end
- is_disjoint
- joined_default_parameter
- let_var_whitespace
- literal_expression_end_indentation
- lower_acl_than_parent
- modifier_order
- multiline_arguments
- multiline_arguments_brackets
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
- nimble_operator
- no_extension_access_modifier
- number_separator
- object_literal
- operator_usage_whitespace
- overridden_super_call
- override_in_extension
- pattern_matching_keywords
- private_action
- private_outlet
- prohibited_super_call
- quick_discouraged_call
- quick_discouraged_focused_test
- quick_discouraged_pending_test
- redundant_nil_coalescing
- redundant_type_annotation
- single_test_class
- sorted_first_last
- sorted_imports
- switch_case_on_newline
- trailing_closure
# - type_contents_order
- unavailable_function
- unneeded_parentheses_in_closure_argument
- untyped_error_in_catch
- vertical_parameter_alignment_on_call
- vertical_whitespace_between_cases
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
- yoda_condition
disabled_rules:
- cyclomatic_complexity
- force_cast
- todo
- type_name
included:
- App/Sources
- Tests/Sources
- UITests/Sources
- Extensions
# Rule Configurations
conditional_returns_on_newline:
if_only: true
explicit_type_interface:
allow_redundancy: true
excluded:
- local
file_header:
required_pattern: |
\/\/
\/\/ Created by [^\(\)\d\n]+ on \S{6,10}\.
\/\/ Copyright © \d{4} DavidLaubenstein\. All rights reserved\.
\/\/
file_name:
suffix_pattern: "Extensions?|\\+.*"
# file_types_order:
# order:
# - supporting_type
# - main_type
# - extension
identifier_name:
max_length: 60
excluded:
- id
line_length: 160
nesting:
type_level: 3
# type_contents_order:
# order:
# - case
# - [type_alias, associated_type]
# - subtype
# - type_property
# - ib_inspectable
# - instance_property
# - ib_outlet
# - initializer
# - type_method
# - view_life_cycle_method
# - ib_action
# - other_method
# - subscript
# Custom Rules
custom_rules:
class_name_suffix_collection_view_controller:
included: ".*.swift"
regex: 'class +\w+(?<!CollectionViewController) *(?:<[^>]+>)? *: +\w+CollectionViewController'
name: "Class Name Suffix View Controller"
message: "All `CollectionViewController` subclasses should end on `CollectionViewController`."
severity: warning
class_name_suffix_table_view_controller:
included: ".*.swift"
regex: 'class +\w+(?<!TableViewController) *(?:<[^>]+>)? *: +\w+TableViewController'
name: "Class Name Suffix View Controller"
message: "All `TableViewController` subclasses should end on `TableViewController`."
severity: warning
class_name_suffix_view_controller:
included: ".*.swift"
regex: 'class +\w+(?<!ViewController) *(?:<[^>]+>)? *: +\w+ViewController'
name: "Class Name Suffix View Controller"
message: "All `ViewController` subclasses should end on `ViewController`."
severity: warning
closure_params_parantheses:
included: ".*.swift"
regex: '\{\s*\((?!self)[^):]+\)\s*in'
name: "Unnecessary Closure Params Parantheses"
message: "Don't use parantheses around non-typed parameters in a closure."
severity: warning
color_literal:
included: ".*.swift"
regex: '#colorLiteral\('
name: "Color Literal"
message: "Don't use color literals – use asset catalog and SwiftGen access instead."
severity: warning
comment_type_note:
included: ".*.swift"
regex: '// *(?:WORKAROUND|HACK|WARNING)[:\\s]'
name: "Comment Type NOTE"
message: "Use a '// NOTE:' comment instead."
severity: warning
comment_type_refactor:
included: ".*.swift"
regex: '// *(?:TODO|NOTE)[:\\s][^\n]*(?:refactor|REFACTOR|Refactor)'
name: "Comment Type REFACTOR"
message: "Use a '// REFACTOR:' comment instead."
severity: warning
comment_type_todo:
included: ".*.swift"
regex: '// *(?:BUG|MOCK|FIXME|RELEASE|TEST)[:\\s]'
name: "Comment Type TODO"
message: "Use a '// TODO:' comment instead."
severity: warning
controller_class_name_suffix:
included: ".*.swift"
regex: 'class +\w+(?<!View|Flow|Model)Controller'
name: "Controller Class Name Suffix"
message: "Only use the `Controller` class name suffix for ViewControllers or FlowControllers."
severity: warning
debug_log_level:
included: ".*.swift"
regex: 'log.debug\('
name: "Debug Log Level"
message: "Make sure to remove all debug log levels before committing."
severity: warning
dynamic_color_reference:
included: ".*.swift"
regex: 'UIColor\(\s*named:\s*\"'
name: "Dynamic Color Reference"
message: "Don't use dynamic color references – use SwiftGen & Color instead."
severity: warning
dynamic_storyboard_reference:
included: ".*.swift"
regex: 'UIStoryboard\(\s*name:\s*\"'
name: "Dynamic Storyboard Reference"
message: "Don't use dynamic storyboard references – use SwiftGen & StoryboardScene instead."
severity: warning
dynamic_string_reference:
included: ".*.swift"
regex: 'NSLocalizedString\s*\('
name: "Dynamic String Reference"
message: "Don't use dynamic localization string references via code strings – use SwiftGen & L10n instead."
severity: warning
empty_init_body:
included: ".*.swift"
regex: 'init\([^\{\n]*\) \{\s+\}'
name: "Empty Init Body"
message: "Don't use whitespace or newlines for the body of empty initializers – use `init() {}` instead."
severity: warning
empty_method:
included: ".*.swift"
regex: 'func [^\s\(]+\([^\{\n]*\) \{\s*\}'
name: "Empty Method"
message: "Don't keep empty methods in code without commenting inside why they are needed or a `// TODO: not yet implemented`."
severity: warning
empty_type:
included: ".*.swift"
regex: '(?:class|protocol|struct|enum) [^\{]+\{\s*\}'
name: "Empty Type"
message: "Don't keep empty types in code without commenting inside why they are needed or a `// TODO: not yet implemented`."
severity: warning
flow_controller_variable_naming:
included: ".*.swift"
regex: '(?:let|var) +\w*(?:fc|FC|Fc|flowC|flowController|FlowController) *='
name: "Flow Controller Variable Naming"
message: "Always name your flow controller variables with the suffix `FlowCtrl`."
severity: warning
handyswift_delay:
included: ".*.swift"
regex: 'DispatchQueue\.\S+\.asyncAfter\(deadline:'
name: "HandySwift Delay"
message: "Use the `delay(by:qosClass:)` method of HandySwift instead of DispatchQueue for delayed code."
severity: warning
handyswift_delay_time_interval:
included: ".*.swift"
regex: 'delay\(by: ?\d'
name: "HandySwift Delay TimeInterval"
message: "Use one of the HandySwift TimeInterval extension methods like `.milliseconds(100)` instead."
severity: warning
handyswift_time_interval:
included: ".*.swift"
regex: ':\s*(?:Dispatch)?TimeInterval\s*=\s*(?:[1-9]|0\.0*[1-9])'
name: "HandySwift TimeInterval"
message: "Use one of the HandySwift (Dispatch)TimeInterval extension methods like `.milliseconds(100)` instead."
severity: warning
if_as_guard:
included: ".*.swift"
regex: '(?<=\n) *if [^\{]+\{\s*return\s*(?:nil){0,1}([^a-zA-z\n]*)\n*\s*\}(?! *else)'
name: "If as Guard"
message: "Don't use an if statement to just return – use guard for such cases instead."
severity: warning
late_force_unwrapping:
included: ".*.swift"
regex: '\(\S+\?\.\S+\)!'
name: "Late Force Unwrapping"
message: "Don't use ? first to force unwrap later – directly unwrap within the parantheses."
severity: warning
local_l10n:
included: ".*.swift"
regex: 'func \S+\s*\{\s*[^\}]*let l10n'
name: "Local l10n"
message: "Don't name local variable `l10n` – use a property instead and further specify with `localL10n` if needed."
severity: warning
log_prefix:
included: ".*.swift"
regex: 'log\.(?:verbose|debug|info|warning|error)\("(?:verbose|debug|info|warning|error).*"\)'
name: "Logging Prefix"
message: "Don't use logging prefixes with log.verbose/debug/info/warning/error – done automatically."
severity: warning
multiple_closure_params:
included: ".*.swift"
regex: '\n *(?:[^\.\n=]+\.)+[^\(\s]+\([^\{\n]+\{[^\}\n]+\}\)\s*\{'
name: "Multiple Closure Params"
message: "Don't use multiple in-line closures – save one or more of them to variables instead."
severity: warning
none_case_enum:
included: ".*.swift"
regex: 'enum\s+[^\{]+\{(?:\s*\/\/[^\n]*)*(?:\s*case\s+[^\n]+)*\s*case\s+none[^\S]'
name: "Non Case Enum"
message: "Do not call enum cases `none` as you might run into problems with Optionals of this type."
severity: warning
quick_temporary_disabling:
included: ".*.swift"
regex: '\sxdescribe\(|\sxcontext\(|\sxit\('
name: "Quick Temporary Disabling"
message: "Temporary disabled Quick examples or groups shouldn't be commited."
severity: warning
quick_temporary_focus:
included: ".*.swift"
regex: '\sfdescribe\(|\sfcontext\(|\sfit\('
name: "Quick Temporary Focus"
message: "Temporary focused Quick examples or groups shouldn't be commited."
severity: warning
remove_where_for_negative_filtering:
included: ".*.swift"
regex: '\.filter *\{ *!\$0\.[^\}&|]+\}'
name: "Remove Where for Negative Filtering"
message: "Use `remove(where:)` instead of `filter(where not ...)` for performance."
severity: warning
single_line_enum_cases:
included: ".*.swift"
regex: 'enum [^\{]+\{\s*(?:\s*\/\/[^\n]*)*\s*case\s+[^,(\n]+,'
name: "Single Line Enum Cases"
message: "Use a new line for each enum case."
severity: warning
single_line_guard:
included: ".*.swift"
regex: 'guard[^\{]{2,80}else\s*\{\s*\n\s*return.{2,40}\}'
name: "Single Line Guard"
message: "Use a single line guard for simple checks."
severity: warning
singleton_default_private_init:
included: ".*.swift"
regex: 'class +(?<TYPE>\w+)(?:<[^\>]+>)? *\{.*static let `default`(?:: *\k<TYPE>)? *= *\k<TYPE>\(.*(?<=private) init\('
name: "Singleton Default Private Init"
message: "Singletons with a `default` object (pseudo-singletons) should not declare init methods as private."
severity: warning
singleton_shared_final:
included: ".*.swift"
regex: '(?<!final )class +(?<TYPE>\w+)(?:<[^\>]+>)? *\{.*static let shared(?:: *\k<TYPE>)? *= *\k<TYPE>\('
name: "Singleton Shared Final"
message: "Singletons with a single object (`shared`) should be marked as final."
severity: warning
singleton_shared_private_init:
included: ".*.swift"
regex: 'class +(?<TYPE>\w+)(?:<[^\>]+>)? *\{.*static let shared(?:: *\k<TYPE>)? *= *\k<TYPE>\(.*(?<= |\t|public|internal) init\('
name: "Singleton Shared Private Init"
message: "Singletons with a single object (`shared`) should declare their init method(s) as private."
severity: warning
singleton_shared_single_object:
included: ".*.swift"
regex: 'class +(?<TYPE>\w+)(?:<[^\>]+>)? *\{.*(?:static let shared(?:: *\k<TYPE>)? *= *\k<TYPE>\(.*static let \w+(?:: *\k<TYPE>)? *= *\k<TYPE>\(|static let \w+(?:: *\k<TYPE>)? *= *\k<TYPE>\(.*static let shared(?:: *\k<TYPE>)? *= *\k<TYPE>\()'
name: "Singleton Shared Single Object"
message: "Singletons with a `shared` object (real Singletons) should not have other static let properties. Use `default` instead (if needed)."
severity: warning
swiftybeaver_logging:
included: ".*.swift"
regex: 'print\([^\n]+\)'
name: "SwiftyBeaver Logging"
message: "Don't use print – use log.verbose/debug/info/warning/error instead."
severity: warning
switch_associated_value_style:
included: ".*.swift"
regex: 'case\s+[^\(][^\n]*(?:\(let |[^\)], let)'
name: "Switch Associated Value Style"
message: "Always put the `let` in front of case – even if only one associated value captured."
severity: warning
toggle_bool:
included: ".*.swift"
regex: '(?<=\n)[ \t]*(?<VAR>\w+) *= *!\k<VAR>(?=\s)'
name: "Toggle Bool"
message: "Use `toggle()` instead of toggling manually."
severity: warning
too_much_indentation:
included: ".*.swift"
regex: '\n {0}[^\s\/][^\n]*[^,|&]\n+ {5,}\S|\n {4}[^\s\/][^\n]*[^,|&]\n+ {9,}\S|\n {8}[^\s\/][^\n]*[^,|&]\n+ {13,}\S|\n {12}[^\s\/][^\n]*[^,|&]\n+ {17,}\S|\n {16}[^\s\/][^\n]*[^,|&]\n+ {21,}\S|\n {20}[^\s\/][^\n]*[^,|&]\n+ {25,}\S'
name: "Too Much Indentation"
message: "Don't indent code by more than 4 whitespaces."
severity: warning
too_much_unindentation:
included: ".*.swift"
regex: ' {28}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,23}[^\s\/]| {24}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,19}[^\s\/]| {20}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,15}[^\s\/]| {16}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,11}[^\s\/]| {12}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,7}[^\s\/]| {8}[^\s\.](.|[^\n]*[^\)][^\ ][^\}])\n+ {0,3}[^\s\/]'
name: "Too Much Unindentation"
message: "Don't unindent code by more than 4 whitespaces."
severity: warning
tuple_index:
included: ".*.swift"
regex: '(\$\d|\w*[^\d \(\[\{])\.\d'
name: "Tuple Index"
message: "Prevent unwraping tuples by their index – define a typealias with named components instead."
severity: warning
unnecessary_case_break:
included: ".*.swift"
regex: '(case |default)(?:[^\n\}]+\n){2,}\s*break *\n|\n *\n *break(?:\n *\n|\n *\})'
name: "Unnecessary Case Break"
message: "Don't use break in switch cases – Swift breaks by default."
severity: warning
unnecessary_nil_assignment:
included: ".*.swift"
regex: 'var \S+\s*:\s*[^\s]+\?\s*=\s*nil'
name: "Unnecessary Nil Assignment"
message: "Don't assign nil as a value when defining an optional type – it's nil by default."
severity: warning
vertical_whitespaces_around_mark:
included: ".*.swift"
regex: '\/\/\s*MARK:[^\n]*(\n\n)|(\n\n\n)[ \t]*\/\/\s*MARK:|[^\s{]\n[^\n\/]*\/\/\s*MARK:'
name: "Vertical Whitespaces Around MARK:"
message: "Include a single vertical whitespace (empty line) before and none after MARK: comments."
severity: warning
view_controller_variable_naming:
included: ".*.swift"
regex: '(?:let|var) +\w*(?:vc|VC|Vc|viewC|viewController|ViewController) *='
name: "View Controller Variable Naming"
message: "Always name your view controller variables with the suffix `ViewCtrl`."
severity: warning
whitespace_around_range_operators:
included: ".*.swift"
regex: '\w\.\.[<\.]\w'
name: "Whitespace around Range Operators"
message: "A range operator should be surrounded by a single whitespace."
severity: warning
whitespace_comment_start:
included: ".*.swift"
regex: '[^:#\]\}\)][^:#\]\}\)]\/\/[^\s\/]'
name: "Whitespace Comment Start"
message: "A comment should always start with a whitespace."
severity: warning