Rely on SPM plugins to consume SwiftLint and SwiftFormat

Use their latest releases and fix some violations and issues.

# Conflicts:
#	.github/workflows/linting.yml
#	.github/workflows/testing.yml
This commit is contained in:
Danny Mösch 2024-11-24 13:14:38 +01:00
parent 358908f161
commit 1bdf9d684b
40 changed files with 126 additions and 186 deletions

View file

@ -21,9 +21,8 @@ jobs:
- name: Installing packages - name: Installing packages
run: | run: |
brew update brew update
brew install carthage swiftformat brew install carthage
brew install go || brew link --overwrite go brew install go || brew link --overwrite go
brew install swiftlint || brew link --overwrite swiftlint
gem install bundler gem install bundler
- uses: actions/cache@v3 - uses: actions/cache@v3
id: carthage-cache id: carthage-cache

View file

@ -1,45 +0,0 @@
name: Linting
on: pull_request
jobs:
swiftformat:
runs-on: macos-12
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
bundler-cache: true
- name: Installing packages
run: |
brew update
if brew ls --version swiftformat > /dev/null; then
brew upgrade swiftformat
else
brew install swiftformat
fi
- name: Formatting code
run: |
swiftformat --lint .
swiftlint:
runs-on: macos-12
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
bundler-cache: true
- name: Installing packages
run: |
brew update
if brew ls --version swiftlint > /dev/null; then
brew upgrade swiftlint
else
# For some reason the SwiftLint binary is kept at its location after shutdown.
brew install swiftlint || brew link --overwrite swiftlint
fi
- name: Linting code
run: |
swiftlint --strict

View file

@ -14,9 +14,8 @@ jobs:
- name: Installing packages - name: Installing packages
run: | run: |
brew update brew update
brew install carthage swiftformat brew install carthage
brew install go@1.20 || brew link --overwrite go brew install go || brew link --overwrite go
brew install swiftlint || brew link --overwrite swiftlint
gem install bundler gem install bundler
- uses: actions/cache@v3 - uses: actions/cache@v3
id: carthage-cache id: carthage-cache

View file

@ -19,6 +19,7 @@
blankLinesAroundMark, \ blankLinesAroundMark, \
blankLinesAtEndOfScope, \ blankLinesAtEndOfScope, \
blankLinesAtStartOfScope, \ blankLinesAtStartOfScope, \
blankLinesBetweenChainedFunctions, \
# blankLinesBetweenImports, \ # blankLinesBetweenImports, \
blankLinesBetweenScopes, \ blankLinesBetweenScopes, \
blockComments, \ blockComments, \
@ -32,6 +33,7 @@
extensionAccessControl, \ extensionAccessControl, \
fileHeader, \ fileHeader, \
# genericExtensions, \ # genericExtensions, \
headerFileName, \
hoistPatternLet, \ hoistPatternLet, \
indent, \ indent, \
initCoderUnavailable, \ initCoderUnavailable, \
@ -41,9 +43,11 @@
linebreaks, \ linebreaks, \
modifierOrder, \ modifierOrder, \
# markTypes, \ # markTypes, \
noExplicitOwnership, \
numberFormatting, \ numberFormatting, \
# opaqueGenericParameters, \ # opaqueGenericParameters, \
# organizeDeclarations, \ # organizeDeclarations, \
# preferForLoop, \
preferKeyPath, \ preferKeyPath, \
redundantBackticks, \ redundantBackticks, \
redundantBreak, \ redundantBreak, \
@ -52,6 +56,7 @@
redundantFileprivate, \ redundantFileprivate, \
redundantGet, \ redundantGet, \
redundantInit, \ redundantInit, \
redundantInternal, \
redundantLet, \ redundantLet, \
redundantLetError, \ redundantLetError, \
redundantNilInit, \ redundantNilInit, \
@ -62,11 +67,13 @@
redundantRawValues, \ redundantRawValues, \
redundantReturn, \ redundantReturn, \
redundantSelf, \ redundantSelf, \
redundantStaticSelf, \
redundantType, \ redundantType, \
redundantVoidReturnType, \ redundantVoidReturnType, \
semicolons, \ semicolons, \
sortedImports, \ sortImports, \
sortedSwitchCases, \ sortSwitchCases, \
sortTypealiases, \
spaceAroundBraces, \ spaceAroundBraces, \
spaceAroundBrackets, \ spaceAroundBrackets, \
spaceAroundComments, \ spaceAroundComments, \
@ -93,6 +100,8 @@
wrapAttributes, \ wrapAttributes, \
wrapConditionalBodies, \ wrapConditionalBodies, \
# wrapEnumCases, \ # wrapEnumCases, \
wrapLoopBodies, \
wrapMultilineConditionalAssignment, \
# wrapMultilineStatementBraces, \ # wrapMultilineStatementBraces, \
wrapSingleLineComments, \ wrapSingleLineComments, \
# wrapSwitchCases, \ # wrapSwitchCases, \

