PrefMgr // Add ability to dump pref data as a shell script.

This commit is contained in:
ShikiSuen 2023-11-30 23:34:50 +08:00
parent 238845fb1d
commit 82dea233b6
1 changed files with 73 additions and 0 deletions

View File

@ -8,6 +8,7 @@
import InputMethodKit
import Shared
import SwiftExtension
import SwiftUI
// MARK: ObservableProject.
@ -68,3 +69,75 @@ public extension PrefMgr {
}
}
}
// MARK: Print share-safe UserDefaults into a bunch of "defaults write" commands.
public extension PrefMgr {
@discardableResult func dumpShellScriptBackup() -> String? {
let mirror = Mirror(reflecting: PrefMgr.shared)
guard let bundleIdentifier = Bundle.main.bundleIdentifier else { return nil }
let strDoubleDashLine = String(String(repeating: "=", count: 70))
let consoleOutput = NSMutableString(string: "#!/bin/sh\n\n")
consoleOutput.append("# \(strDoubleDashLine)\n")
consoleOutput.append("# vChewing Preferences Migration Script\n")
consoleOutput.append("# - vChewing IME v\(IMEApp.appVersionLabel)\n")
consoleOutput.append("# \(strDoubleDashLine)\n\n")
for case let (_, value) in mirror.children {
//
let rawCells = "\(value)".replacingOccurrences(of: "String, Bool", with: "String,Bool").components(separatedBy: " ")
guard rawCells.count >= 4 else { continue }
let strKeyName = rawCells[1].dropLast(2).dropFirst(1).replacingOccurrences(of: "\n", with: "\\n")
guard let theUserDef = UserDef(rawValue: strKeyName) else { continue }
var strTypeParam = String(describing: theUserDef.dataType)
// Sandbox
let blackList: [UserDef] = [
.kUserDataFolderSpecified, .kCassettePath, .kAppleLanguages, .kFailureFlagForUOMObservation,
.kMostRecentInputMode,
]
guard !blackList.contains(theUserDef) else { continue }
var strValue = rawCells[3].dropLast(1).replacingOccurrences(of: "\n", with: "")
typeCheck: switch theUserDef.dataType {
case .double: strTypeParam = strTypeParam.replacingOccurrences(of: "double", with: "float")
case .dictionary:
if let valParsed = value as? AppProperty<[String: Bool]> {
strTypeParam = strTypeParam.replacingOccurrences(of: "ionary", with: "")
let stack = NSMutableString()
valParsed.wrappedValue.forEach { currentPair in
stack.append("\(currentPair.key) \(currentPair.value) ")
}
strValue = stack.replacingOccurrences(of: "\n", with: "\\n")
} else {
continue
}
case .array:
if let valParsed = value as? AppProperty<[String]> {
strValue = valParsed.wrappedValue.joined(separator: " ")
} else {
continue
}
case .other: continue //
default: break typeCheck
}
if let metaData = theUserDef.metaData {
let strDashLine = String(String(repeating: "-", count: 70))
let texts: [String] = [
strDashLine, metaData.shortTitle,
strDashLine, metaData.prompt,
metaData.popupPrompt, metaData.description, metaData.toolTip,
].compactMap { $0 }.map(\.localized)
texts.forEach { currentLines in
currentLines.split(separator: "\n").forEach { currentLine in
consoleOutput.append("# \(currentLine)\n")
}
}
metaData.options?.sorted(by: { $0.key < $1.key }).forEach { pair in
consoleOutput.append("# - \(pair.key): \(pair.value.localized)\n")
}
} else {
consoleOutput.append("# No comments supplied by the engineer.\n")
}
consoleOutput.append("\ndefaults write \(bundleIdentifier) \(strKeyName) -\(strTypeParam) \(strValue)\n\n")
}
return consoleOutput.description
}
}