-
Notifications
You must be signed in to change notification settings - Fork 0
/
rename.swift
170 lines (141 loc) · 5.66 KB
/
rename.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
#!/usr/bin/env swift
//
// rename.swift
// XcodeProjectRenamer
//
// Created by Rob Mulder 19-08-2019.
// Copyright © 2019 Rob Mulder. All rights reserved.
//
import Foundation
class XcodeProjectRenamer: NSObject {
// MARK: - Constants
struct Color {
static let Black = "\u{001B}[0;30m"
static let Red = "\u{001B}[0;31m"
static let Green = "\u{001B}[0;32m"
static let Yellow = "\u{001B}[0;33m"
static let Blue = "\u{001B}[0;34m"
static let Magenta = "\u{001B}[0;35m"
static let Cyan = "\u{001B}[0;36m"
static let White = "\u{001B}[0;37m"
static let DarkGray = "\u{001B}[1;30m"
}
// MARK: - Properties
let fileManager = FileManager.default
var processedPaths = [String]()
let oldName: String
let newName: String
// MARK: - Init
init(oldName: String, newName: String) {
self.oldName = oldName
self.newName = newName
}
// MARK: - API
func run() {
print("\n\(Color.Green)------------------------------------------")
print("\(Color.Green)Rename Xcode Project from [\(oldName)] to [\(newName)]")
print("\(Color.Green)Current Path: \(fileManager.currentDirectoryPath)")
print("\(Color.Green)------------------------------------------\n")
let currentPath = fileManager.currentDirectoryPath
if validatePath(currentPath) {
enumeratePath(currentPath)
print("\(Color.Green) \(shell("pod update"))")
} else {
print("\(Color.Red)Xcode project or workspace with name: [\(oldName)] is not found at current path.")
}
print("\n\(Color.Green)------------------------------------------")
print("\(Color.Green)Xcode Project Rename Finished!")
print("\(Color.Green)------------------------------------------\n")
}
// MARK: - Helpers
private func validatePath(_ path: String) -> Bool {
let projectPath = path.appending("/\(oldName).xcodeproj")
let workspacePath = path.appending("/\(oldName).xcworkspace")
let isValid = fileManager.fileExists(atPath: projectPath) || fileManager.fileExists(atPath: workspacePath)
return isValid
}
private func enumeratePath(_ path: String) {
let enumerator = fileManager.enumerator(atPath: path)
while let element = enumerator?.nextObject() as? String {
let itemPath = path.appending("/\(element)")
if !processedPaths.contains(itemPath) && !shouldSkip(element) {
processPath(itemPath)
}
}
}
private func processPath(_ path: String) {
print("\(Color.DarkGray)Processing: \(path)")
var isDir: ObjCBool = false
if fileManager.fileExists(atPath: path, isDirectory: &isDir) {
if isDir.boolValue {
enumeratePath(path)
} else {
updateContentsOfFile(atPath: path)
}
renameItem(atPath: path)
}
processedPaths.append(path)
}
private func shouldSkip(_ element: String) -> Bool {
guard
!element.hasPrefix("."),
!element.contains(".DS_Store"),
!element.contains("Carthage"),
!element.contains("Pods"),
!element.contains("fastlane")
else { return true }
let fileExtension = URL(fileURLWithPath: element).pathExtension
switch fileExtension {
case "appiconset", "json", "png", "xcuserstate":
return true
default:
return false
}
}
private func updateContentsOfFile(atPath path: String) {
do {
let oldContent = try String(contentsOfFile: path, encoding: .utf8)
if oldContent.contains(oldName) {
let newContent = oldContent.replacingOccurrences(of: oldName, with: newName)
try newContent.write(toFile: path, atomically: true, encoding: .utf8)
print("\(Color.Blue)-- Updated: \(path)")
}
} catch {
print("\(Color.Red)Error while updating file: \(error.localizedDescription)\n")
}
}
private func renameItem(atPath path: String) {
do {
let oldItemName = URL(fileURLWithPath: path).lastPathComponent
if oldItemName.contains(oldName) {
let newItemName = oldItemName.replacingOccurrences(of: oldName, with: newName)
let directoryURL = URL(fileURLWithPath: path).deletingLastPathComponent()
let newPath = directoryURL.appendingPathComponent(newItemName).path
try fileManager.moveItem(atPath: path, toPath: newPath)
print("\(Color.Magenta)-- Renamed: \(oldItemName) -> \(newItemName)")
}
} catch {
print("\(Color.Red)Error while renaming file: \(error.localizedDescription)")
}
}
func shell(_ command: String) -> String {
let task = Process()
task.launchPath = "/bin/bash"
task.arguments = ["-c", command]
let pipe = Pipe()
task.standardOutput = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
return output
}
}
let arguments = CommandLine.arguments
if arguments.count == 3 {
let oldName = arguments[1]
let newName = arguments[2].replacingOccurrences(of: " ", with: "")
let xpr = XcodeProjectRenamer(oldName: oldName, newName: newName)
xpr.run()
} else {
print("\(XcodeProjectRenamer.Color.Red)Invalid number of arguments! Expected OLD and NEW project name.")
}