View file

@ -7,6 +7,7 @@ excluded:
- go - go
- Pods - Pods
- vendor - vendor
- xcode
## Active rules ## Active rules
@ -15,8 +16,8 @@ opt_in_rules:
disabled_rules: disabled_rules:
- anonymous_argument_in_multiline_closure - anonymous_argument_in_multiline_closure
- anyobject_protocol # Deprecated.
- balanced_xctest_lifecycle - balanced_xctest_lifecycle
- contrasted_opening_brace
- discouraged_none_name - discouraged_none_name
- discouraged_object_literal - discouraged_object_literal
- discouraged_optional_collection # Too many false positives in implementations of system protocols. - discouraged_optional_collection # Too many false positives in implementations of system protocols.
@ -40,10 +41,12 @@ disabled_rules:
- legacy_objc_type - legacy_objc_type
- line_length - line_length
- missing_docs - missing_docs
- no_empty_block # To be fixed later.
- no_extension_access_modifier - no_extension_access_modifier
- no_grouping_extension - no_grouping_extension
- no_magic_numbers # Causes a lot of violations in tests. - 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. - number_separator # Contradicts with SwiftFormat rule 'decimalgrouping'. There are not many numbers anyway in the source code.
- one_declaration_per_file
- prefer_nimble - prefer_nimble
- prefixed_toplevel_constant # Violations are mostly in test code. - prefixed_toplevel_constant # Violations are mostly in test code.
- private_outlet - private_outlet
@ -66,6 +69,8 @@ attributes:
closure_body_length: closure_body_length:
warning: 40 warning: 40
error: 60 error: 60
explicit_init:
include_bare_init: true
identifier_name: identifier_name:
excluded: ["id", "to", "Defaults"] excluded: ["id", "to", "Defaults"]
allowed_symbols: ["_"] allowed_symbols: ["_"]
@ -80,4 +85,3 @@ trailing_comma:
xct_specific_matcher: xct_specific_matcher:
matchers: matchers:
- two-argument-asserts - two-argument-asserts

View file

