Files
2022-12-18 16:22:09 +03:00

217 lines
8.7 KiB
Swift
Executable File

#!/usr/bin/env swift
import Foundation
protocol TemplateResolverType {
static var bundleIdPrefix: String { get }
static var defaultConfig: String { get }
static var developmentTeam: String { get }
static var codeSignIdentity: String { get }
static var applicationIdentifier: String { get }
static var targetWalletName: String { get }
static var cfBundleDisplayName: String { get }
static var provisionProfileSpecifier: String { get }
static var branchKey: String { get }
static var apnsEnvironment: String { get }
static var appTestEnvironment: String { get }
static var appSymbolsHidden: String { get }
}
final class YamlGenerator {
enum SchemeType: RawRepresentable {
case develop
case production
case beta
init?(rawValue: String) {
switch rawValue.uppercased() {
case "DEV": self = .develop
case "PROD": self = .production
case "BETA": self = .beta
default: return nil
}
}
var rawValue: String {
switch self {
case .develop: return "DEV"
case .production: return "PROD"
case .beta: return "BETA"
}
}
}
private enum Constants {
enum Templates {
static let bundleIdPrefix = "{{BUNDLE_ID_PREFIX}}"
static let defaultConfig = "{{defaultConfig}}"
static let developmentTeam = "{{DEVELOPMENT_TEAM}}"
static let codeSignIdentity = "{{CODE_SIGN_IDENTITY}}"
static let applicationIdentifier = "{{APPLICATION_IDENTIFIER}}"
static let targetWalletName = "{{TARGET_NAME}}"
static let cfBundleDisplayName = "{{CFBundleDisplayName}}"
static let provisionProfileSpecifier = "{{PROVISIONING_PROFILE_SPECIFIER}}"
static var branchKey = "{{BRANCH_IO_KEY}}"
static let apnsEnvironment = "{{APNS_ENVIRONMENT}}"
static let appTestEnvironment = "{{APPTEST_ENVIRONMENT}}"
static var appSymbolsHidden = "{{APP_SYMBOLS_HIDDEN}}"
// static let developmentTeam = ""
}
enum Develop: TemplateResolverType {
static let bundleIdPrefix = "life.malinka"
static let defaultConfig = "Debug"
static let developmentTeam = "5X8S8LB8AS"
static let codeSignIdentity = "Apple Development: Apple Developer (97PX84935W)"
static let applicationIdentifier = "life.malinka.wallet"
static let targetWalletName = "Malinka"
static let cfBundleDisplayName = "Malinka"
static let provisionProfileSpecifier = "MalinkaLifeDevelop"
static var branchKey = "key_live_dp4OUMZqz0SmPg2p9rUp3cijtrpvCaUD"
static let apnsEnvironment = "development"
static let appTestEnvironment = "development"
static var appSymbolsHidden = "NO"
// static let developmentTeam = ""
}
enum Production: TemplateResolverType {
static let bundleIdPrefix = "life.malinka"
static let defaultConfig = "Release"
static let developmentTeam = "5X8S8LB8AS"
static let codeSignIdentity = "Apple Distribution: Alvosta UAB (5X8S8LB8AS)"
static let applicationIdentifier = "life.malinka.wallet"
static let targetWalletName = "Malinka"
static let cfBundleDisplayName = "Malinka"
static let provisionProfileSpecifier = "MalinkaLifeDistribution"
static var branchKey = "key_live_dp4OUMZqz0SmPg2p9rUp3cijtrpvCaUD"
static let apnsEnvironment = "production"
static let appTestEnvironment = "production"
static var appSymbolsHidden = "YES"
// static let developmentTeam = ""
}
enum Beta: TemplateResolverType {
static let bundleIdPrefix = "life.malinka"
static let defaultConfig = "Release"
static let developmentTeam = "5X8S8LB8AS"
static let codeSignIdentity = "Apple Distribution: Alvosta UAB (5X8S8LB8AS)"
static let applicationIdentifier = "life.malinka.wallet"
static let targetWalletName = "Malinka"
static let cfBundleDisplayName = "Malinka"
static let provisionProfileSpecifier = "MalinkaLifeDistribution"
static var branchKey = "key_live_dp4OUMZqz0SmPg2p9rUp3cijtrpvCaUD"
static let apnsEnvironment = "production"
static let appTestEnvironment = "production"
static var appSymbolsHidden = "YES"
// static let developmentTeam = ""
}
}
static func backup(yaml path: String) -> Data {
return try! Data(contentsOf: URL(string: "file://\(path)")!)
}
static func restore(yaml path: String, data: Data) {
try! data.write(to: URL(string: "file://\(path)")!)
}
static func prepare(yaml path: String, type: SchemeType) {
let data = try! Data(contentsOf: URL(string: "file://\(path)")!)
let content = String(decoding: data, as: UTF8.self)
let resolver: TemplateResolverType.Type
switch type {
case .develop: resolver = Constants.Develop.self
case .production: resolver = Constants.Production.self
case .beta: resolver = Constants.Beta.self
}
var resultContent = content
.replacingOccurrences(of: Constants.Templates.bundleIdPrefix, with: resolver.bundleIdPrefix)
.replacingOccurrences(of: Constants.Templates.applicationIdentifier, with: resolver.applicationIdentifier)
.replacingOccurrences(of: Constants.Templates.cfBundleDisplayName, with: resolver.cfBundleDisplayName)
.replacingOccurrences(of: Constants.Templates.codeSignIdentity, with: resolver.codeSignIdentity)
.replacingOccurrences(of: Constants.Templates.defaultConfig, with: resolver.defaultConfig)
.replacingOccurrences(of: Constants.Templates.developmentTeam, with: resolver.developmentTeam)
.replacingOccurrences(of: Constants.Templates.targetWalletName, with: resolver.targetWalletName)
.replacingOccurrences(of: Constants.Templates.provisionProfileSpecifier, with: resolver.provisionProfileSpecifier)
.replacingOccurrences(of: Constants.Templates.branchKey, with: resolver.branchKey)
.replacingOccurrences(of: Constants.Templates.apnsEnvironment, with: resolver.apnsEnvironment)
.replacingOccurrences(of: Constants.Templates.appTestEnvironment, with: resolver.appTestEnvironment)
.replacingOccurrences(of: Constants.Templates.appSymbolsHidden, with: resolver.appSymbolsHidden)
// Only for debug purposes! Allow Fiddler sniffing
switch type {
case .develop, .beta: resultContent = resultContent.replacingOccurrences(of: "NSExceptionDomains", with: "NSExceptionDomains1")
default: break
}
let resultData = resultContent.data(using: .utf8)!
try! resultData.write(to: URL(string: "file://\(path)")!)
}
// MARK: - Private
}
func showHelp() {
print("How to use:")
print("--path=[PATH TO YAML]")
print("--type=[DEV|BETA|PROD] default value is DEV")
print("--version=X.Y.Z default value is from file 'version'")
print("--build=XX default value is from file 'build'")
}
guard let pathArguments = CommandLine.arguments.first(where: { $0.contains("path") })
, let path = pathArguments.split(separator: "=").last else {
showHelp()
exit(1)
}
guard let xcodegenPath = ["/usr/local/bin/xcodegen", "/opt/homebrew/bin/xcodegen"].first(where: { FileManager.default.fileExists(atPath: $0) }) else {
print("Error 🍄 Can't find xcodegen")
exit(1)
}
let type: YamlGenerator.SchemeType
if let typeArguments = CommandLine.arguments.first(where: { $0.contains("type") })
, let arg = typeArguments.split(separator: "=").last
, let scheme = YamlGenerator.SchemeType(rawValue: String(arg)) {
type = scheme
} else {
type = .develop
}
// Replace templates
let yamlPath = "\(FileManager.default.currentDirectoryPath)/\(String(path))"
let data = YamlGenerator.backup(yaml: yamlPath)
YamlGenerator.prepare(yaml: yamlPath, type: type)
print("Generate xcodeproj 🥃")
let projectDirectory = yamlPath
.split(separator: "/")
.dropLast(1)
.map(String.init)
.joined(separator: "/")
print("PATH: \(yamlPath)")
let xcodegenProcess = Process()
xcodegenProcess.executableURL = URL(fileURLWithPath: xcodegenPath)
xcodegenProcess.arguments = ["generate",
"--spec", "\(yamlPath)"]
do {
try xcodegenProcess.run()
xcodegenProcess.waitUntilExit()
} catch {
print(error)
}
YamlGenerator.restore(yaml: yamlPath, data: data)
exit(0)