Enable SwiftLint rule 'identifier_name' and handle all violations

This commit is contained in:
Danny Moesch 2020-09-20 15:07:18 +02:00 committed by Mingshen Sun
parent 7ada4dd96d
commit e8389eb262
21 changed files with 157 additions and 156 deletions

View file

@ -10,8 +10,8 @@ import Crypto
struct GopenPGPInterface: PGPInterface {
private static let errorMapping: [String: Error] = [
"gopenpgp: error in unlocking key: openpgp: invalid data: private key checksum failure": AppError.WrongPassphrase,
"openpgp: incorrect key": AppError.KeyExpiredOrIncompatible,
"gopenpgp: error in unlocking key: openpgp: invalid data: private key checksum failure": AppError.wrongPassphrase,
"openpgp: incorrect key": AppError.keyExpiredOrIncompatible,
]
private var publicKeys: [String: CryptoKey] = [:]
@ -23,24 +23,24 @@ struct GopenPGPInterface: PGPInterface {
for key in pubKeys {
var error: NSError?
guard let k = CryptoNewKeyFromArmored(key, &error) else {
guard let cryptoKey = CryptoNewKeyFromArmored(key, &error) else {
guard error == nil else {
throw error!
}
throw AppError.KeyImport
throw AppError.keyImport
}
publicKeys[k.getFingerprint().lowercased()] = k
publicKeys[cryptoKey.getFingerprint().lowercased()] = cryptoKey
}
for key in prvKeys {
var error: NSError?
guard let k = CryptoNewKeyFromArmored(key, &error) else {
guard let cryptoKey = CryptoNewKeyFromArmored(key, &error) else {
guard error == nil else {
throw error!
}
throw AppError.KeyImport
throw AppError.keyImport
}
privateKeys[k.getFingerprint().lowercased()] = k
privateKeys[cryptoKey.getFingerprint().lowercased()] = cryptoKey
}
}
@ -71,9 +71,9 @@ struct GopenPGPInterface: PGPInterface {
}
func decrypt(encryptedData: Data, keyID: String, passphrase: String) throws -> Data? {
guard let e = privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) }),
let privateKey = privateKeys[e.key] else {
throw AppError.Decryption
guard let key = privateKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) }),
let privateKey = privateKeys[key.key] else {
throw AppError.decryption
}
do {
@ -84,7 +84,7 @@ struct GopenPGPInterface: PGPInterface {
guard error == nil else {
throw error!
}
throw AppError.Decryption
throw AppError.decryption
}
let message = createPgpMessage(from: encryptedData)
@ -95,9 +95,9 @@ struct GopenPGPInterface: PGPInterface {
}
func encrypt(plainData: Data, keyID: String) throws -> Data {
guard let e = publicKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) }),
let publicKey = publicKeys[e.key] else {
throw AppError.Encryption
guard let key = publicKeys.first(where: { key, _ in key.hasSuffix(keyID.lowercased()) }),
let publicKey = publicKeys[key.key] else {
throw AppError.encryption
}
var error: NSError?
@ -106,7 +106,7 @@ struct GopenPGPInterface: PGPInterface {
guard error == nil else {
throw error!
}
throw AppError.Encryption
throw AppError.encryption
}
let encryptedData = try keyRing.encrypt(CryptoNewPlainMessage(plainData.mutable as Data), privateKey: nil)

View file

@ -16,14 +16,14 @@ struct ObjectivePGPInterface: PGPInterface {
init(publicArmoredKey: String, privateArmoredKey: String) throws {
guard let publicKeyData = publicArmoredKey.data(using: .ascii), let privateKeyData = privateArmoredKey.data(using: .ascii) else {
throw AppError.KeyImport
throw AppError.keyImport
}
let publicKeys = try ObjectivePGP.readKeys(from: publicKeyData)
let privateKeys = try ObjectivePGP.readKeys(from: privateKeyData)
keyring.import(keys: publicKeys)
keyring.import(keys: privateKeys)
guard let publicKey = publicKeys.first, let privateKey = privateKeys.first else {
throw AppError.KeyImport
throw AppError.keyImport
}
self.publicKey = publicKey
self.privateKey = privateKey

View file

@ -21,7 +21,7 @@ public class PGPAgent {
guard let publicKey: String = keyStore.get(for: PgpKey.PUBLIC.getKeychainKey()),
let privateKey: String = keyStore.get(for: PgpKey.PRIVATE.getKeychainKey()) else {
pgpInterface = nil
throw AppError.KeyImport
throw AppError.keyImport
}
do {
pgpInterface = try GopenPGPInterface(publicArmoredKey: publicKey, privateArmoredKey: privateKey)
@ -48,7 +48,7 @@ public class PGPAgent {
// Init keys.
try checkAndInit()
guard let pgpInterface = pgpInterface else {
throw AppError.Decryption
throw AppError.decryption
}
var keyID = keyID
@ -56,7 +56,7 @@ public class PGPAgent {
if pgpInterface.keyID.count == 1 {
keyID = pgpInterface.keyID.first!
} else {
throw AppError.PgpPrivateKeyNotFound(keyID: keyID)
throw AppError.pgpPrivateKeyNotFound(keyID: keyID)
}
}
@ -83,14 +83,14 @@ public class PGPAgent {
public func encrypt(plainData: Data, keyID: String) throws -> Data {
try checkAndInit()
guard let pgpInterface = pgpInterface else {
throw AppError.Encryption
throw AppError.encryption
}
var keyID = keyID
if !pgpInterface.containsPublicKey(with: keyID) {
if pgpInterface.keyID.count == 1 {
keyID = pgpInterface.keyID.first!
} else {
throw AppError.PgpPublicKeyNotFound(keyID: keyID)
throw AppError.pgpPublicKeyNotFound(keyID: keyID)
}
}
return try pgpInterface.encrypt(plainData: plainData, keyID: keyID)

View file

@ -37,8 +37,8 @@ extension UIAlertAction {
public static func selectKey(controller: UIViewController, handler: ((UIAlertAction) -> Void)?) -> UIAlertAction {
UIAlertAction(title: "Select Key", style: .default) { _ in
let selectKeyAlert = UIAlertController(title: "Select from imported keys", message: nil, preferredStyle: .actionSheet)
try? PGPAgent.shared.getShortKeyID().forEach { k in
let action = UIAlertAction(title: k, style: .default, handler: handler)
try? PGPAgent.shared.getShortKeyID().forEach { keyID in
let action = UIAlertAction(title: keyID, style: .default, handler: handler)
selectKeyAlert.addAction(action)
}
selectKeyAlert.addAction(UIAlertAction.cancelAndPopView(controller: controller))

View file

@ -7,34 +7,35 @@
//
public enum AppError: Error, Equatable {
case RepositoryNotSet
case RepositoryRemoteBranchNotFound(_: String)
case RepositoryBranchNotFound(_: String)
case KeyImport
case ReadingFile(_: String)
case PasswordDuplicated
case GitReset
case GitCreateSignature
case GitPushNotSuccessful
case PasswordEntity
case PgpPublicKeyNotFound(keyID: String)
case PgpPrivateKeyNotFound(keyID: String)
case KeyExpiredOrIncompatible
case WrongPassphrase
case WrongPasswordFilename
case Decryption
case Encryption
case Encoding
case Unknown
case repositoryNotSet
case repositoryRemoteBranchNotFound(branchName: String)
case repositoryBranchNotFound(branchName: String)
case keyImport
case readingFile(fileName: String)
case passwordDuplicated
case gitReset
case gitCreateSignature
case gitPushNotSuccessful
case passwordEntity
case pgpPublicKeyNotFound(keyID: String)
case pgpPrivateKeyNotFound(keyID: String)
case keyExpiredOrIncompatible
case wrongPassphrase
case wrongPasswordFilename
case decryption
case encryption
case encoding
case unknown
}
extension AppError: LocalizedError {
public var errorDescription: String? {
let localizationKey = "\(String(describing: self).prefix { $0 != "(" })Error."
let enumName = String(describing: self)
let localizationKey = "\(enumName.first!.uppercased())\(enumName.dropFirst().prefix { $0 != "(" })Error."
switch self {
case let .RepositoryRemoteBranchNotFound(name), let .RepositoryBranchNotFound(name), let .ReadingFile(name):
case let .repositoryRemoteBranchNotFound(name), let .repositoryBranchNotFound(name), let .readingFile(name):
return localizationKey.localize(name)
case let .PgpPublicKeyNotFound(keyID), let .PgpPrivateKeyNotFound(keyID):
case let .pgpPublicKeyNotFound(keyID), let .pgpPrivateKeyNotFound(keyID):
return localizationKey.localize(keyID)
default:
return localizationKey.localize()

View file

@ -44,11 +44,9 @@ public class AppKeychain: KeyStore {
}
public func removeAllContent(withPrefix prefix: String) {
for k in keychain.allKeys() {
if k.hasPrefix(prefix) {
try? keychain.remove(k)
}
}
keychain.allKeys()
.filter { $0.hasPrefix(prefix) }
.forEach { try? keychain.remove($0) }
}
public static func getPGPKeyPassphraseKey(keyID: String) -> String {

View file

@ -35,7 +35,7 @@ public class KeyFileManager {
public func importKey(from string: String) throws {
guard string.unicodeScalars.allSatisfy({ $0.isASCII }) else {
throw AppError.Encoding
throw AppError.encoding
}
keyHandler(string, keyType.getKeychainKey())
}

View file

@ -11,8 +11,8 @@ import SwiftyUserDefaults
extension PasswordEntity {
public var nameWithCategory: String {
if let p = path, p.hasSuffix(".gpg") {
return String(p.prefix(upTo: p.index(p.endIndex, offsetBy: -4)))
if let path = path, path.hasSuffix(".gpg") {
return String(path.prefix(upTo: path.index(path.endIndex, offsetBy: -4)))
}
return ""
}
@ -33,10 +33,10 @@ extension PasswordEntity {
}
public func getURL() throws -> URL {
if let p = getPath().stringByAddingPercentEncodingForRFC3986(), let u = URL(string: p) {
return u
if let path = getPath().stringByAddingPercentEncodingForRFC3986(), let url = URL(string: path) {
return url
}
throw AppError.Unknown
throw AppError.unknown
}
// XXX: define some getters to get core data, we need to consider

View file

@ -53,7 +53,7 @@ public class PasswordStore {
}
}
private let fm = FileManager.default
private let fileManager = FileManager.default
private lazy var context: NSManagedObjectContext = {
let modelURL = Bundle(identifier: Globals.passKitBundleIdentifier)!.url(forResource: "pass", withExtension: "momd")!
let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL)
@ -86,7 +86,7 @@ public class PasswordStore {
}
public var sizeOfRepositoryByteCount: UInt64 {
(try? fm.allocatedSizeOfDirectoryAtURL(directoryURL: storeURL)) ?? 0
(try? fileManager.allocatedSizeOfDirectoryAtURL(directoryURL: storeURL)) ?? 0
}
public var numberOfLocalCommits: Int {
@ -108,7 +108,7 @@ public class PasswordStore {
importExistingKeysIntoKeychain()
do {
if fm.fileExists(atPath: storeURL.path) {
if fileManager.fileExists(atPath: storeURL.path) {
try self.storeRepository = GTRepository(url: storeURL)
}
} catch {
@ -127,8 +127,7 @@ public class PasswordStore {
}
public func repositoryExists() -> Bool {
let fm = FileManager()
return fm.fileExists(atPath: Globals.repositoryPath)
fileManager.fileExists(atPath: Globals.repositoryPath)
}
public func passwordExisted(password: Password) -> Bool {
@ -178,8 +177,8 @@ public class PasswordStore {
transferProgressBlock: @escaping (UnsafePointer<git_transfer_progress>, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _ in },
checkoutProgressBlock: @escaping (String, UInt, UInt) -> Void = { _, _, _ in }
) throws {
try? fm.removeItem(at: storeURL)
try? fm.removeItem(at: tempStoreURL)
try? fileManager.removeItem(at: storeURL)
try? fileManager.removeItem(at: tempStoreURL)
gitPassword = nil
gitSSHPrivateKeyPassphrase = nil
do {
@ -189,7 +188,7 @@ public class PasswordStore {
options: options,
transferProgressBlock: transferProgressBlock
)
try fm.moveItem(at: tempStoreURL, to: storeURL)
try fileManager.moveItem(at: tempStoreURL, to: storeURL)
storeRepository = try GTRepository(url: storeURL)
if (try storeRepository?.currentBranch().name) != branchName {
try checkoutAndChangeBranch(withName: branchName, progressBlock: checkoutProgressBlock)
@ -211,12 +210,12 @@ public class PasswordStore {
private func checkoutAndChangeBranch(withName localBranchName: String, progressBlock: @escaping (String, UInt, UInt) -> Void) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
let remoteBranchName = "origin/\(localBranchName)"
let remoteBranch = try storeRepository.lookUpBranch(withName: remoteBranchName, type: .remote, success: nil)
guard let remoteBranchOid = remoteBranch.oid else {
throw AppError.RepositoryRemoteBranchNotFound(remoteBranchName)
throw AppError.repositoryRemoteBranchNotFound(branchName: remoteBranchName)
}
let localBranch = try storeRepository.createBranchNamed(localBranchName, from: remoteBranchOid, message: nil)
try localBranch.updateTrackingBranch(remoteBranch)
@ -230,7 +229,7 @@ public class PasswordStore {
progressBlock: @escaping (UnsafePointer<git_transfer_progress>, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _ in }
) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
let remote = try GTRemote(name: "origin", in: storeRepository)
try storeRepository.pull(storeRepository.currentBranch(), from: remote, withOptions: options, progress: progressBlock)
@ -245,7 +244,7 @@ public class PasswordStore {
private func updatePasswordEntityCoreData() {
deleteCoreData(entityName: "PasswordEntity")
do {
var q = try fm.contentsOfDirectory(atPath: storeURL.path)
var entities = try fileManager.contentsOfDirectory(atPath: storeURL.path)
.filter { !$0.hasPrefix(".") }
.map { filename -> PasswordEntity in
let passwordEntity = NSEntityDescription.insertNewObject(forEntityName: "PasswordEntity", into: context) as! PasswordEntity
@ -258,18 +257,18 @@ public class PasswordStore {
passwordEntity.parent = nil
return passwordEntity
}
while !q.isEmpty {
let e = q.first!
q.remove(at: 0)
guard !e.name!.hasPrefix(".") else {
while !entities.isEmpty {
let entity = entities.first!
entities.remove(at: 0)
guard !entity.name!.hasPrefix(".") else {
continue
}
var isDirectory: ObjCBool = false
let filePath = storeURL.appendingPathComponent(e.path!).path
if fm.fileExists(atPath: filePath, isDirectory: &isDirectory) {
let filePath = storeURL.appendingPathComponent(entity.path!).path
if fileManager.fileExists(atPath: filePath, isDirectory: &isDirectory) {
if isDirectory.boolValue {
e.isDir = true
let files = try fm.contentsOfDirectory(atPath: filePath)
entity.isDir = true
let files = try fileManager.contentsOfDirectory(atPath: filePath)
.filter { !$0.hasPrefix(".") }
.map { filename -> PasswordEntity in
let passwordEntity = NSEntityDescription.insertNewObject(forEntityName: "PasswordEntity", into: context) as! PasswordEntity
@ -278,13 +277,13 @@ public class PasswordStore {
} else {
passwordEntity.name = filename
}
passwordEntity.path = "\(e.path!)/\(filename)"
passwordEntity.parent = e
passwordEntity.path = "\(entity.path!)/\(filename)"
passwordEntity.parent = entity
return passwordEntity
}
q += files
entities += files
} else {
e.isDir = false
entity.isDir = false
}
}
}
@ -377,7 +376,7 @@ public class PasswordStore {
private func gitAdd(path: String) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
try storeRepository.index().addFile(path)
try storeRepository.index().write()
@ -385,11 +384,11 @@ public class PasswordStore {
private func gitRm(path: String) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
let url = storeURL.appendingPathComponent(path)
if fm.fileExists(atPath: url.path) {
try fm.removeItem(at: url)
if fileManager.fileExists(atPath: url.path) {
try fileManager.removeItem(at: url)
}
try storeRepository.index().removeFile(path)
try storeRepository.index().write()
@ -397,30 +396,30 @@ public class PasswordStore {
private func deleteDirectoryTree(at url: URL) throws {
var tempURL = storeURL.appendingPathComponent(url.deletingLastPathComponent().path)
var count = try fm.contentsOfDirectory(atPath: tempURL.path).count
var count = try fileManager.contentsOfDirectory(atPath: tempURL.path).count
while count == 0 {
try fm.removeItem(at: tempURL)
try fileManager.removeItem(at: tempURL)
tempURL.deleteLastPathComponent()
count = try fm.contentsOfDirectory(atPath: tempURL.path).count
count = try fileManager.contentsOfDirectory(atPath: tempURL.path).count
}
}
private func createDirectoryTree(at url: URL) throws {
let tempURL = storeURL.appendingPathComponent(url.deletingLastPathComponent().path)
try fm.createDirectory(at: tempURL, withIntermediateDirectories: true, attributes: nil)
try fileManager.createDirectory(at: tempURL, withIntermediateDirectories: true, attributes: nil)
}
private func gitMv(from: String, to: String) throws {
let fromURL = storeURL.appendingPathComponent(from)
let toURL = storeURL.appendingPathComponent(to)
try fm.moveItem(at: fromURL, to: toURL)
try fileManager.moveItem(at: fromURL, to: toURL)
try gitAdd(path: to)
try gitRm(path: from)
}
private func gitCommit(message: String) throws -> GTCommit? {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
let newTree = try storeRepository.index().writeTree()
let headReference = try storeRepository.headReference()
@ -428,7 +427,7 @@ public class PasswordStore {
try commitEnum.pushSHA(headReference.targetOID!.sha)
let parent = commitEnum.nextObject() as! GTCommit
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 commit
@ -436,7 +435,7 @@ public class PasswordStore {
private func getLocalBranch(withName branchName: String) throws -> GTBranch? {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
let reference = GTBranch.localNamePrefix().appending(branchName)
let branches = try storeRepository.branches(withPrefix: reference)
@ -448,20 +447,20 @@ public class PasswordStore {
transferProgressBlock: @escaping (UInt32, UInt32, Int, UnsafeMutablePointer<ObjCBool>) -> Void = { _, _, _, _ in }
) throws {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
if let branch = try getLocalBranch(withName: Defaults.gitBranchName) {
let remote = try GTRemote(name: "origin", in: storeRepository)
try storeRepository.push(branch, to: remote, withOptions: options, progress: transferProgressBlock)
}
if numberOfLocalCommits != 0 {
throw AppError.GitPushNotSuccessful
throw AppError.gitPushNotSuccessful
}
}
private func addPasswordEntities(password: Password) throws -> PasswordEntity? {
guard !passwordExisted(password: password) else {
throw AppError.PasswordDuplicated
throw AppError.passwordDuplicated
}
var passwordURL = password.url
@ -472,7 +471,7 @@ public class PasswordStore {
passwordURL = passwordURL.deletingLastPathComponent()
// better identify errors before saving a new password
if passwordURL.path != ".", passwordURL.path.count >= previousPathLength {
throw AppError.WrongPasswordFilename
throw AppError.wrongPasswordFilename
}
previousPathLength = passwordURL.path.count
}
@ -610,8 +609,8 @@ public class PasswordStore {
public func erase() {
// Delete files.
try? fm.removeItem(at: storeURL)
try? fm.removeItem(at: tempStoreURL)
try? fileManager.removeItem(at: storeURL)
try? fileManager.removeItem(at: tempStoreURL)
// Delete PGP key, SSH key and other secrets from the keychain.
AppKeychain.shared.removeAllContent()
@ -637,7 +636,7 @@ public class PasswordStore {
// return the number of discarded commits
public func reset() throws -> Int {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
// get a list of local commits
let localCommits = try getLocalCommits()
@ -648,7 +647,7 @@ public class PasswordStore {
guard let firstLocalCommit = localCommits.last,
firstLocalCommit.parents.count == 1,
let newHead = firstLocalCommit.parents.first else {
throw AppError.GitReset
throw AppError.gitReset
}
try storeRepository.reset(to: newHead, resetType: .hard)
setAllSynced()
@ -661,16 +660,16 @@ public class PasswordStore {
private func getLocalCommits() throws -> [GTCommit] {
guard let storeRepository = storeRepository else {
throw AppError.RepositoryNotSet
throw AppError.repositoryNotSet
}
// get the remote branch
let remoteBranchName = Defaults.gitBranchName
guard let remoteBranch = try storeRepository.remoteBranches().first(where: { $0.shortName == remoteBranchName }) else {
throw AppError.RepositoryRemoteBranchNotFound(remoteBranchName)
throw AppError.repositoryRemoteBranchNotFound(branchName: remoteBranchName)
}
// check oid before calling localCommitsRelative
guard remoteBranch.oid != nil else {
throw AppError.RepositoryRemoteBranchNotFound(remoteBranchName)
throw AppError.repositoryRemoteBranchNotFound(branchName: remoteBranchName)
}
// get a list of local commits
@ -682,7 +681,7 @@ public class PasswordStore {
let keyID = keyID ?? findGPGID(from: encryptedDataPath)
let encryptedData = try Data(contentsOf: encryptedDataPath)
guard let decryptedData = try PGPAgent.shared.decrypt(encryptedData: encryptedData, keyID: keyID, requestPGPKeyPassphrase: requestPGPKeyPassphrase) else {
throw AppError.Decryption
throw AppError.decryption
}
let plainText = String(data: decryptedData, encoding: .utf8) ?? ""
let url = try passwordEntity.getURL()
@ -696,7 +695,7 @@ public class PasswordStore {
}
public func removeGitSSHKeys() {
try? fm.removeItem(atPath: Globals.gitSSHPrivateKeyPath)
try? fileManager.removeItem(atPath: Globals.gitSSHPrivateKeyPath)
Defaults.remove(\.gitSSHKeySource)
Defaults.remove(\.gitSSHPrivateKeyArmor)
Defaults.remove(\.gitSSHPrivateKeyURL)

View file

@ -25,41 +25,41 @@ class Parser {
private func getAdditionFields() -> [AdditionField] {
var additions: [AdditionField] = []
var unknownIndex: UInt = 0
var i = purgedAdditionalLines.startIndex
while i < purgedAdditionalLines.count {
let line = purgedAdditionalLines[i]
i += 1
var lineNumber = purgedAdditionalLines.startIndex
while lineNumber < purgedAdditionalLines.count {
let line = purgedAdditionalLines[lineNumber]
lineNumber += 1
var (key, value) = Parser.getKeyValuePair(from: line)
if key == nil {
unknownIndex += 1
key = Constants.unknown(unknownIndex)
} else if value == Constants.MULTILINE_WITH_LINE_BREAK_INDICATOR {
value = gatherMultilineValue(startingAt: &i, removingLineBreaks: false)
value = gatherMultilineValue(startingAt: &lineNumber, removingLineBreaks: false)
} else if value == Constants.MULTILINE_WITHOUT_LINE_BREAK_INDICATOR {
value = gatherMultilineValue(startingAt: &i, removingLineBreaks: true)
value = gatherMultilineValue(startingAt: &lineNumber, removingLineBreaks: true)
}
additions.append(key! => value)
}
return additions
}
private func gatherMultilineValue(startingAt i: inout Int, removingLineBreaks: Bool) -> String {
private func gatherMultilineValue(startingAt lineNumber: inout Int, removingLineBreaks: Bool) -> String {
var result = ""
guard i < purgedAdditionalLines.count else {
guard lineNumber < purgedAdditionalLines.count else {
return result
}
let numberInitialBlanks = purgedAdditionalLines[i].enumerated().first {
let numberInitialBlanks = purgedAdditionalLines[lineNumber].enumerated().first {
$1 != Character(Constants.BLANK)
}?.0 ?? purgedAdditionalLines[i].count
}?.0 ?? purgedAdditionalLines[lineNumber].count
guard numberInitialBlanks != 0 else {
return result
}
let initialBlanks = String(repeating: Constants.BLANK, count: numberInitialBlanks)
while i < purgedAdditionalLines.count, purgedAdditionalLines[i].starts(with: initialBlanks) {
result.append(String(purgedAdditionalLines[i].dropFirst(numberInitialBlanks)))
while lineNumber < purgedAdditionalLines.count, purgedAdditionalLines[lineNumber].starts(with: initialBlanks) {
result.append(String(purgedAdditionalLines[lineNumber].dropFirst(numberInitialBlanks)))
result.append(Constants.getSeparator(breakingLines: !removingLineBreaks))
i += 1
lineNumber += 1
}
return result.trimmed
}