@ -47,7 +47,7 @@ For more, please read the [wiki page](https://github.com/mssun/passforios/wiki).
## Building Pass for iOS ## Building Pass for iOS
1. Install Carthage, Go, SwiftLint, and SwiftFormat: `brew install carthage go swiftlint swiftformat`. 1. Install Carthage and Go: `brew install carthage go`.
2. Install dependencies via Carthage. Therefore, execute `carthage bootstrap --platform iOS --use-xcframeworks` in the root directory of the project. 2. Install dependencies via Carthage. Therefore, execute `carthage bootstrap --platform iOS --use-xcframeworks` in the root directory of the project.
3. Run `./scripts/gopenpgp_build.sh` to build GopenPGP. 3. Run `./scripts/gopenpgp_build.sh` to build GopenPGP.
5. Open the `pass.xcodeproj` file in Xcode. 5. Open the `pass.xcodeproj` file in Xcode.

View file

@ -199,7 +199,7 @@
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914941E434301007FF592 /* LabelTableViewCell.swift */; }; DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914941E434301007FF592 /* LabelTableViewCell.swift */; };
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */; }; DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */; };
DC5F385B1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5F385A1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift */; }; DC5F385B1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5F385A1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift */; };
DC8963C01E38EEB900828B09 /* SSHKeyURLImportTableViewController..swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController..swift */; }; DC8963C01E38EEB900828B09 /* SSHKeyURLImportTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController.swift */; };
DC917BD71E2E8231000FDF54 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC917BD61E2E8231000FDF54 /* AppDelegate.swift */; }; DC917BD71E2E8231000FDF54 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC917BD61E2E8231000FDF54 /* AppDelegate.swift */; };
DC917BDC1E2E8231000FDF54 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC917BDA1E2E8231000FDF54 /* Main.storyboard */; }; DC917BDC1E2E8231000FDF54 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC917BDA1E2E8231000FDF54 /* Main.storyboard */; };
DC917BDE1E2E8231000FDF54 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC917BDD1E2E8231000FDF54 /* Assets.xcassets */; }; DC917BDE1E2E8231000FDF54 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC917BDD1E2E8231000FDF54 /* Assets.xcassets */; };
@ -496,7 +496,7 @@
DC4914941E434301007FF592 /* LabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelTableViewCell.swift; sourceTree = "<group>"; }; DC4914941E434301007FF592 /* LabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelTableViewCell.swift; sourceTree = "<group>"; };
DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordDetailTableViewController.swift; sourceTree = "<group>"; }; DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordDetailTableViewController.swift; sourceTree = "<group>"; };
DC5F385A1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PGPKeyArmorImportTableViewController.swift; sourceTree = "<group>"; }; DC5F385A1E56AADB00C69ACA /* PGPKeyArmorImportTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PGPKeyArmorImportTableViewController.swift; sourceTree = "<group>"; };
DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController..swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSHKeyURLImportTableViewController..swift; sourceTree = "<group>"; }; DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSHKeyURLImportTableViewController.swift; sourceTree = "<group>"; };
DC917BD31E2E8231000FDF54 /* Pass.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Pass.app; sourceTree = BUILT_PRODUCTS_DIR; }; DC917BD31E2E8231000FDF54 /* Pass.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Pass.app; sourceTree = BUILT_PRODUCTS_DIR; };
DC917BD61E2E8231000FDF54 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; DC917BD61E2E8231000FDF54 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DC917BDB1E2E8231000FDF54 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; DC917BDB1E2E8231000FDF54 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
@ -982,7 +982,7 @@
DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */, DC037CA91E4B8EAE00609409 /* SpecialThanksTableViewController.swift */,
DCC441531E916382008A90C4 /* SSHKeyArmorImportTableViewController.swift */, DCC441531E916382008A90C4 /* SSHKeyArmorImportTableViewController.swift */,
30650E7023F82AF8005CCD5E /* SSHKeyFileImportTableViewController.swift */, 30650E7023F82AF8005CCD5E /* SSHKeyFileImportTableViewController.swift */,
DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController..swift */, DC8963BF1E38EEB900828B09 /* SSHKeyURLImportTableViewController.swift */,
); );
path = Controllers; path = Controllers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1361,6 +1361,8 @@
9A1F47F826E5CF4B000C0E01 /* XCRemoteSwiftPackageReference "OneTimePassword" */, 9A1F47F826E5CF4B000C0E01 /* XCRemoteSwiftPackageReference "OneTimePassword" */,
30ED1775276F8842009BA876 /* XCRemoteSwiftPackageReference "objective-git-swift-package" */, 30ED1775276F8842009BA876 /* XCRemoteSwiftPackageReference "objective-git-swift-package" */,
9A2C7D802782CB2F00BD9AF3 /* XCRemoteSwiftPackageReference "yubikit-ios" */, 9A2C7D802782CB2F00BD9AF3 /* XCRemoteSwiftPackageReference "yubikit-ios" */,
307CA2312CF346D40099F6DE /* XCRemoteSwiftPackageReference "SwiftLintPlugins" */,
307CA2322CF348260099F6DE /* XCRemoteSwiftPackageReference "SwiftFormat" */,
); );
productRefGroup = DC917BD41E2E8231000FDF54 /* Products */; productRefGroup = DC917BD41E2E8231000FDF54 /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -1478,7 +1480,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = ". \"${SRCROOT}/scripts/swiftformat.sh\"\n"; shellScript = "SWIFT_PACKAGE_DIR=\"${BUILD_DIR%Build/*}SourcePackages/checkouts\"\nSWIFTFORMAT_CMD=\"$SWIFT_PACKAGE_DIR\"/SwiftFormat/CommandLineTool/swiftformat\n\nif [[ \"${CI}\" == \"true\" ]]; then\n echo \"Running in a Continuous Integration environment. Formatting is skipped.\"\n exit 0 \nfi\n\nif [[ \"${CONFIGURATION}\" == \"Release\" ]]; then\n echo \"Running during a release build. Formatting is skipped.\"\n exit 0\nfi\n\nif test -f \"$SWIFTFORMAT_CMD\" 2>&1\nthen\n \"$SWIFTFORMAT_CMD\" .\nelse\n echo \"warning: `swiftformat` command not found\"\nfi\n";
}; };
308800C124EB0D3600E87ED3 /* SwiftLint */ = { 308800C124EB0D3600E87ED3 /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@ -1497,7 +1499,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = ". \"${SRCROOT}/scripts/swiftlint.sh\"\n"; shellScript = "SWIFT_PACKAGE_DIR=\"${BUILD_DIR%Build/*}SourcePackages/artifacts\"\nSWIFTLINT_CMD=$(ls \"$SWIFT_PACKAGE_DIR\"/swiftlintplugins/SwiftLintBinary/SwiftLintBinary.artifactbundle/swiftlint-*/bin/swiftlint | head -n 1)\n\nSTRICT_OPT=\n\nif [[ \"${CI}\" == \"true\" ]]; then\n echo \"Running in a Continuous Integration environment. Linting is strictly.\"\n STRICT_OPT=--strict\nfi\n\nif [[ \"${CONFIGURATION}\" == \"Release\" ]]; then\n echo \"Running during a release build. Linting is skipped.\"\n exit 0\nfi\n\nif test -f \"$SWIFTLINT_CMD\" 2>&1\nthen\n \"$SWIFTLINT_CMD\" lint --fix\n \"$SWIFTLINT_CMD\" lint $STRICT_OPT\nelse\n echo \"warning: `swiftlint` command not found\"\nfi\n";
}; };
9A996C4726DDEAF100A4485D /* Remove SPM Duplicate Frameworks */ = { 9A996C4726DDEAF100A4485D /* Remove SPM Duplicate Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@ -1661,7 +1663,7 @@
DCC441541E916382008A90C4 /* SSHKeyArmorImportTableViewController.swift in Sources */, DCC441541E916382008A90C4 /* SSHKeyArmorImportTableViewController.swift in Sources */,
306D970E24091CDD006C0E2E /* SwitchTableViewCell.swift in Sources */, 306D970E24091CDD006C0E2E /* SwitchTableViewCell.swift in Sources */,
A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */, A2A61C201EEFABAD00CFE063 /* UtilsExtension.swift in Sources */,
DC8963C01E38EEB900828B09 /* SSHKeyURLImportTableViewController..swift in Sources */, DC8963C01E38EEB900828B09 /* SSHKeyURLImportTableViewController.swift in Sources */,
DC30F83829BED4E2001EB12B /* PasswordGeneratorUISwitch.swift in Sources */, DC30F83829BED4E2001EB12B /* PasswordGeneratorUISwitch.swift in Sources */,
9AFC87F025B514AD008D6060 /* PasswordDecryptor.swift in Sources */, 9AFC87F025B514AD008D6060 /* PasswordDecryptor.swift in Sources */,
3066AD6823EE0D6500F65535 /* PGPKeyImporter.swift in Sources */, 3066AD6823EE0D6500F65535 /* PGPKeyImporter.swift in Sources */,
@ -2846,6 +2848,22 @@
minimumVersion = 0.99.2; minimumVersion = 0.99.2;
}; };
}; };
30333B292CF922D9008A2EA2 /* XCRemoteSwiftPackageReference "SwiftLintPlugins" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SimplyDanny/SwiftLintPlugins.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.57.1;
};
};
307CA2322CF348260099F6DE /* XCRemoteSwiftPackageReference "SwiftFormat" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nicklockwood/SwiftFormat";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.55.2;
};
};
30A3000C26DA62F4002A734E /* XCRemoteSwiftPackageReference "Base32" */ = { 30A3000C26DA62F4002A734E /* XCRemoteSwiftPackageReference "Base32" */ = {
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mattrubin/Base32"; repositoryURL = "https://github.com/mattrubin/Base32";

View file

@ -1,4 +1,5 @@
{ {
"originHash" : "cfd99fa2de57765d4ea0531870a48806df8e3971c39177b2ec90b24da2c77efb",
"pins" : [ "pins" : [
{ {
"identity" : "base32", "identity" : "base32",
@ -53,6 +54,24 @@
"revision" : "8d59e4abba762d0f1e9aed161081f7b3fe21daa0" "revision" : "8d59e4abba762d0f1e9aed161081f7b3fe21daa0"
} }
}, },
{
"identity" : "swiftformat",
"kind" : "remoteSourceControl",
"location" : "https://github.com/nicklockwood/SwiftFormat",
"state" : {
"revision" : "eb55d16245567e99d18ea871a7609befc8210c46",
"version" : "0.55.2"
}
},
{
"identity" : "swiftlintplugins",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SimplyDanny/SwiftLintPlugins.git",
"state" : {
"revision" : "f9731bef175c3eea3a0ca960f1be78fcc2bc7853",
"version" : "0.57.1"
}
},
{ {
"identity" : "swiftyuserdefaults", "identity" : "swiftyuserdefaults",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
@ -72,5 +91,5 @@
} }
} }
], ],
"version" : 2 "version" : 3
} }

