RxSwift/Preprocessor/Preprocessor/main.swift

104 lines
3.4 KiB
Swift

//
// main.swift
// Preprocessor
//
// Created by Krunoslav Zaher on 4/22/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
if Process.argc != 3 {
print("./Preprocessor <source-files-root> <derived-data> ")
exit(-1)
}
let sourceFilesRoot = Process.arguments[1]
let derivedData = Process.arguments[2]
let fileManager = NSFileManager()
func escape(value: String) -> String {
let escapedString = value.stringByReplacingOccurrencesOfString("\n", withString: "\\n")
let escapedString1 = escapedString.stringByReplacingOccurrencesOfString("\r", withString: "\\r")
let escapedString2 = escapedString1.stringByReplacingOccurrencesOfString("\"", withString: "\\\"")
return "\"\(escapedString2)\""
}
func processFile(path: String, outputPath: String) -> String {
let rawContent = NSData(contentsOfFile: path)!
let content = NSString(data: rawContent, encoding: NSUTF8StringEncoding)! as String
let components = content.componentsSeparatedByString("<%")
var functionContentComponents: [String] = []
functionContentComponents.append("var components: [String] = [\"// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project \\n\"]\n")
functionContentComponents.append("components.append(\(escape(components[0])))\n")
for codePlusSuffix in (components[1 ..< components.count]) {
let codePlusSuffixSeparated = codePlusSuffix.componentsSeparatedByString("%>")
if codePlusSuffixSeparated.count != 2 {
fatalError("Error in \(path) near \(codePlusSuffix)")
}
let code = codePlusSuffixSeparated[0]
let suffix = codePlusSuffixSeparated[1]
if code.hasPrefix("=") {
functionContentComponents.append("components.append(String(\(code.substringFromIndex(code.startIndex.successor()))))\n")
}
else {
functionContentComponents.append("\(code)\n")
}
functionContentComponents.append("components.append(\(escape(suffix)));\n")
}
functionContentComponents.append("try! components.joinWithSeparator(\"\").writeToFile(\"\(outputPath)\", atomically: false, encoding: NSUTF8StringEncoding)")
return functionContentComponents.joinWithSeparator("")
}
func runCommand(path: String) {
_ = NSProcessInfo().processIdentifier
let task = NSTask()
task.launchPath = "/bin/bash"
task.arguments = ["-c", "xcrun swift \"\(path)\""]
task.launch()
task.waitUntilExit()
if task.terminationReason != NSTaskTerminationReason.Exit {
exit(-1)
}
}
let files = fileManager.subpathsAtPath(sourceFilesRoot)
var generateAllFiles = ["// Generated code\n", "import Foundation\n"]
for file in files! {
if ((file as NSString).pathExtension ?? "") != "tt" {
continue
}
print(file)
let path = (sourceFilesRoot as NSString).stringByAppendingPathComponent(file as String)
let outputPath = path.substringToIndex(path.endIndex.predecessor().predecessor().predecessor()) + ".swift"
generateAllFiles.append("_ = { () -> Void in\n\(processFile(path, outputPath: outputPath))\n}()\n")
}
let script = generateAllFiles.joinWithSeparator("")
let scriptPath = (derivedData as NSString).stringByAppendingPathComponent("_preprocessor.sh")
do {
try script.writeToFile(scriptPath, atomically: true, encoding: NSUTF8StringEncoding)
} catch _ {
}
runCommand(scriptPath)