/
FileReader.swift
108 lines (94 loc) · 3.02 KB
/
FileReader.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
import Foundation
final class FileReader {
private let fileURL: URL
private let dryRun: Bool
private let fileManager: FileManager = .init()
// MARK: - Initialization
init(
fileURL: URL,
dryRun: Bool
) {
self.fileURL = fileURL
self.dryRun = dryRun
guard dryRun else { return }
console.info("FileReader: \(fileURL.path)")
}
// MARK: - Internal
func replaceAll(regex: String, with text: String) {
guard var content = readFile() else { return }
var newContent = content
repeat {
content = newContent
newContent = replace(firstRegex: regex, with: text, in: content)
} while content != newContent
writeToFile(text: newContent)
}
func replace(firstRegex: String, with text: String) {
guard var content = readFile() else { return }
content = replace(firstRegex: firstRegex, with: text, in: content)
writeToFile(text: content)
}
func writeToFile(text: String?) {
if fileExists() {
removeFile()
}
createFile(content: text)
}
func readFile() -> String? {
readString(encoding: .utf8)
}
func removeFile() {
guard !dryRun else {
console.info("removeFile")
return
}
do {
try fileManager.removeItem(at: fileURL)
} catch {
fatalError("File removing error: \(error)")
}
}
func fileExists() -> Bool {
return fileManager.fileExists(atPath: fileURL.path)
}
func copy(to: URL) {
guard !dryRun else {
console.info("copyTo: \(to.path)")
return
}
do {
if fileManager.fileExists(atPath: to.path) {
try fileManager.removeItem(at: to)
}
try fileManager.copyItem(at: fileURL, to: to)
} catch {
fatalError("Error occured while copying file: \(error)")
}
}
}
// MARK: - Private
extension FileReader {
private func replace(firstRegex: String, with newText: String, in content: String) -> String {
guard let regexRange = content.range(of: firstRegex, options: .regularExpression) else { return content }
var newContent = content
newContent.removeSubrange(regexRange)
newContent.insert(contentsOf: newText, at: regexRange.lowerBound)
return newContent
}
private func createFile(content: String?) {
guard !dryRun else {
console.info("writeToFile: \(text ?? "<nil>")")
return
}
fileManager.createFile(
atPath: fileURL.path,
contents: content?.data(using: .utf8))
}
private func readString(encoding: String.Encoding) -> String? {
guard let data = readData() else { return nil }
return String(data: data, encoding: encoding)
}
private func readData() -> Data? {
fileManager.contents(atPath: fileURL.path)
}
}