View file

@ -20,7 +20,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? var window: UIWindow?
lazy var passcodeLockPresenter: PasscodeLockPresenter = .init(mainWindow: self.window) lazy var passcodeLockPresenter = PasscodeLockPresenter(mainWindow: self.window)
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.

View file

@ -13,7 +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 = .init(style: .medium) private var indicator = UIActivityIndicatorView(style: .medium)
private let passwordStore = PasswordStore.shared private let passwordStore = PasswordStore.shared

View file

@ -38,11 +38,6 @@ class BasicStaticTableViewController: UITableViewController, MFMailComposeViewCo
tableData[section].count tableData[section].count
} }
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { override func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellData = tableData[indexPath.section][indexPath.row] let cellData = tableData[indexPath.section][indexPath.row]
let cellDataStyle = cellData[CellDataKey.style] as? CellDataStyle let cellDataStyle = cellData[CellDataKey.style] as? CellDataStyle

View file

@ -24,13 +24,13 @@ protocol KeyImporter {
extension KeyImporter { extension KeyImporter {
static var isCurrentKeySource: Bool { static var isCurrentKeySource: Bool {
Defaults.gitSSHKeySource == Self.keySource Defaults.gitSSHKeySource == keySource
} }
static var menuLabel: String { static var menuLabel: String {
if isCurrentKeySource { if isCurrentKeySource {
return "\(Self.label)" return "\(label)"
} }
return Self.label return label
} }
} }

View file

@ -16,6 +16,7 @@ class PGPKeyFileImportTableViewController: AutoCellHeightUITableViewController,
private var privateKey: String? private var privateKey: String?
private enum KeyType { case none, `private`, `public` } private enum KeyType { case none, `private`, `public` }
private var currentlyPicking = KeyType.none private var currentlyPicking = KeyType.none
@IBAction @IBAction

View file

@ -14,7 +14,7 @@ protocol PGPKeyImporter: KeyImporter {
extension PGPKeyImporter { extension PGPKeyImporter {
static var isCurrentKeySource: Bool { static var isCurrentKeySource: Bool {
Defaults.pgpKeySource == Self.keySource Defaults.pgpKeySource == keySource
} }
func doAfterImport() {} func doAfterImport() {}

View file

@ -30,7 +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 = .init(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit)) private lazy var editUIBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(pressEdit))
private struct TableSection { private struct TableSection {
var type: PasswordDetailTableViewControllerSectionType var type: PasswordDetailTableViewControllerSectionType

View file

@ -14,14 +14,4 @@ class PasswordDetailTitleTableViewCell: UITableViewCell {
@IBOutlet var passwordImageImageView: UIImageView! @IBOutlet var passwordImageImageView: UIImageView!
@IBOutlet var labelImageConstraint: NSLayoutConstraint! @IBOutlet var labelImageConstraint: NSLayoutConstraint!
@IBOutlet var labelCellConstraint: NSLayoutConstraint! @IBOutlet var labelCellConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
} }

View file

@ -35,39 +35,39 @@ extension SearchBarScope: DefaultsSerializable {}
extension PasswordGenerator: DefaultsSerializable {} extension PasswordGenerator: DefaultsSerializable {}
public extension DefaultsKeys { public extension DefaultsKeys {
var pgpKeySource: DefaultsKey<KeySource?> { .init("pgpKeySource") } var pgpKeySource: DefaultsKey<KeySource?> { DefaultsKey("pgpKeySource") }
var pgpPublicKeyURL: DefaultsKey<URL?> { .init("pgpPublicKeyURL") } var pgpPublicKeyURL: DefaultsKey<URL?> { DefaultsKey("pgpPublicKeyURL") }
var pgpPrivateKeyURL: DefaultsKey<URL?> { .init("pgpPrivateKeyURL") } var pgpPrivateKeyURL: DefaultsKey<URL?> { DefaultsKey("pgpPrivateKeyURL") }
var isYubiKeyEnabled: DefaultsKey<Bool> { .init("isYubiKeyEnabled", defaultValue: false) } var isYubiKeyEnabled: DefaultsKey<Bool> { DefaultsKey("isYubiKeyEnabled", defaultValue: false) }
// Keep them for legacy reasons. // Keep them for legacy reasons.
var pgpPublicKeyArmor: DefaultsKey<String?> { .init("pgpPublicKeyArmor") } var pgpPublicKeyArmor: DefaultsKey<String?> { DefaultsKey("pgpPublicKeyArmor") }
var pgpPrivateKeyArmor: DefaultsKey<String?> { .init("pgpPrivateKeyArmor") } var pgpPrivateKeyArmor: DefaultsKey<String?> { DefaultsKey("pgpPrivateKeyArmor") }
var gitSSHPrivateKeyArmor: DefaultsKey<String?> { .init("gitSSHPrivateKeyArmor") } var gitSSHPrivateKeyArmor: DefaultsKey<String?> { DefaultsKey("gitSSHPrivateKeyArmor") }
var passcodeKey: DefaultsKey<String?> { .init("passcodeKey") } var passcodeKey: DefaultsKey<String?> { DefaultsKey("passcodeKey") }
var gitURL: DefaultsKey<URL> { .init("gitURL", defaultValue: URL(string: "https://")!) } var gitURL: DefaultsKey<URL> { DefaultsKey("gitURL", defaultValue: URL(string: "https://")!) }
var gitAuthenticationMethod: DefaultsKey<GitAuthenticationMethod> { .init("gitAuthenticationMethod", defaultValue: GitAuthenticationMethod.password) } var gitAuthenticationMethod: DefaultsKey<GitAuthenticationMethod> { DefaultsKey("gitAuthenticationMethod", defaultValue: GitAuthenticationMethod.password) }
var gitUsername: DefaultsKey<String> { .init("gitUsername", defaultValue: "git") } var gitUsername: DefaultsKey<String> { DefaultsKey("gitUsername", defaultValue: "git") }
var gitBranchName: DefaultsKey<String> { .init("gitBranchName", defaultValue: "master") } var gitBranchName: DefaultsKey<String> { DefaultsKey("gitBranchName", defaultValue: "master") }
var gitSSHPrivateKeyURL: DefaultsKey<URL?> { .init("gitSSHPrivateKeyURL") } var gitSSHPrivateKeyURL: DefaultsKey<URL?> { DefaultsKey("gitSSHPrivateKeyURL") }
var gitSSHKeySource: DefaultsKey<KeySource?> { .init("gitSSHKeySource") } var gitSSHKeySource: DefaultsKey<KeySource?> { DefaultsKey("gitSSHKeySource") }
var gitSignatureName: DefaultsKey<String?> { .init("gitSignatureName") } var gitSignatureName: DefaultsKey<String?> { DefaultsKey("gitSignatureName") }
var gitSignatureEmail: DefaultsKey<String?> { .init("gitSignatureEmail") } var gitSignatureEmail: DefaultsKey<String?> { DefaultsKey("gitSignatureEmail") }
var lastSyncedTime: DefaultsKey<Date?> { .init("lastSyncedTime") } var lastSyncedTime: DefaultsKey<Date?> { DefaultsKey("lastSyncedTime") }
var isHideUnknownOn: DefaultsKey<Bool> { .init("isHideUnknownOn", defaultValue: false) } var isHideUnknownOn: DefaultsKey<Bool> { DefaultsKey("isHideUnknownOn", defaultValue: false) }
var isHideOTPOn: DefaultsKey<Bool> { .init("isHideOTPOn", defaultValue: false) } var isHideOTPOn: DefaultsKey<Bool> { DefaultsKey("isHideOTPOn", defaultValue: false) }
var isRememberPGPPassphraseOn: DefaultsKey<Bool> { .init("isRememberPGPPassphraseOn", defaultValue: false) } var isRememberPGPPassphraseOn: DefaultsKey<Bool> { DefaultsKey("isRememberPGPPassphraseOn", defaultValue: false) }
var isRememberGitCredentialPassphraseOn: DefaultsKey<Bool> { .init("isRememberGitCredentialPassphraseOn", defaultValue: false) } var isRememberGitCredentialPassphraseOn: DefaultsKey<Bool> { DefaultsKey("isRememberGitCredentialPassphraseOn", defaultValue: false) }
var isEnableGPGIDOn: DefaultsKey<Bool> { .init("isEnableGPGIDOn", defaultValue: false) } var isEnableGPGIDOn: DefaultsKey<Bool> { DefaultsKey("isEnableGPGIDOn", defaultValue: false) }
var isShowFolderOn: DefaultsKey<Bool> { .init("isShowFolderOn", defaultValue: true) } var isShowFolderOn: DefaultsKey<Bool> { DefaultsKey("isShowFolderOn", defaultValue: true) }
var isHidePasswordImagesOn: DefaultsKey<Bool> { .init("isHidePasswordImagesOn", defaultValue: false) } var isHidePasswordImagesOn: DefaultsKey<Bool> { DefaultsKey("isHidePasswordImagesOn", defaultValue: false) }
var searchDefault: DefaultsKey<SearchBarScope?> { .init("searchDefault", defaultValue: .all) } var searchDefault: DefaultsKey<SearchBarScope?> { DefaultsKey("searchDefault", defaultValue: .all) }
var passwordGenerator: DefaultsKey<PasswordGenerator> { .init("passwordGenerator", defaultValue: PasswordGenerator()) } var passwordGenerator: DefaultsKey<PasswordGenerator> { DefaultsKey("passwordGenerator", defaultValue: PasswordGenerator()) }
var encryptInArmored: DefaultsKey<Bool> { .init("encryptInArmored", defaultValue: false) } var encryptInArmored: DefaultsKey<Bool> { DefaultsKey("encryptInArmored", defaultValue: false) }
var autoCopyOTP: DefaultsKey<Bool> { .init("autoCopyOTP", defaultValue: false) } var autoCopyOTP: DefaultsKey<Bool> { DefaultsKey("autoCopyOTP", defaultValue: false) }
} }

View file

@ -48,6 +48,7 @@ class Parser {
guard lineNumber < purgedAdditionalLines.count else { guard lineNumber < purgedAdditionalLines.count else {
return result return result
} }
// swiftlint:disable:next unused_enumerated
let numberInitialBlanks = purgedAdditionalLines[lineNumber].enumerated().first { let numberInitialBlanks = purgedAdditionalLines[lineNumber].enumerated().first {
$1 != Character(Constants.BLANK) $1 != Character(Constants.BLANK)
}?.0 ?? purgedAdditionalLines[lineNumber].count }?.0 ?? purgedAdditionalLines[lineNumber].count

View file

@ -8,11 +8,12 @@
import XCTest import XCTest
// swiftformat:disable:next sortedImports
@testable import passKit
@testable import Gopenpgp @testable import Gopenpgp
class CryptoFrameworkTest: XCTestCase { // swiftformat:disable:next sortedImports
@testable import passKit
final class CryptoFrameworkTest: XCTestCase {
private typealias MessageConverter = (CryptoPGPMessage, NSErrorPointer) -> CryptoPGPMessage? private typealias MessageConverter = (CryptoPGPMessage, NSErrorPointer) -> CryptoPGPMessage?
private let testText = "Hello World!" private let testText = "Hello World!"

View file

@ -11,11 +11,11 @@ import XCTest
@testable import passKit @testable import passKit
class PGPAgentTest: XCTestCase { final class PGPAgentTest: XCTestCase {
private var keychain: KeyStore! private var keychain: KeyStore!
private var pgpAgent: PGPAgent! private var pgpAgent: PGPAgent!
private let testData = "Hello World!".data(using: .utf8)! private let testData = Data("Hello World!".utf8)
override func setUp() { override func setUp() {
super.setUp() super.setUp()

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class ArraySlicesTest: XCTestCase { final class ArraySlicesTest: XCTestCase {
func testZeroCount() { func testZeroCount() {
XCTAssertEqual([1, 2, 3].slices(count: 0), []) XCTAssertEqual([1, 2, 3].slices(count: 0), [])
} }

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class StringUtilitiesTest: XCTestCase { final class StringUtilitiesTest: XCTestCase {
func testTrimmed() { func testTrimmed() {
[ [
(" ", ""), (" ", ""),

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class KeyFileManagerTest: XCTestCase { final class KeyFileManagerTest: XCTestCase {
private static let filePath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("test.txt").path private static let filePath = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("test.txt").path
private static let keyFileManager = KeyFileManager(keyType: PGPKey.PUBLIC, keyPath: filePath) { _, _ in } private static let keyFileManager = KeyFileManager(keyType: PGPKey.PUBLIC, keyPath: filePath) { _, _ in }

View file

@ -12,7 +12,7 @@ import ObjectiveGit
import SwiftyUserDefaults import SwiftyUserDefaults
@testable import passKit @testable import passKit
class GitCredentialTest: XCTestCase { final class GitCredentialTest: XCTestCase {
private static let defaultsID = "SharedDefaultsForGitCredentialTest" private static let defaultsID = "SharedDefaultsForGitCredentialTest"
private let keyStore = DictBasedKeychain() private let keyStore = DictBasedKeychain()

View file

@ -12,7 +12,7 @@ import XCTest
@testable import passKit @testable import passKit
class PasswordStoreTest: XCTestCase { final class PasswordStoreTest: XCTestCase {
private let remoteRepoURL = URL(string: "https://github.com/mssun/passforios-password-store.git")! private let remoteRepoURL = URL(string: "https://github.com/mssun/passforios-password-store.git")!
func testCloneAndDecryptMultiKeys() throws { func testCloneAndDecryptMultiKeys() throws {

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class PasswordTableEntryTest: XCTestCase { final class PasswordTableEntryTest: XCTestCase {
func testExample() { func testExample() {
let nameWithCategoryList = [ let nameWithCategoryList = [
"github", "github",

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class PasswordTest: XCTestCase { final class PasswordTest: XCTestCase {
func testURL() { func testURL() {
let password = getPasswordObjectWith(content: "") let password = getPasswordObjectWith(content: "")

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class AdditionFieldTest: XCTestCase { final class AdditionFieldTest: XCTestCase {
func testAdditionField() { func testAdditionField() {
let field1 = AdditionField(title: "key", content: "value") let field1 = AdditionField(title: "key", content: "value")
let field2 = AdditionField(title: "no content") let field2 = AdditionField(title: "no content")

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class ConstantsTest: XCTestCase { final class ConstantsTest: XCTestCase {
func testIsOtpRelated() { func testIsOtpRelated() {
XCTAssert(Constants.isOtpRelated(line: "otpauth://something")) XCTAssert(Constants.isOtpRelated(line: "otpauth://something"))
XCTAssert(Constants.isOtpRelated(line: "otp_algorithm: algorithm")) XCTAssert(Constants.isOtpRelated(line: "otp_algorithm: algorithm"))

View file

@ -11,9 +11,9 @@ import XCTest
@testable import passKit @testable import passKit
class OTPTypeTest: XCTestCase { final class OTPTypeTest: XCTestCase {
func testInitFromToken() { func testInitFromToken() {
let secret = "secret".data(using: .utf8)! let secret = Data("secret".utf8)
let totpGenerator = Generator(factor: .timer(period: 30.0), secret: secret, algorithm: .sha1, digits: 6)! let totpGenerator = Generator(factor: .timer(period: 30.0), secret: secret, algorithm: .sha1, digits: 6)!
let totpToken = Token(name: "", issuer: "", generator: totpGenerator) let totpToken = Token(name: "", issuer: "", generator: totpGenerator)

View file

@ -9,7 +9,7 @@
import XCTest import XCTest
@testable import passKit @testable import passKit
class ParserTest: XCTestCase { final class ParserTest: XCTestCase {
func testInit() { func testInit() {
[ [
("", "", "", []), ("", "", "", []),

View file

@ -12,7 +12,7 @@ import XCTest
@testable import passKit @testable import passKit
class TokenBuilderTest: XCTestCase { final class TokenBuilderTest: XCTestCase {
private let SECRET = "secret" private let SECRET = "secret"
private let DIGITS = Constants.DEFAULT_DIGITS private let DIGITS = Constants.DEFAULT_DIGITS
private let TIMER = Generator.Factor.timer(period: Constants.DEFAULT_PERIOD) private let TIMER = Generator.Factor.timer(period: Constants.DEFAULT_PERIOD)

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class PasswordGeneratorFlavorTest: XCTestCase { final class PasswordGeneratorFlavorTest: XCTestCase {
func testLengthLimits() { func testLengthLimits() {
// Ensure properly chosen length limits. So this check no longer needs to be performed in the code. // Ensure properly chosen length limits. So this check no longer needs to be performed in the code.
PasswordGeneratorFlavor.allCases.map(\.lengthLimits).forEach { PasswordGeneratorFlavor.allCases.map(\.lengthLimits).forEach {

View file

@ -10,7 +10,7 @@ import XCTest
@testable import passKit @testable import passKit
class PasswordGeneratorTest: XCTestCase { final class PasswordGeneratorTest: XCTestCase {
func testLimitedLength() { func testLimitedLength() {
[ [
PasswordGenerator(length: 15), PasswordGenerator(length: 15),

View file

@ -11,7 +11,7 @@ import XCTest
@testable import passKit @testable import passKit
struct PGPTestSet { struct PGPTestSet {
fileprivate static var ALL_TEST_SETS: [String: PGPTestSet] = [:] // swiftlint:disable:this strict_fileprivate fileprivate static var ALL_TEST_SETS: [String: Self] = [:] // swiftlint:disable:this strict_fileprivate
let publicKey: String let publicKey: String
let privateKey: String let privateKey: String

View file

@ -10,7 +10,7 @@ import XCTest
@testable import Pass @testable import Pass
class QRKeyScannerTest: XCTestCase { final class QRKeyScannerTest: XCTestCase {
private let header = "-----BEGIN PGP PUBLIC KEY BLOCK-----" private let header = "-----BEGIN PGP PUBLIC KEY BLOCK-----"
private let body = "key body" private let body = "key body"
private let footer = "-----END PGP PUBLIC KEY BLOCK-----" private let footer = "-----END PGP PUBLIC KEY BLOCK-----"

View file

@ -10,7 +10,7 @@ import XCTest
@testable import Pass @testable import Pass
class ScannableKeyTypeTest: XCTestCase { final class ScannableKeyTypeTest: XCTestCase {
func testPGPPublicKey() { func testPGPPublicKey() {
let type = ScannableKeyType.pgpPublic let type = ScannableKeyType.pgpPublic

View file

@ -1,25 +0,0 @@
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin${PATH+:$PATH}"
SWIFTFORMAT_VERSION="0.51.*"
if [[ "${CI}" == "true" ]]; then
echo "Running in a Continuous Integration environment. Formatting is skipped."
exit 0
fi
if [[ "${CONFIGURATION}" == "Release" ]]; then
echo "Running during a release build. Formatting is skipped."
exit 0
fi
if which swiftformat > /dev/null; then
if [[ "$(swiftformat --version)" == $SWIFTFORMAT_VERSION ]]; then
swiftformat .
else
echo "Failure: SwiftFormat $SWIFTFORMAT_VERSION is required. Install it or update the build script to use a newer version."
exit 1
fi
else
echo "Failure: SwiftFormat not installed. Get it via 'brew install swiftformat'."
exit 2
fi

View file

@ -1,26 +0,0 @@
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin${PATH+:$PATH}"
SWIFTLINT_VERSION="0.52.*"
if [[ "${CI}" == "true" ]]; then
echo "Running in a Continuous Integration environment. Linting is skipped."
exit 0
fi
if [[ "${CONFIGURATION}" == "Release" ]]; then
echo "Running during a release build. Linting is skipped."
exit 0
fi
if which swiftlint > /dev/null; then
if [[ "$(swiftlint version)" == $SWIFTLINT_VERSION ]]; then
swiftlint --strict
else
echo "Failure: SwiftLint $SWIFTLINT_VERSION is required. Install it or update the build script to use a newer version."
exit 1
fi
else
echo "Failure: SwiftLint not installed. Get it via 'brew install swiftlint'."
exit 2
fi