perennial 0.2.2.2 → 1.0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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