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:
parent
a22e872a8c
commit
d9bd0f3014
24 changed files with 90 additions and 272 deletions
|
|
@ -1 +1 @@
|
||||||
5.3.1
|
5.8
|
||||||
|
|
|
||||||
257
.swiftlint.yml
257
.swiftlint.yml
|
|
@ -10,219 +10,50 @@ excluded:
|
||||||
|
|
||||||
## Active rules
|
## Active rules
|
||||||
|
|
||||||
only_rules:
|
opt_in_rules:
|
||||||
- accessibility_label_for_image
|
- all
|
||||||
# - anonymous_argument_in_multiline_closure
|
|
||||||
- anyobject_protocol
|
disabled_rules:
|
||||||
- array_init
|
- anonymous_argument_in_multiline_closure
|
||||||
- attributes
|
- balanced_xctest_lifecycle
|
||||||
# - balanced_xctest_lifecycle
|
- discouraged_none_name
|
||||||
- block_based_kvo
|
- discouraged_object_literal
|
||||||
- capture_variable
|
- discouraged_optional_collection # Too many false positives in implementations of system protocols.
|
||||||
- class_delegate_protocol
|
- empty_count # Too many false positives for variables named 'count'.
|
||||||
- closing_brace
|
- explicit_acl
|
||||||
- closure_body_length
|
- explicit_enum_raw_value # Disabled in favor of 'redundant_string_enum_value'.
|
||||||
- closure_end_indentation
|
- explicit_top_level_acl
|
||||||
- closure_parameter_position
|
- explicit_type_interface
|
||||||
- closure_spacing
|
- extension_access_modifier
|
||||||
- collection_alignment
|
- file_header
|
||||||
- colon
|
- file_length
|
||||||
- comma
|
- file_name
|
||||||
- comma_inheritance
|
- file_types_order
|
||||||
- comment_spacing
|
- force_cast
|
||||||
- compiler_protocol_init
|
- force_try
|
||||||
- computed_accessors_order
|
- force_unwrapping
|
||||||
- conditional_returns_on_newline
|
- function_body_length
|
||||||
- contains_over_filter_count
|
- implicitly_unwrapped_optional
|
||||||
- contains_over_filter_is_empty
|
- indentation_width
|
||||||
- contains_over_first_not_nil
|
- legacy_objc_type
|
||||||
- contains_over_range_nil_comparison
|
- line_length
|
||||||
- control_statement
|
- missing_docs
|
||||||
- convenience_type
|
- no_extension_access_modifier
|
||||||
- custom_rules
|
- no_grouping_extension
|
||||||
- cyclomatic_complexity
|
- no_magic_numbers # Causes a lot of violations in tests.
|
||||||
- deployment_target
|
- number_separator # Contradicts with SwiftFormat rule 'decimalgrouping'. There are not many numbers anyway in the source code.
|
||||||
- discarded_notification_center_observer
|
- prefer_nimble
|
||||||
- discouraged_assert
|
- prefixed_toplevel_constant # Violations are mostly in test code.
|
||||||
- discouraged_direct_init
|
- private_outlet
|
||||||
# - discouraged_none_name
|
- prohibited_interface_builder
|
||||||
# - discouraged_object_literal
|
- prohibited_super_call
|
||||||
- discouraged_optional_boolean
|
- required_deinit
|
||||||
# - discouraged_optional_collection # Too many false positives in implementations of system protocols.
|
- self_binding
|
||||||
- duplicated_key_in_dictionary_literal
|
- sorted_imports # Managed by SwiftFormat.
|
||||||
- duplicate_enum_cases
|
- type_body_length
|
||||||
- duplicate_imports
|
- type_contents_order
|
||||||
- dynamic_inline
|
- unowned_variable_capture
|
||||||
- empty_collection_literal
|
- vertical_whitespace_between_cases # Additional whitespace not needed because of visible indentation.
|
||||||
# - 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
|
|
||||||
|
|
||||||
## Configuration for specific rules
|
## Configuration for specific rules
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
lazy var passcodeLockPresenter: PasscodeLockPresenter = {
|
lazy var passcodeLockPresenter: PasscodeLockPresenter = .init(mainWindow: self.window)
|
||||||
let presenter = PasscodeLockPresenter(mainWindow: self.window)
|
|
||||||
return presenter
|
|
||||||
}()
|
|
||||||
|
|
||||||
func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
// Override point for customization after application launch.
|
// Override point for customization after application launch.
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,7 @@ class AboutRepositoryTableViewController: BasicStaticTableViewController {
|
||||||
private static let VALUE_NOT_AVAILABLE = "ValueNotAvailable".localize()
|
private static let VALUE_NOT_AVAILABLE = "ValueNotAvailable".localize()
|
||||||
|
|
||||||
private var needRefresh = false
|
private var needRefresh = false
|
||||||
private var indicator: UIActivityIndicatorView = {
|
private var indicator: UIActivityIndicatorView = .init(style: .medium)
|
||||||
let indicator = UIActivityIndicatorView(style: .medium)
|
|
||||||
return indicator
|
|
||||||
}()
|
|
||||||
|
|
||||||
private let passwordStore = PasswordStore.shared
|
private let passwordStore = PasswordStore.shared
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class AdvancedSettingsTableViewController: UITableViewController {
|
||||||
present(alert, animated: true, completion: nil)
|
present(alert, animated: true, completion: nil)
|
||||||
} else if tableView.cellForRow(at: indexPath) == clearSuggestionsTableViewCell {
|
} else if tableView.cellForRow(at: indexPath) == clearSuggestionsTableViewCell {
|
||||||
ASCredentialIdentityStore.shared.removeAllCredentialIdentities { _, error in
|
ASCredentialIdentityStore.shared.removeAllCredentialIdentities { _, error in
|
||||||
if let error = error {
|
if let error {
|
||||||
SVProgressHUD.showError(withStatus: "FailedToClearQuickTypeSuggestions".localize(error))
|
SVProgressHUD.showError(withStatus: "FailedToClearQuickTypeSuggestions".localize(error))
|
||||||
SVProgressHUD.dismiss(withDelay: 1)
|
SVProgressHUD.dismiss(withDelay: 1)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -83,10 +83,10 @@ extension PGPKeyFileImportTableViewController: PGPKeyImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importKeys() throws {
|
func importKeys() throws {
|
||||||
if let publicKey = publicKey {
|
if let publicKey {
|
||||||
try KeyFileManager.PublicPGP.importKey(from: publicKey)
|
try KeyFileManager.PublicPGP.importKey(from: publicKey)
|
||||||
}
|
}
|
||||||
if let privateKey = privateKey {
|
if let privateKey {
|
||||||
try KeyFileManager.PrivatePGP.importKey(from: privateKey)
|
try KeyFileManager.PrivatePGP.importKey(from: privateKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,12 @@ extension PGPKeyURLImportTableViewController: PGPKeyImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importKeys() throws {
|
func importKeys() throws {
|
||||||
if let pgpPrivateKeyURL = pgpPrivateKeyURL {
|
if let pgpPrivateKeyURL {
|
||||||
Defaults.pgpPrivateKeyURL = pgpPrivateKeyURL
|
Defaults.pgpPrivateKeyURL = pgpPrivateKeyURL
|
||||||
try KeyFileManager.PrivatePGP.importKey(from: pgpPrivateKeyURL)
|
try KeyFileManager.PrivatePGP.importKey(from: pgpPrivateKeyURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let pgpPublicKeyURL = pgpPublicKeyURL {
|
if let pgpPublicKeyURL {
|
||||||
Defaults.pgpPublicKeyURL = pgpPublicKeyURL
|
Defaults.pgpPublicKeyURL = pgpPublicKeyURL
|
||||||
try KeyFileManager.PublicPGP.importKey(from: pgpPublicKeyURL)
|
try KeyFileManager.PublicPGP.importKey(from: pgpPublicKeyURL)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
// preserve path so it can be reloaded even if the passwordEntity is deleted during the update process
|
||||||
private var passwordPath: String?
|
private var passwordPath: String?
|
||||||
|
|
||||||
private lazy var editUIBarButtonItem: UIBarButtonItem = {
|
private lazy var editUIBarButtonItem: UIBarButtonItem = .init(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit))
|
||||||
let uiBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit))
|
|
||||||
return uiBarButtonItem
|
|
||||||
}()
|
|
||||||
|
|
||||||
private struct TableSection {
|
private struct TableSection {
|
||||||
var type: PasswordDetailTableViewControllerSectionType
|
var type: PasswordDetailTableViewControllerSectionType
|
||||||
|
|
@ -112,7 +109,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
||||||
}
|
}
|
||||||
|
|
||||||
private func decryptThenShowPasswordLocalKey(keyID: String? = nil) {
|
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: {
|
Utils.alert(title: "CannotShowPassword".localize(), message: "PasswordDoesNotExist".localize(), controller: self, completion: {
|
||||||
self.navigationController!.popViewController(animated: true)
|
self.navigationController!.popViewController(animated: true)
|
||||||
})
|
})
|
||||||
|
|
@ -259,7 +256,7 @@ class PasswordDetailTableViewController: UITableViewController, UIGestureRecogni
|
||||||
|
|
||||||
// main section
|
// main section
|
||||||
section = TableSection(type: .main)
|
section = TableSection(type: .main)
|
||||||
let password = self.password!
|
let password = password!
|
||||||
if let username = password.username {
|
if let username = password.username {
|
||||||
section.item.append(Constants.USERNAME_KEYWORD => username)
|
section.item.append(Constants.USERNAME_KEYWORD => username)
|
||||||
}
|
}
|
||||||
|
|
@ -607,7 +604,7 @@ extension PasswordDetailTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func decryptThenShowPasswordYubiKey() {
|
private func decryptThenShowPasswordYubiKey() {
|
||||||
guard let passwordEntity = passwordEntity else {
|
guard let passwordEntity else {
|
||||||
handleError(error: AppError.other(message: "PasswordDoesNotExist"))
|
handleError(error: AppError.other(message: "PasswordDoesNotExist"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ class PasswordNavigationViewController: UIViewController {
|
||||||
if gesture.state == UIGestureRecognizer.State.began {
|
if gesture.state == UIGestureRecognizer.State.began {
|
||||||
let touchPoint = gesture.location(in: tableView)
|
let touchPoint = gesture.location(in: tableView)
|
||||||
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
|
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
|
||||||
guard let dataSource = dataSource else {
|
guard let dataSource else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let passwordTableEntry = dataSource.getPasswordTableEntry(at: indexPath)
|
let passwordTableEntry = dataSource.getPasswordTableEntry(at: indexPath)
|
||||||
|
|
@ -283,7 +283,7 @@ class PasswordNavigationViewController: UIViewController {
|
||||||
extension PasswordNavigationViewController: UITableViewDelegate {
|
extension PasswordNavigationViewController: UITableViewDelegate {
|
||||||
func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
|
func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
tableView.deselectRow(at: indexPath, animated: true)
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
guard let dataSource = dataSource else {
|
guard let dataSource else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let entry = dataSource.getPasswordTableEntry(at: indexPath)
|
let entry = dataSource.getPasswordTableEntry(at: indexPath)
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ class QRScannerController: UIViewController, AVCaptureMetadataOutputObjectsDeleg
|
||||||
// Initialize QR Code Frame to highlight the QR code
|
// Initialize QR Code Frame to highlight the QR code
|
||||||
qrCodeFrameView = UIView()
|
qrCodeFrameView = UIView()
|
||||||
|
|
||||||
if let qrCodeFrameView = qrCodeFrameView {
|
if let qrCodeFrameView {
|
||||||
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
|
qrCodeFrameView.layer.borderColor = UIColor.green.cgColor
|
||||||
qrCodeFrameView.layer.borderWidth = 2
|
qrCodeFrameView.layer.borderWidth = 2
|
||||||
view.addSubview(qrCodeFrameView)
|
view.addSubview(qrCodeFrameView)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ extension SSHKeyFileImportTableViewController: KeyImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func importKeys() throws {
|
func importKeys() throws {
|
||||||
guard let privateKey = privateKey else {
|
guard let privateKey else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try KeyFileManager.PrivateSSH.importKey(from: privateKey)
|
try KeyFileManager.PrivateSSH.importKey(from: privateKey)
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ class SettingsTableViewController: UITableViewController, UITabBarControllerDele
|
||||||
@objc
|
@objc
|
||||||
func alertTextFieldDidChange(_ sender: UITextField) {
|
func alertTextFieldDidChange(_ sender: UITextField) {
|
||||||
// check whether we should enable the Save button in setPasscodeLockAlert
|
// check whether we should enable the Save button in setPasscodeLockAlert
|
||||||
if let setPasscodeLockAlert = setPasscodeLockAlert,
|
if let setPasscodeLockAlert,
|
||||||
let setPasscodeLockAlertTextFields0 = setPasscodeLockAlert.textFields?[0],
|
let setPasscodeLockAlertTextFields0 = setPasscodeLockAlert.textFields?[0],
|
||||||
let setPasscodeLockAlertTextFields1 = setPasscodeLockAlert.textFields?[1] {
|
let setPasscodeLockAlertTextFields1 = setPasscodeLockAlert.textFields?[1] {
|
||||||
if sender == setPasscodeLockAlertTextFields0 || sender == setPasscodeLockAlertTextFields1 {
|
if sender == setPasscodeLockAlertTextFields0 || sender == setPasscodeLockAlertTextFields1 {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class UICodeHighlightingLabel: UILocalizedLabel {
|
||||||
|
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
guard let text = text else {
|
guard let text else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
attributedText = formatCode(in: text)
|
attributedText = formatCode(in: text)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ open class PasscodeLockViewController: UIViewController, UITextFieldDelegate {
|
||||||
|
|
||||||
override open func viewDidAppear(_ animated: Bool) {
|
override open func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
if let biometryAuthButton = biometryAuthButton {
|
if let biometryAuthButton {
|
||||||
bioButtonPressedAction(biometryAuthButton)
|
bioButtonPressedAction(biometryAuthButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ struct GopenPGPInterface: PGPInterface {
|
||||||
|
|
||||||
func decrypt(encryptedData: Data, keyID: String?, passphrase: String) throws -> Data? {
|
func decrypt(encryptedData: Data, keyID: String?, passphrase: String) throws -> Data? {
|
||||||
let key: CryptoKey? = {
|
let key: CryptoKey? = {
|
||||||
if let keyID = keyID {
|
if let keyID {
|
||||||
return privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
|
return privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
|
||||||
}
|
}
|
||||||
return privateKeys.first?.value
|
return privateKeys.first?.value
|
||||||
|
|
@ -109,7 +109,7 @@ struct GopenPGPInterface: PGPInterface {
|
||||||
|
|
||||||
func encrypt(plainData: Data, keyID: String?) throws -> Data {
|
func encrypt(plainData: Data, keyID: String?) throws -> Data {
|
||||||
let key: CryptoKey? = {
|
let key: CryptoKey? = {
|
||||||
if let keyID = keyID {
|
if let keyID {
|
||||||
return publicKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
|
return publicKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) })?.value
|
||||||
}
|
}
|
||||||
return publicKeys.first?.value
|
return publicKeys.first?.value
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public class PGPAgent {
|
||||||
public func decrypt(encryptedData: Data, keyID: String, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Data? {
|
public func decrypt(encryptedData: Data, keyID: String, requestPGPKeyPassphrase: @escaping (String) -> String) throws -> Data? {
|
||||||
// Init keys.
|
// Init keys.
|
||||||
try checkAndInit()
|
try checkAndInit()
|
||||||
guard let pgpInterface = pgpInterface else {
|
guard let pgpInterface else {
|
||||||
throw AppError.decryption
|
throw AppError.decryption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ public class PGPAgent {
|
||||||
|
|
||||||
public func encrypt(plainData: Data, keyID: String) throws -> Data {
|
public func encrypt(plainData: Data, keyID: String) throws -> Data {
|
||||||
try checkAndInit()
|
try checkAndInit()
|
||||||
guard let pgpInterface = pgpInterface else {
|
guard let pgpInterface else {
|
||||||
throw AppError.encryption
|
throw AppError.encryption
|
||||||
}
|
}
|
||||||
var keyID = keyID
|
var keyID = keyID
|
||||||
|
|
@ -120,7 +120,7 @@ public class PGPAgent {
|
||||||
|
|
||||||
public func encrypt(plainData: Data) throws -> Data {
|
public func encrypt(plainData: Data) throws -> Data {
|
||||||
try checkAndInit()
|
try checkAndInit()
|
||||||
guard let pgpInterface = pgpInterface else {
|
guard let pgpInterface else {
|
||||||
throw AppError.encryption
|
throw AppError.encryption
|
||||||
}
|
}
|
||||||
return try pgpInterface.encrypt(plainData: plainData, keyID: nil)
|
return try pgpInterface.encrypt(plainData: plainData, keyID: nil)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ public extension FileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to enumerate all directory contents, including subdirectories.
|
// We have to enumerate all directory contents, including subdirectories.
|
||||||
let enumerator = self.enumerator(
|
let enumerator = enumerator(
|
||||||
at: directoryURL,
|
at: directoryURL,
|
||||||
includingPropertiesForKeys: prefetchedProperties,
|
includingPropertiesForKeys: prefetchedProperties,
|
||||||
options: Self.DirectoryEnumerationOptions(),
|
options: Self.DirectoryEnumerationOptions(),
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ import YubiKit
|
||||||
|
|
||||||
public enum YubiKeyAPDU {
|
public enum YubiKeyAPDU {
|
||||||
public static func selectOpenPGPApplication() -> YKFSelectApplicationAPDU {
|
public static func selectOpenPGPApplication() -> YKFSelectApplicationAPDU {
|
||||||
let selectOpenPGPAPDU = YKFSelectApplicationAPDU(data: Data([0xD2, 0x76, 0x00, 0x01, 0x24, 0x01]))!
|
YKFSelectApplicationAPDU(data: Data([0xD2, 0x76, 0x00, 0x01, 0x24, 0x01]))!
|
||||||
return selectOpenPGPAPDU
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func verify(password: String) -> YKFAPDU {
|
public static func verify(password: String) -> YKFAPDU {
|
||||||
|
|
@ -22,8 +21,7 @@ public enum YubiKeyAPDU {
|
||||||
apdu += [0x82] // P2: PW1
|
apdu += [0x82] // P2: PW1
|
||||||
apdu += withUnsafeBytes(of: UInt8(pw1.count).bigEndian, Array.init)
|
apdu += withUnsafeBytes(of: UInt8(pw1.count).bigEndian, Array.init)
|
||||||
apdu += pw1
|
apdu += pw1
|
||||||
let verifyApdu = YKFAPDU(data: Data(apdu))!
|
return YKFAPDU(data: Data(apdu))!
|
||||||
return verifyApdu
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func decipherExtended(data: Data) -> [YKFAPDU] {
|
public static func decipherExtended(data: Data) -> [YKFAPDU] {
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ public class Password {
|
||||||
|
|
||||||
private func checkPasswordForOtpToken() {
|
private func checkPasswordForOtpToken() {
|
||||||
let (key, value) = Parser.getKeyValuePair(from: password)
|
let (key, value) = Parser.getKeyValuePair(from: password)
|
||||||
if let key = key, Constants.isOtpKeyword(key) {
|
if let key, Constants.isOtpKeyword(key) {
|
||||||
firstLineIsOTPField = true
|
firstLineIsOTPField = true
|
||||||
additions.append(key => value)
|
additions.append(key => value)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import SwiftyUserDefaults
|
||||||
|
|
||||||
public extension PasswordEntity {
|
public extension PasswordEntity {
|
||||||
var nameWithCategory: String {
|
var nameWithCategory: String {
|
||||||
if let path = path {
|
if let path {
|
||||||
if path.hasSuffix(".gpg") {
|
if path.hasSuffix(".gpg") {
|
||||||
return String(path.prefix(upTo: path.index(path.endIndex, offsetBy: -4)))
|
return String(path.prefix(upTo: path.index(path.endIndex, offsetBy: -4)))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkoutAndChangeBranch(withName localBranchName: String, progressBlock: @escaping (String, UInt, UInt) -> Void) throws {
|
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
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
let remoteBranchName = "origin/\(localBranchName)"
|
let remoteBranchName = "origin/\(localBranchName)"
|
||||||
|
|
@ -218,7 +218,7 @@ public class PasswordStore {
|
||||||
options: [String: Any],
|
options: [String: Any],
|
||||||
progressBlock: @escaping (UnsafePointer<git_transfer_progress>, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _ in }
|
progressBlock: @escaping (UnsafePointer<git_transfer_progress>, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _ in }
|
||||||
) throws {
|
) throws {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
let remote = try GTRemote(name: "origin", in: storeRepository)
|
let remote = try GTRemote(name: "origin", in: storeRepository)
|
||||||
|
|
@ -284,7 +284,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getRecentCommits(count: Int) throws -> [GTCommit] {
|
public func getRecentCommits(count: Int) throws -> [GTCommit] {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
var commits = [GTCommit]()
|
var commits = [GTCommit]()
|
||||||
|
|
@ -328,8 +328,7 @@ public class PasswordStore {
|
||||||
let passwordEntityFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PasswordEntity")
|
let passwordEntityFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PasswordEntity")
|
||||||
passwordEntityFetchRequest.predicate = NSPredicate(format: "synced = %i", 0)
|
passwordEntityFetchRequest.predicate = NSPredicate(format: "synced = %i", 0)
|
||||||
do {
|
do {
|
||||||
let passwordEntities = try context.fetch(passwordEntityFetchRequest) as! [PasswordEntity]
|
return try context.fetch(passwordEntityFetchRequest) as! [PasswordEntity]
|
||||||
return passwordEntities
|
|
||||||
} catch {
|
} catch {
|
||||||
fatalError("FailedToFetchPasswords".localize(error))
|
fatalError("FailedToFetchPasswords".localize(error))
|
||||||
}
|
}
|
||||||
|
|
@ -357,7 +356,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getLatestUpdateInfo(filename: String) -> String {
|
public func getLatestUpdateInfo(filename: String) -> String {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
return "Unknown".localize()
|
return "Unknown".localize()
|
||||||
}
|
}
|
||||||
guard let blameHunks = try? storeRepository.blame(withFile: filename, options: nil).hunks else {
|
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 {
|
private func gitAdd(path: String) throws {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
try storeRepository.index().addFile(path)
|
try storeRepository.index().addFile(path)
|
||||||
|
|
@ -382,7 +381,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gitRm(path: String) throws {
|
private func gitRm(path: String) throws {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
let url = storeURL.appendingPathComponent(path)
|
let url = storeURL.appendingPathComponent(path)
|
||||||
|
|
@ -417,7 +416,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gitCommit(message: String) throws -> GTCommit? {
|
private func gitCommit(message: String) throws -> GTCommit? {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
let newTree = try storeRepository.index().writeTree()
|
let newTree = try storeRepository.index().writeTree()
|
||||||
|
|
@ -428,12 +427,11 @@ public class PasswordStore {
|
||||||
guard let signature = gitSignatureForNow else {
|
guard let signature = gitSignatureForNow else {
|
||||||
throw AppError.gitCreateSignature
|
throw AppError.gitCreateSignature
|
||||||
}
|
}
|
||||||
let commit = try storeRepository.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
return try storeRepository.createCommit(with: newTree, message: message, author: signature, committer: signature, parents: [parent], updatingReferenceNamed: headReference.name)
|
||||||
return commit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getLocalBranch(withName branchName: String) throws -> GTBranch? {
|
private func getLocalBranch(withName branchName: String) throws -> GTBranch? {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
let reference = GTBranch.localNamePrefix().appending(branchName)
|
let reference = GTBranch.localNamePrefix().appending(branchName)
|
||||||
|
|
@ -445,7 +443,7 @@ public class PasswordStore {
|
||||||
options: [String: Any],
|
options: [String: Any],
|
||||||
transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _, _, _ in }
|
transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _, _, _ in }
|
||||||
) throws {
|
) throws {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
if let branch = try getLocalBranch(withName: Defaults.gitBranchName) {
|
if let branch = try getLocalBranch(withName: Defaults.gitBranchName) {
|
||||||
|
|
@ -588,7 +586,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func updateImage(passwordEntity: PasswordEntity, image: Data?) {
|
public func updateImage(passwordEntity: PasswordEntity, image: Data?) {
|
||||||
guard let image = image else {
|
guard let image else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
|
let privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
|
||||||
|
|
@ -638,7 +636,7 @@ public class PasswordStore {
|
||||||
|
|
||||||
// return the number of discarded commits
|
// return the number of discarded commits
|
||||||
public func reset() throws -> Int {
|
public func reset() throws -> Int {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
// get a list of local commits
|
// get a list of local commits
|
||||||
|
|
@ -662,7 +660,7 @@ public class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getLocalCommits() throws -> [GTCommit] {
|
private func getLocalCommits() throws -> [GTCommit] {
|
||||||
guard let storeRepository = storeRepository else {
|
guard let storeRepository else {
|
||||||
throw AppError.repositoryNotSet
|
throw AppError.repositoryNotSet
|
||||||
}
|
}
|
||||||
// get the remote branch
|
// get the remote branch
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func presentFailureAlert(title: String? = nil, message: String, action: AlertAction? = nil) {
|
||||||
let title = title ?? "Error"
|
let title = title ?? "Error"
|
||||||
presentAlert(
|
presentAlert(
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ class GitCredentialTest: XCTestCase {
|
||||||
|
|
||||||
func testPasswordCredentialProvider() {
|
func testPasswordCredentialProvider() {
|
||||||
let password = GitCredential.from(authenticationMethod: .password, userName: "user", keyStore: keyStore)
|
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.assertForOverFulfill = true
|
||||||
expectation.expectedFulfillmentCount = 3
|
expectation.expectedFulfillmentCount = 3
|
||||||
let options = password.getCredentialOptions { _, _ in
|
let options = password.getCredentialOptions { _, _ in
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin${PATH+:$PATH}"
|
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin${PATH+:$PATH}"
|
||||||
|
|
||||||
SWIFTLINT_VERSION="0.50.*"
|
SWIFTLINT_VERSION="0.51.*"
|
||||||
|
|
||||||
if [[ "${CI}" == "true" ]]; then
|
if [[ "${CI}" == "true" ]]; then
|
||||||
echo "Running in a Continuous Integration environment. Linting is skipped."
|
echo "Running in a Continuous Integration environment. Linting is skipped."
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue