perennial 0.2.2.2 → 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,448 +0,0 @@
1
- require 'fileutils'
2
- require 'pathname'
3
-
4
- RealFile = File
5
- RealFileUtils = FileUtils
6
- RealDir = Dir
7
- RealFileUtils::Dir = RealDir
8
- RealFileUtils::File = RealFile
9
-
10
- module FakeFS
11
- module FileUtils
12
- extend self
13
-
14
- def mkdir_p(path)
15
- FileSystem.add(path, MockDir.new)
16
- end
17
-
18
- def rm(path)
19
- FileSystem.delete(path)
20
- end
21
- alias_method :rm_rf, :rm
22
-
23
- def ln_s(target, path)
24
- raise Errno::EEXIST, path if FileSystem.find(path)
25
- FileSystem.add(path, MockSymlink.new(target))
26
- end
27
-
28
- def cp(src, dest)
29
- dst_file = FileSystem.find(dest)
30
- src_file = FileSystem.find(src)
31
-
32
- if !src_file
33
- raise Errno::ENOENT, src
34
- end
35
-
36
- if File.directory? src_file
37
- raise Errno::EISDIR, src
38
- end
39
-
40
- if dst_file and File.directory?(dst_file)
41
- FileSystem.add(File.join(dest, src), src_file.entry.clone(dst_file))
42
- else
43
- FileSystem.delete(dest)
44
- FileSystem.add(dest, src_file.entry.clone)
45
- end
46
- end
47
-
48
- def cp_r(src, dest)
49
- # This error sucks, but it conforms to the original Ruby
50
- # method.
51
- raise "unknown file type: #{src}" unless dir = FileSystem.find(src)
52
-
53
- new_dir = FileSystem.find(dest)
54
-
55
- if new_dir && !File.directory?(dest)
56
- raise Errno::EEXIST, dest
57
- end
58
-
59
- if !new_dir && !FileSystem.find(dest+'/../')
60
- raise Errno::ENOENT, dest
61
- end
62
-
63
- # This last bit is a total abuse and should be thought hard
64
- # about and cleaned up.
65
- if new_dir
66
- if src[-2..-1] == '/.'
67
- dir.values.each{|f| new_dir[f.name] = f.clone(new_dir) }
68
- else
69
- new_dir[dir.name] = dir.entry.clone(new_dir)
70
- end
71
- else
72
- FileSystem.add(dest, dir.entry.clone)
73
- end
74
- end
75
-
76
- def mv(src, dest)
77
- if target = FileSystem.find(src)
78
- FileSystem.add(dest, target.entry.clone)
79
- FileSystem.delete(src)
80
- else
81
- raise Errno::ENOENT, src
82
- end
83
- end
84
-
85
- def chown(user, group, list, options={})
86
- list = Array(list)
87
- list.each do |f|
88
- unless File.exists?(f)
89
- raise Errno::ENOENT, f
90
- end
91
- end
92
- list
93
- end
94
-
95
- def chown_R(user, group, list, options={})
96
- chown(user, group, list, options={})
97
- end
98
-
99
- def touch(list, options={})
100
- Array(list).each do |f|
101
- directory = File.dirname(f)
102
- # FIXME this explicit check for '.' shouldn't need to happen
103
- if File.exists?(directory) || directory == '.'
104
- FileSystem.add(f, MockFile.new)
105
- else
106
- raise Errno::ENOENT, f
107
- end
108
- end
109
- end
110
- end
111
-
112
- class File
113
- PATH_SEPARATOR = '/'
114
-
115
- def self.join(*parts)
116
- parts * PATH_SEPARATOR
117
- end
118
-
119
- def self.exist?(path)
120
- FileSystem.find(path) || false
121
- end
122
-
123
- class << self
124
- alias_method :exists?, :exist?
125
- end
126
-
127
- def self.directory?(path)
128
- if path.respond_to? :entry
129
- path.entry.is_a? MockDir
130
- else
131
- result = FileSystem.find(path)
132
- result ? result.entry.is_a?(MockDir) : false
133
- end
134
- end
135
-
136
- def self.symlink?(path)
137
- if path.respond_to? :entry
138
- path.is_a? MockSymlink
139
- else
140
- FileSystem.find(path).is_a? MockSymlink
141
- end
142
- end
143
-
144
- def self.file?(path)
145
- if path.respond_to? :entry
146
- path.entry.is_a? MockFile
147
- else
148
- result = FileSystem.find(path)
149
- result ? result.entry.is_a?(MockFile) : false
150
- end
151
- end
152
-
153
- def self.expand_path(*args)
154
- RealFile.expand_path(*args)
155
- end
156
-
157
- def self.basename(*args)
158
- RealFile.basename(*args)
159
- end
160
-
161
- def self.dirname(path)
162
- RealFile.dirname(path)
163
- end
164
-
165
- def self.readlink(path)
166
- symlink = FileSystem.find(path)
167
- FileSystem.find(symlink.target).to_s
168
- end
169
-
170
- def self.open(path, mode='r')
171
- if block_given?
172
- yield new(path, mode)
173
- else
174
- new(path, mode)
175
- end
176
- end
177
-
178
- def self.read(path)
179
- file = new(path)
180
- if file.exists?
181
- file.read
182
- else
183
- raise Errno::ENOENT
184
- end
185
- end
186
-
187
- def self.readlines(path)
188
- read(path).split("\n")
189
- end
190
-
191
- attr_reader :path
192
- def initialize(path, mode = nil)
193
- @path = path
194
- @mode = mode
195
- @file = FileSystem.find(path)
196
- @open = true
197
- end
198
-
199
- def close
200
- @open = false
201
- end
202
-
203
- def read
204
- raise IOError.new('closed stream') unless @open
205
- @file.content
206
- end
207
-
208
- def exists?
209
- @file
210
- end
211
-
212
- def puts(content)
213
- write(content + "\n")
214
- end
215
-
216
- def write(content)
217
- raise IOError.new('closed stream') unless @open
218
-
219
- if !File.exists?(@path)
220
- @file = FileSystem.add(path, MockFile.new)
221
- end
222
-
223
- @file.content += content
224
- end
225
- alias_method :print, :write
226
- alias_method :<<, :write
227
-
228
- def flush; self; end
229
- end
230
-
231
- class Dir
232
- def self.glob(pattern)
233
- if pattern[-1,1] == '*'
234
- blk = proc { |entry| entry.to_s }
235
- else
236
- blk = proc { |entry| entry[1].parent.to_s }
237
- end
238
- (FileSystem.find(pattern) || []).map(&blk).uniq.sort
239
- end
240
-
241
- def self.[](pattern)
242
- glob(pattern)
243
- end
244
-
245
- def self.chdir(dir, &blk)
246
- FileSystem.chdir(dir, &blk)
247
- end
248
- end
249
-
250
- module FileSystem
251
- extend self
252
-
253
- def dir_levels
254
- @dir_levels ||= []
255
- end
256
-
257
- def fs
258
- @fs ||= MockDir.new('.')
259
- end
260
-
261
- def clear
262
- @dir_levels = nil
263
- @fs = nil
264
- end
265
-
266
- def files
267
- fs.values
268
- end
269
-
270
- def find(path)
271
- parts = path_parts(normalize_path(path))
272
-
273
- target = parts[0...-1].inject(fs) do |dir, part|
274
- dir[part] || {}
275
- end
276
-
277
- case parts.last
278
- when '*'
279
- target.values
280
- else
281
- target[parts.last]
282
- end
283
- end
284
-
285
- def add(path, object=MockDir.new)
286
- parts = path_parts(normalize_path(path))
287
-
288
- d = parts[0...-1].inject(fs) do |dir, part|
289
- dir[part] ||= MockDir.new(part, dir)
290
- end
291
-
292
- object.name = parts.last
293
- object.parent = d
294
- d[parts.last] ||= object
295
- end
296
-
297
- # copies directories and files from the real filesystem
298
- # into our fake one
299
- def clone(path)
300
- path = File.expand_path(path)
301
- pattern = File.join(path, '**', '*')
302
- files = RealFile.file?(path) ? [path] : [path] + RealDir.glob(pattern, RealFile::FNM_DOTMATCH)
303
-
304
- files.each do |f|
305
- if RealFile.file?(f)
306
- FileUtils.mkdir_p(File.dirname(f))
307
- File.open(f, 'w') do |g|
308
- g.print RealFile.open(f){|h| h.read }
309
- end
310
- elsif RealFile.directory?(f)
311
- FileUtils.mkdir_p(f)
312
- elsif RealFile.symlink?(f)
313
- FileUtils.ln_s()
314
- end
315
- end
316
- end
317
-
318
- def delete(path)
319
- if dir = FileSystem.find(path)
320
- dir.parent.delete(dir.name)
321
- end
322
- end
323
-
324
- def chdir(dir, &blk)
325
- new_dir = find(dir)
326
- dir_levels.push dir if blk
327
-
328
- raise Errno::ENOENT, dir unless new_dir
329
-
330
- dir_levels.push dir if !blk
331
- blk.call if blk
332
- ensure
333
- dir_levels.pop if blk
334
- end
335
-
336
- def path_parts(path)
337
- path.split(File::PATH_SEPARATOR).reject { |part| part.empty? }
338
- end
339
-
340
- def normalize_path(path)
341
- if Pathname.new(path).absolute?
342
- File.expand_path(path)
343
- else
344
- parts = dir_levels + [path]
345
- File.expand_path(File.join(*parts))
346
- end
347
- end
348
-
349
- def current_dir
350
- find(normalize_path('.'))
351
- end
352
- end
353
-
354
- class MockFile
355
- attr_accessor :name, :parent, :content
356
-
357
- def initialize(name = nil, parent = nil)
358
- @name = name
359
- @parent = parent
360
- @content = ''
361
- end
362
-
363
- def clone(parent = nil)
364
- clone = super()
365
- clone.parent = parent if parent
366
- clone
367
- end
368
-
369
- def entry
370
- self
371
- end
372
-
373
- def inspect
374
- "(MockFile name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{content.size})"
375
- end
376
-
377
- def to_s
378
- File.join(parent.to_s, name)
379
- end
380
- end
381
-
382
- class MockDir < Hash
383
- attr_accessor :name, :parent
384
-
385
- def initialize(name = nil, parent = nil)
386
- @name = name
387
- @parent = parent
388
- end
389
-
390
- def entry
391
- self
392
- end
393
-
394
- def inspect
395
- "(MockDir name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{size})"
396
- end
397
-
398
- def clone(parent = nil)
399
- clone = Marshal.load(Marshal.dump(self))
400
- clone.each do |key, value|
401
- value.parent = clone
402
- end
403
- clone.parent = parent if parent
404
- clone
405
- end
406
-
407
- def to_s
408
- if parent && parent.to_s != '.'
409
- File.join(parent.to_s, name)
410
- elsif parent && parent.to_s == '.'
411
- "#{File::PATH_SEPARATOR}#{name}"
412
- else
413
- name
414
- end
415
- end
416
- end
417
-
418
- class MockSymlink
419
- attr_accessor :name, :target
420
- alias_method :to_s, :name
421
-
422
- def initialize(target)
423
- @target = target
424
- end
425
-
426
- def inspect
427
- "symlink(#{target.split('/').last})"
428
- end
429
-
430
- def entry
431
- FileSystem.find(target)
432
- end
433
-
434
- def method_missing(*args, &block)
435
- entry.send(*args, &block)
436
- end
437
- end
438
- end
439
-
440
- Object.class_eval do
441
- remove_const(:Dir)
442
- remove_const(:File)
443
- remove_const(:FileUtils)
444
- end
445
-
446
- File = FakeFS::File
447
- FileUtils = FakeFS::FileUtils
448
- Dir = FakeFS::Dir