200 lines
8.2 KiB
Swift
Executable File
200 lines
8.2 KiB
Swift
Executable File
#!/usr/bin/env swift
|
|
|
|
import Foundation
|
|
|
|
protocol TemplateResolverType {
|
|
static var defaultConfig: String { get }
|
|
static var developmentTeam: String { get }
|
|
static var codeSignIdentity: String { get }
|
|
static var swiftActiveCompilationConditions: String { get }
|
|
static var applicationIdentifier: String { get }
|
|
static var targetPrivadoName: String { get }
|
|
static var cfBundleDisplayName: String { get }
|
|
static var provisionProfileSpecifier: String { get }
|
|
static var provisionProfileSpecifierOVPN: String { get }
|
|
static var provisionProfileSpecifierWireGuard: 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 defaultConfig = "{{defaultConfig}}"
|
|
static let developmentTeam = "{{DEVELOPMENT_TEAM}}"
|
|
static let codeSignIdentity = "{{CODE_SIGN_IDENTITY}}"
|
|
static let swiftActiveCompilationConditions = "{{SWIFT_ACTIVE_COMPILATION_CONDITIONS}}"
|
|
static let applicationIdentifier = "{{APPLICATION_IDENTIFIER}}"
|
|
static let targetPrivadoName = "{{TARGET_PRIVADO_NAME}}"
|
|
static let cfBundleDisplayName = "{{CFBundleDisplayName}}"
|
|
static let provisionProfileSpecifier = "{{PROVISIONING_PROFILE_SPECIFIER}}"
|
|
static let provisionProfileSpecifierOVPN = "{{PROVISIONING_PROFILE_SPECIFIER_OVPN}}"
|
|
static let provisionProfileSpecifierWireGuard = "{{PROVISIONING_PROFILE_SPECIFIER_WIREGUARD}}"
|
|
// static let developmentTeam = ""
|
|
}
|
|
|
|
enum Develop: TemplateResolverType {
|
|
static let defaultConfig = "Debug"
|
|
static let developmentTeam = "4D7YV49724"
|
|
static let codeSignIdentity = "Apple Development: Yuriy Shikin (S9D2XZUZH2)"
|
|
static let swiftActiveCompilationConditions = "BETA"
|
|
static let applicationIdentifier = "io.privado.ios"
|
|
static let targetPrivadoName = "PrivadoVPN"
|
|
static let cfBundleDisplayName = "PrivadoVPN"
|
|
static let provisionProfileSpecifier = "Privado iOS"
|
|
static let provisionProfileSpecifierOVPN = "Privado iOS OpenVPN Extension"
|
|
static let provisionProfileSpecifierWireGuard = "Privado iOS Wireguard Extension"
|
|
// static let developmentTeam = ""
|
|
}
|
|
|
|
enum Production: TemplateResolverType {
|
|
static let defaultConfig = "Release"
|
|
static let developmentTeam = "4D7YV49724"
|
|
static let codeSignIdentity = "Apple Distribution: PRIVADO NETWORKS LLC (4D7YV49724)"
|
|
static let swiftActiveCompilationConditions = "PRODUCTION"
|
|
static let applicationIdentifier = "io.privado.ios"
|
|
static let targetPrivadoName = "PrivadoVPN"
|
|
static let cfBundleDisplayName = "PrivadoVPN"
|
|
static let provisionProfileSpecifier = "Privado iOS AppStore"
|
|
static let provisionProfileSpecifierOVPN = "Privado iOS OpenVPN Extension AppStore"
|
|
static let provisionProfileSpecifierWireGuard = "Privado iOS Wireguard Extension AppStore"
|
|
// static let developmentTeam = ""
|
|
}
|
|
|
|
enum Beta: TemplateResolverType {
|
|
static let defaultConfig = "Release"
|
|
static let developmentTeam = "4D7YV49724"
|
|
static let codeSignIdentity = "Apple Distribution: PRIVADO NETWORKS LLC (4D7YV49724)"
|
|
static let swiftActiveCompilationConditions = "BETA"
|
|
static let applicationIdentifier = "io.privado.beta.ios"
|
|
static let targetPrivadoName = "PrivadoVPN"
|
|
static let cfBundleDisplayName = "PrivadoVPN Beta"
|
|
static let provisionProfileSpecifier = "Privado Beta iOS AppStore"
|
|
static let provisionProfileSpecifierOVPN = "Privado Beta iOS OpenVPN Extension AppStore"
|
|
static let provisionProfileSpecifierWireGuard = "Privado Beta iOS Wireguard Extension AppStore"
|
|
// static let developmentTeam = ""
|
|
}
|
|
}
|
|
|
|
@discardableResult
|
|
static func backup(yaml path: String, data: Data? = nil) -> Data? {
|
|
if let data = data {
|
|
try! data.write(to: URL(string: "file://\(path)")!)
|
|
return data
|
|
} else {
|
|
return try! Data(contentsOf: 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
|
|
}
|
|
|
|
let resultContent = content
|
|
.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.provisionProfileSpecifier, with: resolver.provisionProfileSpecifier)
|
|
.replacingOccurrences(of: Constants.Templates.provisionProfileSpecifierOVPN, with: resolver.provisionProfileSpecifierOVPN)
|
|
.replacingOccurrences(of: Constants.Templates.provisionProfileSpecifierWireGuard, with: resolver.provisionProfileSpecifierWireGuard)
|
|
.replacingOccurrences(of: Constants.Templates.swiftActiveCompilationConditions, with: resolver.swiftActiveCompilationConditions)
|
|
.replacingOccurrences(of: Constants.Templates.targetPrivadoName, with: resolver.targetPrivadoName)
|
|
|
|
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")
|
|
}
|
|
|
|
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.backup(yaml: yamlPath, data: data)
|
|
|
|
exit(0)
|