import Foundation
struct Deploy {
private let keyValue: [Deploy.NamedKey: String]
}
extension Deploy.NamedKey {
var fileName: String? { switch self { case .title: return "name.txt" case .subtitle: return "subtitle.txt" case .keywords: return "keywords.txt" case .whatsNew: return "release_notes.txt" default: return nil } }
}
public extension Array {
func isIndexValid(index: Int) -> Bool { return index >= 0 && index < self.count } func safeObject(at index: Int) -> Element? { guard self.isIndexValid(index: index) else { return nil } return self[index] }
}
extension String {
func fixedValue() -> String { self .replacingOccurrences(of: "\\n", with: "\n") .replacingOccurrences(of: "\r", with: "") }
}
extension Deploy {
enum NamedKey: String, CaseIterable { case title = "Title" case subtitle = "Subtitle" case keywords = "keywords" case iPhone8 = "iPhone8" case iPhone11 = "iPhone11" case whatsNew = "What's new" case locale = "locale" case previewTimestamp case iPadPro = "iPadPro" case iPadPro3Gen = "iPadPro3Gen" } init(string: String, map: [Int: NamedKey]) { let cmp = string.components(separatedBy: "\t") var keyValue = [Deploy.NamedKey: String]() cmp.enumerated().forEach { (idx, item) in if let key = map[idx] { keyValue[key] = item.fixedValue() } } self.keyValue = keyValue } subscript(key: NamedKey) -> String { let text = self.keyValue[key] ?? "" return text } func createFiles(at url: URL) { NamedKey.allCases.forEach { if let fileName = $0.fileName { url.write(self[$0], to: fileName) } } }
}
extension URL {
func write(_ text: String, to path: String) { let url = self.appendingPathComponent(path) do { print("Write \(url.path)") try text.write(to: url, atomically: true, encoding: .utf8) print("Done") } catch { print(">>>>>\(text) write error: \(error) to path \(url)") } }
}
extension Deploy {
static func fromTSV(_ url: String) throws -> [Deploy] { let data = try Data(contentsOf: URL(string: url)!) var map = [Int: Deploy.NamedKey]() let deploys: [Deploy] do { let tsv = String(data: data, encoding: .utf8)!.components(separatedBy: "\n") guard tsv.count > 1 else { print("TSV should have more than 1 line"); exit(-1) } let keys = tsv[0].components(separatedBy: "\t") print("Raw keys: \(keys)") keys.enumerated().forEach { (idx, key) in map[idx] = Deploy.NamedKey(rawValue: key.fixedValue()) } print("Found keys: \(map.map({ "\($0.key):\($0.value.rawValue)" }))") deploys = tsv.dropFirst().map { Deploy(string: $0, map: map) } } return deploys }
}
//fileprivate extension String { // // func ids(scale: Int) -> [Deploy.IdWithScale] { // return self.components(separatedBy: “,”).map { // ($0 as NSString).trimmingCharacters(in: CharacterSet(charactersIn: “0123456789:”).inverted) // }.filter { // !$0.isEmpty // }.map { // Deploy.IdWithScale(id: $0, scale: scale) // } // } // //}