Update SwiftLint and SwiftFormat (#613)

* Update Swift version used by SwiftFormat

* Update SwiftLint version

* Rely on new virtual 'all' rule in SwiftLint

* Enable SwiftLint rule 'direct_return' rule and fix all violations

* Enable SwiftLint rule 'shorthand_optional_binding' rule and fix all violations

* Enable SwiftLint rule 'blanket_disable_command' rule and fix all violations
This commit is contained in:
Danny Mösch 2023-04-23 22:01:37 +02:00 committed by GitHub
parent a22e872a8c
commit d9bd0f3014
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 90 additions and 272 deletions

View file

@ -1 +1 @@
5.3.1
5.8

View file

@ -10,219 +10,50 @@ excluded:
## Active rules
only_rules:
- accessibility_label_for_image
# - anonymous_argument_in_multiline_closure
- anyobject_protocol
- array_init
- attributes
# - balanced_xctest_lifecycle
- block_based_kvo
- capture_variable
- class_delegate_protocol
- closing_brace
- closure_body_length
- closure_end_indentation
- closure_parameter_position
- closure_spacing
- collection_alignment
- colon
- comma
- comma_inheritance
- comment_spacing
- compiler_protocol_init
- computed_accessors_order
- conditional_returns_on_newline
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- control_statement
- convenience_type
- custom_rules
- cyclomatic_complexity
- deployment_target
- discarded_notification_center_observer
- discouraged_assert
- discouraged_direct_init
# - discouraged_none_name
# - discouraged_object_literal
- discouraged_optional_boolean
# - discouraged_optional_collection # Too many false positives in implementations of system protocols.
- duplicated_key_in_dictionary_literal
- duplicate_enum_cases
- duplicate_imports
- dynamic_inline
- empty_collection_literal
# - empty_count # Too many false positives for variables named 'count'.
- empty_enum_arguments
- empty_parameters
- empty_parentheses_with_trailing_closure
- empty_string
- empty_xctest_method
- enum_case_associated_values_count
- expiring_todo
# - explicit_acl
# - explicit_enum_raw_value # Disabled in favor of 'redundant_string_enum_value'.
- explicit_init
- explicit_self
# - explicit_top_level_acl
# - explicit_type_interface
# - extension_access_modifier
- fallthrough
- fatal_error_message
# - file_header
# - file_length
# - file_name
- file_name_no_space
# - file_types_order
- first_where
- flatmap_over_map_reduce
- for_where
# - force_cast
# - force_try
# - force_unwrapping
# - function_body_length
- function_default_parameter_at_end
- function_parameter_count
- generic_type_name
- ibinspectable_in_extension
- identical_operands
- identifier_name
- implicit_getter
- implicit_return
# - implicitly_unwrapped_optional
- inclusive_language
# - indentation_width
- inert_defer
- is_disjoint
- joined_default_parameter
- large_tuple
- last_where
- leading_whitespace
# - legacy_objc_type
- legacy_cggeometry_functions
- legacy_constant
- legacy_constructor
- legacy_hashing
- legacy_multiple
- legacy_nsgeometry_functions
- legacy_random
- let_var_whitespace
# - line_length
- literal_expression_end_indentation
- lower_acl_than_parent
- mark
# - missing_docs
- modifier_order
- multiline_arguments
- multiline_arguments_brackets
- multiline_function_chains
- multiline_literal_brackets
- multiline_parameters
- multiline_parameters_brackets
- multiple_closures_with_trailing_closure
- nesting
- nimble_operator
# - no_extension_access_modifier
- no_fallthrough_only
# - no_grouping_extension
- no_space_in_method_call
- notification_center_detachment
- nslocalizedstring_key
- nslocalizedstring_require_bundle
- nsobject_prefer_isequal
# - number_separator # Contradicts with SwiftFormat rule 'decimalgrouping'. There are not many numbers anyway in the source code.
- object_literal
- opening_brace
- operator_usage_whitespace
- operator_whitespace
- optional_enum_case_matching
- orphaned_doc_comment
- overridden_super_call
- override_in_extension
- pattern_matching_keywords
# - prefer_nimble
- prefer_self_in_static_references
- prefer_self_type_over_type_of_self
- prefer_zero_over_explicit_init
# - prefixed_toplevel_constant # Violations are mostly in test code.
- private_action
# - private_outlet
- private_over_fileprivate
- private_subject
- private_unit_test
# - prohibited_interface_builder
# - prohibited_super_call
- protocol_property_accessors_order
- quick_discouraged_call
- quick_discouraged_focused_test
- quick_discouraged_pending_test
- raw_value_for_camel_cased_codable_enum
- reduce_boolean
- reduce_into
- redundant_discardable_let
- redundant_nil_coalescing
- redundant_objc_attribute
- redundant_optional_initialization
- redundant_set_access_control
- redundant_string_enum_value
- redundant_type_annotation
- redundant_void_return
# - required_deinit
- required_enum_case
- return_arrow_whitespace
- return_value_from_void_function
- self_in_property_initialization
- shorthand_operator
- single_test_class
- sorted_first_last
# - sorted_imports # Managed by SwiftFormat.
- statement_position
- static_operator
- strict_fileprivate
- strong_iboutlet
- superfluous_disable_command
- switch_case_alignment
- switch_case_on_newline
- syntactic_sugar
- test_case_accessibility
- todo
- toggle_bool
- trailing_closure
- trailing_comma
- trailing_newline
- trailing_semicolon
- trailing_whitespace
# - type_body_length
# - type_contents_order
- type_name
- unavailable_condition
- unavailable_function
- unneeded_break_in_switch
- unneeded_parentheses_in_closure_argument
# - unowned_variable_capture
- untyped_error_in_catch
- unused_capture_list
- unused_closure_parameter
- unused_control_flow_label
- unused_declaration
- unused_enumerated
- unused_import
- unused_optional_binding
- unused_setter_value
- valid_ibinspectable
- vertical_parameter_alignment
- vertical_parameter_alignment_on_call
- vertical_whitespace
# - vertical_whitespace_between_cases # Additional whitespace not needed because of visible indentation.
- vertical_whitespace_closing_braces
- vertical_whitespace_opening_braces
- void_return
- weak_delegate
- xct_specific_matcher
- xctfail_message
- yoda_condition
opt_in_rules:
- all
disabled_rules:
- anonymous_argument_in_multiline_closure
- balanced_xctest_lifecycle
- discouraged_none_name
- discouraged_object_literal
- discouraged_optional_collection # Too many false positives in implementations of system protocols.
- empty_count # Too many false positives for variables named 'count'.
- explicit_acl
- explicit_enum_raw_value # Disabled in favor of 'redundant_string_enum_value'.
- explicit_top_level_acl
- explicit_type_interface
- extension_access_modifier
- file_header
- file_length
- file_name
- file_types_order
- force_cast
- force_try
- force_unwrapping
- function_body_length
- implicitly_unwrapped_optional
- indentation_width
- legacy_objc_type
- line_length
- missing_docs
- no_extension_access_modifier
- no_grouping_extension
- no_magic_numbers # Causes a lot of violations in tests.
- number_separator # Contradicts with SwiftFormat rule 'decimalgrouping'. There are not many numbers anyway in the source code.
- prefer_nimble
- prefixed_toplevel_constant # Violations are mostly in test code.
- private_outlet
- prohibited_interface_builder
- prohibited_super_call
- required_deinit
- self_binding
- sorted_imports # Managed by SwiftFormat.
- type_body_length
- type_contents_order
- unowned_variable_capture
- vertical_whitespace_between_cases # Additional whitespace not needed because of visible indentation.
## Configuration for specific rules

View file

@ -20,10 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
lazy var passcodeLockPresenter: PasscodeLockPresenter = {
let presenter = PasscodeLockPresenter(mainWindow: self.window)
return presenter
}()
lazy var passcodeLockPresenter: PasscodeLockPresenter = .init(mainWindow: self.window)
func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

View file

@ -13,10 +13,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
private static let VALUE_NOT_AVAILABLE = "ValueNotAvailable".localize()
private var needRefresh = false
private var indicator: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(style: .medium)
return indicator
}()
private var indicator: UIActivityIndicatorView = .init(style: .medium)
private let passwordStore = PasswordStore.shared

View file

@ -80,7 +80,7 @@ class AdvancedSettingsTableViewController: UITableViewController {
present(alert, animated: true, completion: nil)
} else if tableView.cellForRow(at: indexPath) == clearSuggestionsTableViewCell {
ASCredentialIdentityStore.shared.removeAllCredentialIdentities { _, error in
if let error = error {
if let error {
SVProgressHUD.showError(withStatus: "FailedToClearQuickTypeSuggestions".localize(error))
SVProgressHUD.dismiss(withDelay: 1)
} else {

View file

@ -83,10 +83,10 @@ extension PGPKeyFileImportTableViewController: PGPKeyImporter {
}
func importKeys() throws {
if let publicKey = publicKey {
if let publicKey {
try KeyFileManager.PublicPGP.importKey(from: publicKey)
}
if let privateKey = privateKey {
if let privateKey {
try KeyFileManager.PrivatePGP.importKey(from: privateKey)
}
}

View file

@ -43,12 +43,12 @@ extension PGPKeyURLImportTableViewController: PGPKeyImporter {
}
func importKeys() throws {
if let pgpPrivateKeyURL = pgpPrivateKeyURL {
if let pgpPrivateKeyURL {
Defaults.pgpPrivateKeyURL = pgpPrivateKeyURL
try KeyFileManager.PrivatePGP.importKey(from: pgpPrivateKeyURL)
}
if let pgpPublicKeyURL = pgpPublicKeyURL {
if let pgpPublicKeyURL {
Defaults.pgpPublicKeyURL = pgpPublicKeyURL
try KeyFileManager.PublicPGP.importKey(from: pgpPublicKeyURL)
}

View file

@ -30,10 +30,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
// preserve path so it can be reloaded even if the passwordEntity is deleted during the update process
private var passwordPath: String?
private lazy var editUIBarButtonItem: UIBarButtonItem = {
let uiBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit))
return uiBarButtonItem
}()
private lazy var editUIBarButtonItem: UIBarButtonItem = .init(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit))
private struct TableSection {
var type: PasswordDetailTableViewControllerSectionType
@ -112,7 +109,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
}
private func decryptThenShowPasswordLocalKey(keyID: String? = nil) {
guard let passwordEntity = passwordEntity else {
guard let passwordEntity else {
Utils.alert(title: "CannotShowPassword".localize(), message: "PasswordDoesNotExist".localize(), controller: self, completion: {
self.navigationController!.popViewController(animated: true)
})
@ -259,7 +256,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
// main section
section = TableSection(type: .main)
let password = self.password!
let password = password!
if let username = password.username {
section.item.append(Constants.USERNAME_KEYWORD => username)
}
@ -607,7 +604,7 @@ extension PasswordDetailTableViewController {
}
private func decryptThenShowPasswordYubiKey() {
guard let passwordEntity = passwordEntity else {
guard let passwordEntity else {
handleError(error: AppError.other(message: "PasswordDoesNotExist"))
return
}

View file

@ -254,7 +254,7 @@ class PasswordNavigationViewController: UIViewController {
if gesture.state == UIGestureRecognizer.State.began {
let touchPoint = gesture.location(in: tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
guard let dataSource = dataSource else {
guard let dataSource else {
return
}
let passwordTableEntry = dataSource.getPasswordTableEntry(at: indexPath)
@ -283,7 +283,7 @@ class PasswordNavigationViewController: UIViewController {
extension PasswordNavigationViewController: UITableViewDelegate {
func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
guard let dataSource = dataSource else {
guard let dataSource else {
return
}
let entry = dataSource.getPasswordTableEntry(at: indexPath)

View file

@ -75,7 +75,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
// Initialize QR Code Frame to highlight the QR code
qrCodeFrameView = UIView()
if let qrCodeFrameView = qrCodeFrameView {
if let qrCodeFrameView {
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
qrCodeFrameView.layer.borderWidth = 2
view.addSubview(qrCodeFrameView)

View file

@ -70,7 +70,7 @@ extension SSHKeyFileImportTableViewController: KeyImporter {
}
func importKeys() throws {
guard let privateKey = privateKey else {
guard let privateKey else {
return
}
try KeyFileManager.PrivateSSH.importKey(from: privateKey)

View file

@ -241,7 +241,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
@objc
func alertTextFieldDidChange(_ sender: UITextField) {
// check whether we should enable the Save button in setPasscodeLockAlert
if let setPasscodeLockAlert = setPasscodeLockAlert,
if let setPasscodeLockAlert,
let setPasscodeLockAlertTextFields0 = setPasscodeLockAlert.textFields?[0],
let setPasscodeLockAlertTextFields1 = setPasscodeLockAlert.textFields?[1] {
if sender == setPasscodeLockAlertTextFields0 || sender == setPasscodeLockAlertTextFields1 {

View file

@ -15,7 +15,7 @@ class UICodeHighlightingLabel: UILocalizedLabel {
override func awakeFromNib() {
super.awakeFromNib()
guard let text = text else {
guard let text else {
return
}
attributedText = formatCode(in: text)

View file

@ -129,7 +129,7 @@ open class PasscodeLockViewController: UIViewController, UITextFieldDelegate {
override open func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let biometryAuthButton = biometryAuthButton {
if let biometryAuthButton {
bioButtonPressedAction(biometryAuthButton)
}
}

View file

@ -72,7 +72,7 @@ struct GopenPGPInterface: PGPInterface {
func decrypt(encryptedData: Data, keyID: String?, passphrase: String) throws -> Data? {
let key: CryptoKey? = {
if let keyID = keyID {
if let keyID {
return privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
}
return privateKeys.first?.value
@ -109,7 +109,7 @@ struct GopenPGPInterface: PGPInterface {
func encrypt(plainData: Data, keyID: String?) throws -> Data {
let key: CryptoKey? = {
if let keyID = keyID {
if let keyID {
return publicKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
}
return publicKeys.first?.value

View file

@ -47,7 +47,7 @@ public class PGPAgent {
public func decrypt(encryptedData: Data, keyID: String, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Data? {
// Init keys.
try checkAndInit()
guard let pgpInterface = pgpInterface else {
guard let pgpInterface else {
throw AppError.decryption
}
@ -82,7 +82,7 @@ public class PGPAgent {
public func encrypt(plainData: Data, keyID: String) throws -> Data {
try checkAndInit()
guard let pgpInterface = pgpInterface else {
guard let pgpInterface else {
throw AppError.encryption
}
var keyID = keyID
@ -120,7 +120,7 @@ public class PGPAgent {
public func encrypt(plainData: Data) throws -> Data {
try checkAndInit()
guard let pgpInterface = pgpInterface else {
guard let pgpInterface else {
throw AppError.encryption
}
return try pgpInterface.encrypt(plainData: plainData, keyID: nil)

View file

@ -37,7 +37,7 @@ public extension FileManager {
}
// We have to enumerate all directory contents, including subdirectories.
let enumerator = self.enumerator(
let enumerator = enumerator(
at: directoryURL,
includingPropertiesForKeys: prefetchedProperties,
options: Self.DirectoryEnumerationOptions(),

View file

@ -9,8 +9,7 @@ import YubiKit
public enum YubiKeyAPDU {
public static func selectOpenPGPApplication() -> YKFSelectApplicationAPDU {
let selectOpenPGPAPDU = YKFSelectApplicationAPDU(data: Data([0xD2, 0x76, 0x00, 0x01, 0x24, 0x01]))!
return selectOpenPGPAPDU
YKFSelectApplicationAPDU(data: Data([0xD2, 0x76, 0x00, 0x01, 0x24, 0x01]))!
}
public static func verify(password: String) -> YKFAPDU {
@ -22,8 +21,7 @@ public enum YubiKeyAPDU {
apdu += [0x82] // P2: PW1
apdu += withUnsafeBytes(of: UInt8(pw1.count).bigEndian, Array.init)
apdu += pw1
let verifyApdu = YKFAPDU(data: Data(apdu))!
return verifyApdu
return YKFAPDU(data: Data(apdu))!
}
public static func decipherExtended(data: Data) -> [YKFAPDU] {

View file

@ -113,7 +113,7 @@ public class Password {
private func checkPasswordForOtpToken() {
let (key, value) = Parser.getKeyValuePair(from: password)
if let key = key, Constants.isOtpKeyword(key) {
if let key, Constants.isOtpKeyword(key) {
firstLineIsOTPField = true
additions.append(key => value)
} else {

View file

@ -11,7 +11,7 @@ import SwiftyUserDefaults
public extension PasswordEntity {
var nameWithCategory: String {
if let path = path {
if let path {
if path.hasSuffix(".gpg") {
return String(path.prefix(upTo: path.index(path.endIndex, offsetBy: -4)))
}

View file

@ -199,7 +199,7 @@ public class PasswordStore {
}
private func checkoutAndChangeBranch(withName localBranchName: String, progressBlock: @escaping (String, UInt, UInt) -> Void) throws {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
let remoteBranchName = "origin/\(localBranchName)"
@ -218,7 +218,7 @@ public class PasswordStore {
options: [String: Any],
progressBlock: @escaping (UnsafePointer<git_transfer_progress>, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _ in }
) throws {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
let remote = try GTRemote(name: "origin", in: storeRepository)
@ -284,7 +284,7 @@ public class PasswordStore {
}
public func getRecentCommits(count: Int) throws -> [GTCommit] {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
return []
}
var commits = [GTCommit]()
@ -328,8 +328,7 @@ public class PasswordStore {
let passwordEntityFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PasswordEntity")
passwordEntityFetchRequest.predicate = NSPredicate(format: "synced = %i", 0)
do {
let passwordEntities = try context.fetch(passwordEntityFetchRequest) as! [PasswordEntity]
return passwordEntities
return try context.fetch(passwordEntityFetchRequest) as! [PasswordEntity]
} catch {
fatalError("FailedToFetchPasswords".localize(error))
}
@ -357,7 +356,7 @@ public class PasswordStore {
}
public func getLatestUpdateInfo(filename: String) -> String {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
return "Unknown".localize()
}
guard let blameHunks = try? storeRepository.blame(withFile: filename, options: nil).hunks else {
@ -374,7 +373,7 @@ public class PasswordStore {
}
private func gitAdd(path: String) throws {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
try storeRepository.index().addFile(path)
@ -382,7 +381,7 @@ public class PasswordStore {
}
private func gitRm(path: String) throws {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
let url = storeURL.appendingPathComponent(path)
@ -417,7 +416,7 @@ public class PasswordStore {
}
private func gitCommit(message: String) throws -> GTCommit? {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
let newTree = try storeRepository.index().writeTree()
@ -428,12 +427,11 @@ public class PasswordStore {
guard let signature = gitSignatureForNow else {
throw AppError.gitCreateSignature
}
let commit = try storeRepository.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
return commit
return try storeRepository.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
}
private func getLocalBranch(withName branchName: String) throws -> GTBranch? {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
let reference = GTBranch.localNamePrefix().appending(branchName)
@ -445,7 +443,7 @@ public class PasswordStore {
options: [String: Any],
transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _, _, _ in }
) throws {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
if let branch = try getLocalBranch(withName: Defaults.gitBranchName) {
@ -588,7 +586,7 @@ public class PasswordStore {
}
public func updateImage(passwordEntity: PasswordEntity, image: Data?) {
guard let image = image else {
guard let image else {
return
}
let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
@ -638,7 +636,7 @@ public class PasswordStore {
// return the number of discarded commits
public func reset() throws -> Int {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
// get a list of local commits
@ -662,7 +660,7 @@ public class PasswordStore {
}
private func getLocalCommits() throws -> [GTCommit] {
guard let storeRepository = storeRepository else {
guard let storeRepository else {
throw AppError.repositoryNotSet
}
// get the remote branch

View file

@ -24,7 +24,7 @@ public extension AlertPresenting where Self: UIViewController {
)
}
// swiftlint:disable function_default_parameter_at_end
// swiftlint:disable:next function_default_parameter_at_end
func presentFailureAlert(title: String? = nil, message: String, action: AlertAction? = nil) {
let title = title ?? "Error"
presentAlert(

View file

@ -59,7 +59,7 @@ class GitCredentialTest: XCTestCase {
func testPasswordCredentialProvider() {
let password = GitCredential.from(authenticationMethod: .password, userName: "user", keyStore: keyStore)
let expectation = self.expectation(description: "Password is requested.")
let expectation = expectation(description: "Password is requested.")
expectation.assertForOverFulfill = true
expectation.expectedFulfillmentCount = 3
let options = password.getCredentialOptions { _, _ in

View file

@ -1,6 +1,6 @@
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin${PATH+:$PATH}"
SWIFTLINT_VERSION="0.50.*"
SWIFTLINT_VERSION="0.51.*"
if [[ "${CI}" == "true" ]]; then
echo "Running in a Continuous Integration environment. Linting is skipped."