-
Notifications
You must be signed in to change notification settings - Fork 0
/
installer.swift
172 lines (141 loc) · 6.15 KB
/
installer.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env xcrun swift
import Foundation
var TPLProjectName = ""
let arguments: Array = CommandLine.arguments
let templateName = arguments[2]
switch templateName {
case "Template":
TPLProjectName = "TPLProjectName"
break
case "CLT_GenericTemplate":
TPLProjectName = "CLTProjectName"
break
case "macOS_GenericTemplate":
TPLProjectName = "GRTPLProjectName"
break
default:
break
}
let TPLAuthor = "TPLAuthor"
var TPLBundleIdentifier = "TPLBundleIdentifier"
let TPLAuthorWebsite = "TPLAuthorWebsite"
let TPLUserName = "TPLUserName"
let TPLOrganizationName = "TPLOrganizationName"
let TPLCopyright = "Copyright © 2023"
var projectName = "SampleProject"
var bundleIdentifier = "com.HungQ.SampleProject"
var author = "Hung Q."
var authorWebsite = "https://htq287.com"
var userName = "hungtq"
var organizationName = "Hung Q."
var copyright = "Copyright © 2023"
var out = "Out"
let fileManager = FileManager.default
let runScriptPathURL = NSURL(fileURLWithPath: fileManager.currentDirectoryPath, isDirectory: true)
let currentScriptPathURL = NSURL(fileURLWithPath: NSURL(fileURLWithPath: CommandLine.arguments[0], relativeTo: runScriptPathURL as URL).deletingLastPathComponent!.path, isDirectory: true)
let projectTemplateForlderURL = NSURL(fileURLWithPath: templateName, relativeTo: currentScriptPathURL as URL)
var newProjectFolderPath = ""
let ignoredFiles = [".DS_Store", "UserInterfaceState.xcuserstate", "Pods", "Carthage", "build", "ed25519_sign", "background.png", "assets.sketch", "launch-screen.sketch", "default.profraw", "app-icon.sketch"]
extension NSURL {
var fileName: String {
var fileName: AnyObject?
try! getResourceValue(&fileName, forKey: URLResourceKey.nameKey)
return fileName as! String
}
var isDirectory: Bool {
var isDirectory: AnyObject?
try! getResourceValue(&isDirectory, forKey: URLResourceKey.isDirectoryKey)
return isDirectory as! Bool
}
func renameIfNeeded() {
if let _ = fileName.range(of: TPLProjectName) {
let renamedFileName = fileName.replacingOccurrences(of: TPLProjectName, with: projectName)
try! FileManager.default.moveItem(at: self as URL, to: NSURL(fileURLWithPath: renamedFileName, relativeTo: deletingLastPathComponent) as URL)
}
}
func updateContent() {
guard let path = path, let content = try? String(contentsOfFile: path, encoding: String.Encoding.utf8) else {
print("ERROR READING: \(self)")
return
}
var newContent = content.replacingOccurrences(of: TPLProjectName, with: projectName)
newContent = newContent.replacingOccurrences(of: TPLBundleIdentifier, with: bundleIdentifier)
newContent = newContent.replacingOccurrences(of: TPLAuthor, with: author)
newContent = newContent.replacingOccurrences(of: TPLUserName, with: userName)
newContent = newContent.replacingOccurrences(of: TPLAuthorWebsite, with: authorWebsite)
newContent = newContent.replacingOccurrences(of: TPLOrganizationName, with: organizationName)
newContent = newContent.replacingOccurrences(of: TPLCopyright, with: copyright)
try! newContent.write(to: self as URL, atomically: true, encoding: String.Encoding.utf8)
}
}
func printLogs<T>(_ message: T) {
print("Logs: \(message)")
}
func printErrorLogsAndExit<T>(logs message: T) {
print("ErrorLogs: \(message)")
exit(1)
}
func checkThatProjectForlderCanBeCreated(projectURL: NSURL){
var isDirectory: ObjCBool = true
if fileManager.fileExists(atPath: projectURL.path!, isDirectory: &isDirectory) {
printErrorLogsAndExit(logs: "\(String(describing:projectName)) \(String(describing:(isDirectory.boolValue ? "folder already" : "file"))) exists in \(String(describing:runScriptPathURL.path)) directory, please delete it and try again")
}
}
func shell(args: String...) -> (output: String, exitCode: Int32) {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.currentDirectoryPath = newProjectFolderPath
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(decoding: data, as: UTF8.self)
return (output, task.terminationStatus)
}
func prompt(_ message: String, _ defaultValue: String) -> String {
print("\n> \(message) (or press Enter to use \(defaultValue))")
let line = readLine()
return line == nil || line == "" ? defaultValue : line!
}
projectName = prompt("Project Name", projectName)
bundleIdentifier = prompt("Bundle Identifier", bundleIdentifier)
author = prompt("Author", author)
organizationName = prompt("Organizer", organizationName)
copyright = prompt("Copyright", copyright)
let out_path = out + "/" + projectName;
// create output folder
let putFolderURL = NSURL(fileURLWithPath: out, relativeTo: runScriptPathURL as URL);
do {
try fileManager.createDirectory(atPath: putFolderURL.path!, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error.localizedDescription)
}
// Check if folder already exists
let newProjectFolderURL = NSURL(fileURLWithPath: out_path, relativeTo: runScriptPathURL as URL)
newProjectFolderPath = newProjectFolderURL.path!
checkThatProjectForlderCanBeCreated(projectURL: newProjectFolderURL)
// Copy template folder to a new folder
do {
try fileManager.copyItem(at: projectTemplateForlderURL as URL, to: newProjectFolderURL as URL)
} catch let error as NSError {
printErrorLogsAndExit(logs: error)
}
// rename files/Folders and update content
let enumerator = fileManager.enumerator(at: newProjectFolderURL as URL, includingPropertiesForKeys: [.nameKey, .isDirectoryKey], options: [], errorHandler: nil)!
var directories = [NSURL]()
print("\nCreating \(projectName) ...")
while let fileURL = enumerator.nextObject() as? NSURL {
guard !ignoredFiles.contains(fileURL.fileName) else { continue }
if fileURL.isDirectory {
directories.append(fileURL)
}
else {
fileURL.updateContent()
fileURL.renameIfNeeded()
}
}
for fileURL in directories.reversed() {
fileURL.renameIfNeeded()
}