-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathFileUtils.swift
264 lines (210 loc) · 12.5 KB
/
FileUtils.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
//
// public class func swift
// SwiftRuby
//
// Created by John Holdsworth on 30/09/2015.
// Copyright © 2015 John Holdsworth. All rights reserved.
//
// $Id: //depot/SwiftRuby/FileUtils.swift#18 $
//
// Repo: https://github.com/RubyNative/SwiftRuby
//
// See: http://ruby-doc.org/stdlib-2.2.3/libdoc/fileutils/rdoc/FileUtils.html
//
import Darwin
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
switch (lhs, rhs) {
case let (l?, r?):
return l < r
case (nil, _?):
return true
default:
return false
}
}
// FIXME: comparison operators with optionals were removed from the Swift Standard Libary.
// Consider refactoring the code to use the non-optional operators.
fileprivate func > <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
switch (lhs, rhs) {
case let (l?, r?):
return l > r
default:
return rhs < lhs
}
}
public var STATUS = 0
public func systemOK(_ command: string_like, file: StaticString? = #file, line: UInt = #line) -> Bool {
#if os(iOS)
SRNotImplemented("system() depricated since iOS 8", file: file!, line: line)
#else
STATUS = Int(_system(command.to_s))
if STATUS != 0 {
if file != nil {
SRLog("system call '\(command.to_s)' failed", file: file!, line: line)
}
return false
}
STATUS >>= 8
#endif
return true
}
open class FileUtils {
open var pwd: String? {
return Dir.getwd
}
fileprivate class func expand(_ list: array_like) -> String {
return list.to_a.map { "\""+$0.replacingOccurrences(of: "\"", with: "\\\"")+"\"" }
.joined(separator: " ")
}
open class func cd(_ dir: string_like, options: [String]?, file: StaticString = #file, line: UInt = #line) -> Bool {
return Dir.chdir(dir, file: file, line: line)
}
// public class func cd(dir: string_like, options: [String]?, file: StaticString = #file, line: UInt = #line) -> Bool { {|dir| .... }
open class func chmod(_ mode: string_like, _ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("chmod \(mode.to_s) \(expand(list))", file: file, line: line)
}
open class func chmod_R(_ mode: string_like, _ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("chmod -R \(mode.to_s) \(expand(list))", file: file, line: line)
}
open class func chown(_ user: string_like, _ group: string_like?, _ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
let whoto = user.to_s + (group != nil ? ":"+group!.to_s : "")
return systemOK("chown \(whoto) \(expand(list))", file: file, line: line)
}
open class func chown_R(_ user: string_like, _ group: string_like?, _ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
let whoto = user.to_s + (group != nil ? ":"+group!.to_s : "")
return systemOK("chown -R \(whoto) \(expand(list))", file: file, line: line)
}
open class func cmp(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return compare_file(src, dest, options, file: file, line: line)
}
open class func compare_file(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("diff -q \"\(src.to_s)\" \"\(dest.to_s)\" >/dev/null", file: file, line: line)
}
open class func compare_stream(_ a: IO, _ b: IO, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
if let a = a.read(), let b = b.read() {
return a.length == b.length && memcmp(a.bytes, b.bytes, a.length) == 0
}
return false
}
open class func copy(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return cp(src, dest, options, file: file, line: line)
}
open class func copy_entry(_ src: string_like, _ dest: string_like, _ preserve: Bool = false, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return rsync([src.to_s], dest, preserve ? "-rlpogt" : "-rlp", options, file: file, line: line)
}
open class func copy_file(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return cp(src, dest, options, file: file, line: line)
}
open class func copy_stream(_ src: IO, _ dest: IO, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
if let data = src.read() {
dest.write(data)
return true
}
return false
}
open class func cat(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("cat \(expand(list)) >\"\(dir.to_s)\"", file: file, line: line)
}
open class func cp(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("cp \(expand(list)) \"\(dir.to_s)\"", file: file, line: line)
}
open class func cp_r(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("cp -r \(expand(list)) \"\(dir.to_s)\"", file: file, line: line)
}
open class func cp_rf(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("cp -rf \(expand(list)) \"\(dir.to_s)\"", file: file, line: line)
}
open class func identical(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return compare_file(src, dest, options, file: file, line: line)
}
open class func install(_ src: string_like, _ dest: string_like, _ mode: string_like?, options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
let mode = mode != nil ? " -m " + mode!.to_s : ""
return systemOK("install\(mode) \"\(src.to_s)\" \"\(dest.to_s)\"", file: file, line: line)
}
open class func link(_ old: string_like, _ new: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return ln(old, new, options, file: file, line: line)
}
open class func ln(_ list: array_like, _ destdir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("ln \(expand(list)) \"\(destdir.to_s)\"", file: file, line: line)
}
open class func ln_s(_ list: array_like, _ destdir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("ln -s \(expand(list)) \"\(destdir.to_s)\"", file: file, line: line)
}
open class func ln_sf(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("ln -sf \"\(src.to_s)\" \"\(dest.to_s)\"", file: file, line: line)
}
open class func makedirs(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return mkdir_p(list, options, file: file, line: line)
}
open class func mkdir(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("mkdir \(expand(list))", file: file, line: line)
}
open class func mkdir_p(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("mkdir -p \(expand(list))", file: file, line: line)
}
open class func mkpath(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return mkdir_p(list, options, file: file, line: line)
}
open class func mv(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("mv \(expand(list)) \"\(dir.to_s)\"", file: file, line: line)
}
open class func mv_f(_ list: array_like, _ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("mv -f \(expand(list)) \"\(dir.to_s)\"", file: file, line: line)
}
open class func remove_dir(_ dir: string_like, _ force: Bool = false, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return force ? rm_rf(dir, options, file: file, line: line) : rm_r([dir.to_s], options, file: file, line: line)
}
open class func remove_entry(_ dir: string_like, _ force: Bool = false, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return force ? rm_rf(dir, options, file: file, line: line) : rm_r([dir.to_s], options, file: file, line: line)
}
open class func remove_entry_secure(_ dir: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rm -rfP \"\(dir.to_s)\"", file: file, line: line)
}
open class func remove_file(_ path: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return rm([path.to_s], options, file: file, line: line)
}
open class func rm(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rm \(expand(list))", file: file, line: line)
}
open class func rm_f(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rm -f \(expand(list))", file: file, line: line)
}
open class func rm_r(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rm -r \(expand(list))", file: file, line: line)
}
open class func rm_rf(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rm -rf \(expand(list.to_a))", file: file, line: line)
}
open class func rmdir(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rmdir \(expand(list))", file: file, line: line)
}
open class func rmtree(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return rm_rf(list, options, file: file, line: line)
}
open class func safe_unlink(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return rm_f(list, options, file: file, line: line)
}
open class func symlink(_ src: string_like, _ dest: string_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return ln_s(src, dest, options, file: file, line: line)
}
open class func rsync(_ list: array_like, _ dest: string_like, _ args: string_like = "-a", _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("rsync \(args) \(expand(list)) \"\(dest.to_s)\"", file: file, line: line)
}
open class func touch(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("touch \(expand(list))", file: file, line: line)
}
open class func touch_f(_ list: array_like, _ options: [String]? = nil, file: StaticString = #file, line: UInt = #line) -> Bool {
return systemOK("touch -f \(expand(list))", file: file, line: line)
}
open class func uptodate(_ new: string_like, old_list: array_like, file: StaticString = #file, line: UInt = #line) -> Bool {
let new_time = Stat(new, file: nil)?.mtime.to_f ?? 0
for old in old_list.to_a {
if Stat(old, file: file, line: line)?.mtime.to_f > new_time {
return false
}
}
return true
}
}