fakefs 0.13.3 → 0.14.0
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.
- checksums.yaml +4 -4
- data/lib/fakefs/base.rb +6 -8
- data/lib/fakefs/dir.rb +69 -74
- data/lib/fakefs/fake/dir.rb +2 -2
- data/lib/fakefs/fake/file.rb +3 -6
- data/lib/fakefs/fake/symlink.rb +2 -2
- data/lib/fakefs/file.rb +129 -138
- data/lib/fakefs/file_system.rb +26 -26
- data/lib/fakefs/fileutils.rb +55 -59
- data/lib/fakefs/globber.rb +11 -9
- data/lib/fakefs/kernel.rb +1 -2
- data/lib/fakefs/pathname.rb +882 -879
- data/lib/fakefs/safe.rb +1 -1
- data/lib/fakefs/version.rb +1 -1
- metadata +25 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31db99cb7de1e5f339b6c41d82f61680c648e36f319e5d1973299a2b3effe347
|
4
|
+
data.tar.gz: b18014abd60aa12ba08bc037164cec52ddc005c1a780d17ed6a7a6e9906af399
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 814c3fe4b2eb600b674adbb0d903550a3a3fdf1a6209660b0f9dea7f4d90657981e2078e5e584aca8972c738fbddd73f39b20c3704970a368ee3b17a174e2d2c
|
7
|
+
data.tar.gz: 70892ade1983519bdb0900005dadd09e1d620ed457754c02bc12f5505dac61a74d8dfdeca8d801c22db4d2c24445fbed9b6cad343d16f8beb87867c1692a0a1c
|
data/lib/fakefs/base.rb
CHANGED
@@ -8,10 +8,8 @@ def RealPathname(*args)
|
|
8
8
|
RealPathname.new(*args)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
Pathname.new(*args)
|
14
|
-
end
|
11
|
+
def Pathname(*args)
|
12
|
+
Pathname.new(*args)
|
15
13
|
end
|
16
14
|
|
17
15
|
# FakeFS module
|
@@ -28,13 +26,13 @@ module FakeFS
|
|
28
26
|
remove_const(:File)
|
29
27
|
remove_const(:FileTest)
|
30
28
|
remove_const(:FileUtils)
|
31
|
-
remove_const(:Pathname)
|
29
|
+
remove_const(:Pathname)
|
32
30
|
|
33
31
|
const_set(:Dir, FakeFS::Dir)
|
34
32
|
const_set(:File, FakeFS::File)
|
35
33
|
const_set(:FileUtils, FakeFS::FileUtils)
|
36
34
|
const_set(:FileTest, FakeFS::FileTest)
|
37
|
-
const_set(:Pathname, FakeFS::Pathname)
|
35
|
+
const_set(:Pathname, FakeFS::Pathname)
|
38
36
|
::FakeFS::Kernel.hijack!
|
39
37
|
end
|
40
38
|
|
@@ -50,13 +48,13 @@ module FakeFS
|
|
50
48
|
remove_const(:File)
|
51
49
|
remove_const(:FileTest)
|
52
50
|
remove_const(:FileUtils)
|
53
|
-
remove_const(:Pathname)
|
51
|
+
remove_const(:Pathname)
|
54
52
|
|
55
53
|
const_set(:Dir, RealDir)
|
56
54
|
const_set(:File, RealFile)
|
57
55
|
const_set(:FileTest, RealFileTest)
|
58
56
|
const_set(:FileUtils, RealFileUtils)
|
59
|
-
const_set(:Pathname, RealPathname)
|
57
|
+
const_set(:Pathname, RealPathname)
|
60
58
|
::FakeFS::Kernel.unhijack!
|
61
59
|
end
|
62
60
|
|
data/lib/fakefs/dir.rb
CHANGED
@@ -7,7 +7,7 @@ module FakeFS
|
|
7
7
|
attr_reader :path
|
8
8
|
|
9
9
|
def self._check_for_valid_file(path)
|
10
|
-
|
10
|
+
raise Errno::ENOENT, path unless FileSystem.find(path)
|
11
11
|
end
|
12
12
|
|
13
13
|
def initialize(string)
|
@@ -45,7 +45,7 @@ module FakeFS
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def read
|
48
|
-
|
48
|
+
raise IOError, 'closed directory' unless @pointer
|
49
49
|
entry = @contents[@pointer]
|
50
50
|
@pointer += 1
|
51
51
|
entry_to_relative_path(entry) if entry
|
@@ -56,7 +56,7 @@ module FakeFS
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def seek(integer)
|
59
|
-
|
59
|
+
raise IOError, 'closed directory' if @pointer.nil?
|
60
60
|
@pointer = integer
|
61
61
|
@contents[integer]
|
62
62
|
end
|
@@ -74,12 +74,12 @@ module FakeFS
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def self.chroot(_string)
|
77
|
-
|
77
|
+
raise NotImplementedError
|
78
78
|
end
|
79
79
|
|
80
80
|
def self.delete(string)
|
81
81
|
_check_for_valid_file(string)
|
82
|
-
|
82
|
+
raise Errno::ENOTEMPTY, string unless FileSystem.find(string).empty?
|
83
83
|
|
84
84
|
FileSystem.delete(string)
|
85
85
|
end
|
@@ -91,12 +91,12 @@ module FakeFS
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def self.children(dirname, opts = {})
|
94
|
-
entries(dirname, opts) -
|
94
|
+
entries(dirname, opts) - ['.', '..']
|
95
95
|
end
|
96
96
|
|
97
97
|
def self.each_child(dirname, &_block)
|
98
98
|
Dir.open(dirname) do |file|
|
99
|
-
next if
|
99
|
+
next if ['.', '..'].include?(file)
|
100
100
|
yield file
|
101
101
|
end
|
102
102
|
end
|
@@ -140,10 +140,8 @@ module FakeFS
|
|
140
140
|
block_given? ? files.each { |file| block.call(file) } : files
|
141
141
|
end
|
142
142
|
|
143
|
-
|
144
|
-
|
145
|
-
RealDir.home(user)
|
146
|
-
end
|
143
|
+
def self.home(user = nil)
|
144
|
+
RealDir.home(user)
|
147
145
|
end
|
148
146
|
|
149
147
|
def self.mkdir(string, _integer = 0)
|
@@ -166,70 +164,60 @@ module FakeFS
|
|
166
164
|
FileSystem.current_dir.to_s
|
167
165
|
end
|
168
166
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
module_function
|
167
|
+
# Tmpname module
|
168
|
+
module Tmpname # :nodoc:
|
169
|
+
module_function
|
173
170
|
|
174
|
-
|
175
|
-
|
176
|
-
|
171
|
+
def tmpdir
|
172
|
+
Dir.tmpdir
|
173
|
+
end
|
177
174
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
"unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
189
|
-
end
|
190
|
-
t = Time.now.strftime('%Y%m%d')
|
191
|
-
path = "#{prefix}#{t}-#{$PID}-#{rand(0x100000000).to_s(36)}"
|
192
|
-
path << "-#{n}" if n
|
193
|
-
path << suffix
|
175
|
+
def make_tmpname(prefix_suffix, suffix)
|
176
|
+
case prefix_suffix
|
177
|
+
when String
|
178
|
+
prefix = prefix_suffix
|
179
|
+
suffix = ''
|
180
|
+
when Array
|
181
|
+
prefix = prefix_suffix[0]
|
182
|
+
suffix = prefix_suffix[1]
|
183
|
+
else
|
184
|
+
raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
194
185
|
end
|
186
|
+
t = Time.now.strftime('%Y%m%d')
|
187
|
+
path = "#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
|
188
|
+
path << "-#{suffix}" if suffix
|
189
|
+
path << suffix
|
190
|
+
end
|
195
191
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
210
|
-
n = nil
|
211
|
-
begin
|
212
|
-
path = File.join(tmpdir, make_tmpname(basename, n))
|
213
|
-
yield(path, n, *opts)
|
214
|
-
rescue Errno::EEXIST
|
215
|
-
n ||= 0
|
216
|
-
n += 1
|
217
|
-
retry if !max_try || n < max_try
|
218
|
-
raise "cannot generate temporary name using `#{basename}' " \
|
219
|
-
"under `#{tmpdir}'"
|
220
|
-
end
|
221
|
-
path
|
192
|
+
def create(basename, *rest)
|
193
|
+
if (opts = Hash.try_convert(rest[-1]))
|
194
|
+
opts = opts.dup if rest.pop.equal?(opts)
|
195
|
+
max_try = opts.delete(:max_try)
|
196
|
+
opts = [opts]
|
197
|
+
else
|
198
|
+
opts = []
|
199
|
+
end
|
200
|
+
tmpdir, = *rest
|
201
|
+
if $SAFE > 0 && tmpdir.tainted?
|
202
|
+
tmpdir = '/tmp'
|
203
|
+
else
|
204
|
+
tmpdir ||= self.tmpdir
|
222
205
|
end
|
206
|
+
n = nil
|
207
|
+
begin
|
208
|
+
path = File.join(tmpdir, make_tmpname(basename, n))
|
209
|
+
yield(path, n, *opts)
|
210
|
+
rescue Errno::EEXIST
|
211
|
+
n ||= 0
|
212
|
+
n += 1
|
213
|
+
retry if !max_try || n < max_try
|
214
|
+
raise "cannot generate temporary name using `#{basename}' " \
|
215
|
+
"under `#{tmpdir}'"
|
216
|
+
end
|
217
|
+
path
|
223
218
|
end
|
224
219
|
end
|
225
220
|
|
226
|
-
private
|
227
|
-
|
228
|
-
def entry_to_relative_path(entry)
|
229
|
-
filename = entry.to_s
|
230
|
-
filename.start_with?("#{path}/") ? filename[path.size + 1..-1] : filename
|
231
|
-
end
|
232
|
-
|
233
221
|
# This code has been borrowed from Rubinius
|
234
222
|
def self.mktmpdir(prefix_suffix = nil, tmpdir = nil)
|
235
223
|
case prefix_suffix
|
@@ -243,17 +231,17 @@ module FakeFS
|
|
243
231
|
prefix = prefix_suffix[0]
|
244
232
|
suffix = prefix_suffix[1]
|
245
233
|
else
|
246
|
-
|
234
|
+
raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
247
235
|
end
|
248
236
|
|
249
237
|
t = Time.now.strftime('%Y%m%d')
|
250
238
|
n = nil
|
251
239
|
|
252
240
|
begin
|
253
|
-
path = "#{tmpdir}/#{prefix}#{t}-#{
|
241
|
+
path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
|
254
242
|
path << "-#{n}" if n
|
255
243
|
path << suffix
|
256
|
-
mkdir(path,
|
244
|
+
mkdir(path, 0o700)
|
257
245
|
rescue Errno::EEXIST
|
258
246
|
n ||= 0
|
259
247
|
n += 1
|
@@ -276,11 +264,18 @@ module FakeFS
|
|
276
264
|
end
|
277
265
|
end
|
278
266
|
|
267
|
+
private
|
268
|
+
|
269
|
+
def entry_to_relative_path(entry)
|
270
|
+
filename = entry.to_s
|
271
|
+
filename.start_with?("#{path}/") ? filename[path.size + 1..-1] : filename
|
272
|
+
end
|
273
|
+
|
279
274
|
class << self
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
275
|
+
alias getwd pwd
|
276
|
+
alias rmdir delete
|
277
|
+
alias unlink delete
|
278
|
+
alias exist? exists?
|
284
279
|
end
|
285
280
|
end
|
286
281
|
end
|
data/lib/fakefs/fake/dir.rb
CHANGED
@@ -10,7 +10,7 @@ module FakeFS
|
|
10
10
|
@ctime = Time.now
|
11
11
|
@mtime = @ctime
|
12
12
|
@atime = @ctime
|
13
|
-
@mode =
|
13
|
+
@mode = 0o100000 + (0o777 - File.umask)
|
14
14
|
@uid = Process.uid
|
15
15
|
@gid = Process.gid
|
16
16
|
@content = ''
|
@@ -54,7 +54,7 @@ module FakeFS
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def matches(pattern)
|
57
|
-
@entries.
|
57
|
+
@entries.select { |k, _v| pattern =~ k }.values
|
58
58
|
end
|
59
59
|
|
60
60
|
def [](name)
|
data/lib/fakefs/fake/file.rb
CHANGED
@@ -7,11 +7,8 @@ module FakeFS
|
|
7
7
|
# Inode class
|
8
8
|
class Inode
|
9
9
|
def initialize(file_owner)
|
10
|
-
|
11
|
-
@
|
12
|
-
@content = ''.encode(
|
13
|
-
Encoding.default_external) if ''.respond_to?(:encode)
|
14
|
-
@links = [file_owner]
|
10
|
+
@content = ''.encode(Encoding.default_external)
|
11
|
+
@links = [file_owner]
|
15
12
|
end
|
16
13
|
|
17
14
|
attr_accessor :content
|
@@ -41,7 +38,7 @@ module FakeFS
|
|
41
38
|
@mtime = @ctime
|
42
39
|
@atime = @ctime
|
43
40
|
@birthtime = @ctime
|
44
|
-
@mode =
|
41
|
+
@mode = 0o100000 + (0o666 - File.umask)
|
45
42
|
@uid = Process.uid
|
46
43
|
@gid = Process.gid
|
47
44
|
end
|
data/lib/fakefs/fake/symlink.rb
CHANGED
@@ -23,13 +23,13 @@ module FakeFS
|
|
23
23
|
File.join(parent.to_s, name)
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def respond_to_missing?(method, include_private = false)
|
27
27
|
entry.respond_to?(method, include_private)
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
-
def method_missing(*args, &block)
|
32
|
+
def method_missing(*args, &block) # rubocop:disable Style/MethodMissingSuper
|
33
33
|
entry.send(*args, &block)
|
34
34
|
end
|
35
35
|
end
|
data/lib/fakefs/file.rb
CHANGED
@@ -14,16 +14,18 @@ module FakeFS
|
|
14
14
|
|
15
15
|
FILE_CREATION_MODES = (MODES - [READ_ONLY, READ_WRITE]).freeze
|
16
16
|
|
17
|
-
MODE_BITMASK =
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
MODE_BITMASK = (
|
18
|
+
RealFile::RDONLY |
|
19
|
+
RealFile::WRONLY |
|
20
|
+
RealFile::RDWR |
|
21
|
+
RealFile::APPEND |
|
22
|
+
RealFile::CREAT |
|
23
|
+
RealFile::EXCL |
|
24
|
+
RealFile::NONBLOCK |
|
25
|
+
RealFile::TRUNC |
|
26
|
+
(RealFile.const_defined?(:NOCTTY) ? RealFile::NOCTTY : 0) |
|
27
|
+
(RealFile.const_defined?(:SYNC) ? RealFile::SYNC : 0)
|
28
|
+
)
|
27
29
|
|
28
30
|
FILE_CREATION_BITMASK = RealFile::CREAT
|
29
31
|
|
@@ -49,11 +51,11 @@ module FakeFS
|
|
49
51
|
end
|
50
52
|
|
51
53
|
class << self
|
52
|
-
|
54
|
+
alias exists? exist?
|
53
55
|
|
54
56
|
# Assuming that everyone can read and write files
|
55
|
-
|
56
|
-
|
57
|
+
alias readable? exist?
|
58
|
+
alias writable? exist?
|
57
59
|
|
58
60
|
# Assume nothing is sticky.
|
59
61
|
def sticky?(_path)
|
@@ -65,7 +67,7 @@ module FakeFS
|
|
65
67
|
if exists?(path)
|
66
68
|
FileSystem.find(path).mtime
|
67
69
|
else
|
68
|
-
|
70
|
+
raise Errno::ENOENT
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
@@ -73,7 +75,7 @@ module FakeFS
|
|
73
75
|
if exists?(path)
|
74
76
|
FileSystem.find(path).ctime
|
75
77
|
else
|
76
|
-
|
78
|
+
raise Errno::ENOENT
|
77
79
|
end
|
78
80
|
end
|
79
81
|
|
@@ -81,7 +83,7 @@ module FakeFS
|
|
81
83
|
if exists?(path)
|
82
84
|
FileSystem.find(path).atime
|
83
85
|
else
|
84
|
-
|
86
|
+
raise Errno::ENOENT
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
@@ -91,7 +93,7 @@ module FakeFS
|
|
91
93
|
FileSystem.find(path).atime = atime
|
92
94
|
FileSystem.find(path).mtime = mtime
|
93
95
|
else
|
94
|
-
|
96
|
+
raise Errno::ENOENT
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -112,7 +114,7 @@ module FakeFS
|
|
112
114
|
|
113
115
|
if RUBY_VERSION >= '2.4'
|
114
116
|
class << self
|
115
|
-
|
117
|
+
alias empty? zero?
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
@@ -169,12 +171,12 @@ module FakeFS
|
|
169
171
|
|
170
172
|
def self.read(path, *args)
|
171
173
|
options = args[-1].is_a?(Hash) ? args.pop : {}
|
172
|
-
length = args.
|
173
|
-
offset = args.
|
174
|
+
length = args.empty? ? nil : args.shift
|
175
|
+
offset = args.empty? ? 0 : args.shift
|
174
176
|
file = new(path, options)
|
175
177
|
|
176
|
-
|
177
|
-
|
178
|
+
raise Errno::ENOENT unless file.exists?
|
179
|
+
raise Errno::EISDIR, path if directory?(path)
|
178
180
|
|
179
181
|
FileSystem.find(path).atime = Time.now
|
180
182
|
file.seek(offset)
|
@@ -187,7 +189,7 @@ module FakeFS
|
|
187
189
|
FileSystem.find(path).atime = Time.now
|
188
190
|
file.readlines
|
189
191
|
else
|
190
|
-
|
192
|
+
raise Errno::ENOENT
|
191
193
|
end
|
192
194
|
end
|
193
195
|
|
@@ -201,17 +203,17 @@ module FakeFS
|
|
201
203
|
file.each_line(*args)
|
202
204
|
end
|
203
205
|
else
|
204
|
-
|
206
|
+
raise Errno::ENOENT
|
205
207
|
end
|
206
208
|
end
|
207
209
|
|
208
210
|
def self.rename(source, dest)
|
209
211
|
if directory?(source) && file?(dest)
|
210
|
-
|
212
|
+
raise Errno::ENOTDIR, "#{source} or #{dest}"
|
211
213
|
elsif file?(source) && directory?(dest)
|
212
|
-
|
214
|
+
raise Errno::EISDIR, "#{source} or #{dest}"
|
213
215
|
elsif !exist?(dirname(dest))
|
214
|
-
|
216
|
+
raise Errno::ENOENT, "#{source} or #{dest}"
|
215
217
|
end
|
216
218
|
|
217
219
|
if (target = FileSystem.find(source))
|
@@ -223,16 +225,16 @@ module FakeFS
|
|
223
225
|
|
224
226
|
FileSystem.delete(source)
|
225
227
|
else
|
226
|
-
|
228
|
+
raise Errno::ENOENT, "#{source} or #{dest}"
|
227
229
|
end
|
228
230
|
|
229
231
|
0
|
230
232
|
end
|
231
233
|
|
232
234
|
def self.link(source, dest)
|
233
|
-
|
234
|
-
|
235
|
-
|
235
|
+
raise Errno::EPERM, "#{source} or #{dest}" if directory?(source)
|
236
|
+
raise Errno::ENOENT, "#{source} or #{dest}" unless exists?(source)
|
237
|
+
raise Errno::EEXIST, "#{source} or #{dest}" if exists?(dest)
|
236
238
|
|
237
239
|
source = FileSystem.find(source)
|
238
240
|
dest = FileSystem.add(dest, source.entry.clone)
|
@@ -243,7 +245,7 @@ module FakeFS
|
|
243
245
|
|
244
246
|
def self.delete(*file_names)
|
245
247
|
file_names.each do |file_name|
|
246
|
-
|
248
|
+
raise Errno::ENOENT, file_name unless exists?(file_name)
|
247
249
|
|
248
250
|
FileUtils.rm(file_name)
|
249
251
|
end
|
@@ -252,7 +254,7 @@ module FakeFS
|
|
252
254
|
end
|
253
255
|
|
254
256
|
class << self
|
255
|
-
|
257
|
+
alias unlink delete
|
256
258
|
end
|
257
259
|
|
258
260
|
def self.symlink(source, dest)
|
@@ -272,7 +274,7 @@ module FakeFS
|
|
272
274
|
end
|
273
275
|
|
274
276
|
def self.chmod(mode_int, filename)
|
275
|
-
FileSystem.find(filename).mode =
|
277
|
+
FileSystem.find(filename).mode = 0o100000 + mode_int
|
276
278
|
end
|
277
279
|
|
278
280
|
# Not exactly right, returns true if the file is chmod +x for owner. In the
|
@@ -280,20 +282,18 @@ module FakeFS
|
|
280
282
|
def self.executable?(filename)
|
281
283
|
file = FileSystem.find(filename)
|
282
284
|
return false unless file
|
283
|
-
(file.mode -
|
285
|
+
(file.mode - 0o100000) & 0o100 != 0
|
284
286
|
end
|
285
287
|
|
286
288
|
def self.chown(owner_int, group_int, filename)
|
287
289
|
file = FileSystem.find(filename)
|
288
290
|
|
289
291
|
if owner_int && owner_int != -1
|
290
|
-
owner_int.is_a?(Integer) ||
|
291
|
-
"can't convert String into Integer")
|
292
|
+
owner_int.is_a?(Integer) || raise(TypeError, "can't convert String into Integer")
|
292
293
|
file.uid = owner_int
|
293
294
|
end
|
294
295
|
if group_int && group_int != -1
|
295
|
-
group_int.is_a?(Integer) ||
|
296
|
-
"can't convert String into Integer")
|
296
|
+
group_int.is_a?(Integer) || raise(TypeError, "can't convert String into Integer")
|
297
297
|
file.gid = group_int
|
298
298
|
end
|
299
299
|
end
|
@@ -311,16 +311,16 @@ module FakeFS
|
|
311
311
|
end
|
312
312
|
|
313
313
|
class << self
|
314
|
-
|
314
|
+
alias fnmatch fnmatch?
|
315
315
|
end
|
316
316
|
|
317
317
|
# FakeFS Stat class
|
318
318
|
class Stat
|
319
319
|
attr_reader :ctime, :mtime, :atime, :mode, :uid, :gid
|
320
|
-
attr_reader :birthtime
|
320
|
+
attr_reader :birthtime
|
321
321
|
|
322
322
|
def initialize(file, lstat = false)
|
323
|
-
|
323
|
+
raise(Errno::ENOENT, file) unless File.exist?(file)
|
324
324
|
|
325
325
|
@file = file
|
326
326
|
@fake_file = FileSystem.find(@file)
|
@@ -374,11 +374,11 @@ module FakeFS
|
|
374
374
|
# World_writable and readable are platform dependent
|
375
375
|
# usually comparing with S_IROTH defined on compilation (MRI)
|
376
376
|
def world_writable?
|
377
|
-
|
377
|
+
0o777
|
378
378
|
end
|
379
379
|
|
380
380
|
def world_readable?
|
381
|
-
|
381
|
+
0o777
|
382
382
|
end
|
383
383
|
|
384
384
|
def nlink
|
@@ -429,9 +429,9 @@ module FakeFS
|
|
429
429
|
val
|
430
430
|
end
|
431
431
|
|
432
|
-
|
433
|
-
|
434
|
-
|
432
|
+
alias tell= pos=
|
433
|
+
alias sysread read
|
434
|
+
alias syswrite write
|
435
435
|
|
436
436
|
undef_method :closed_read?
|
437
437
|
undef_method :closed_write?
|
@@ -453,11 +453,11 @@ module FakeFS
|
|
453
453
|
end
|
454
454
|
|
455
455
|
def ioctl(*)
|
456
|
-
|
456
|
+
raise NotImplementedError
|
457
457
|
end
|
458
458
|
|
459
459
|
def read_nonblock
|
460
|
-
|
460
|
+
raise NotImplementedError
|
461
461
|
end
|
462
462
|
|
463
463
|
def stat
|
@@ -473,18 +473,18 @@ module FakeFS
|
|
473
473
|
pos
|
474
474
|
end
|
475
475
|
|
476
|
-
|
476
|
+
alias to_i fileno
|
477
477
|
|
478
478
|
def to_io
|
479
479
|
self
|
480
480
|
end
|
481
481
|
|
482
482
|
def write_nonblock(*)
|
483
|
-
|
483
|
+
raise NotImplementedError
|
484
484
|
end
|
485
485
|
|
486
486
|
def readpartial(*)
|
487
|
-
|
487
|
+
raise NotImplementedError
|
488
488
|
end
|
489
489
|
|
490
490
|
def atime
|
@@ -496,7 +496,7 @@ module FakeFS
|
|
496
496
|
end
|
497
497
|
|
498
498
|
def flock(*)
|
499
|
-
|
499
|
+
raise NotImplementedError
|
500
500
|
end
|
501
501
|
|
502
502
|
def mtime
|
@@ -504,119 +504,107 @@ module FakeFS
|
|
504
504
|
end
|
505
505
|
|
506
506
|
def chmod(mode_int)
|
507
|
-
@file.mode =
|
507
|
+
@file.mode = 0o100000 + mode_int
|
508
508
|
end
|
509
509
|
|
510
510
|
def chown(owner_int, group_int)
|
511
511
|
return unless group_int && group_int != -1
|
512
512
|
|
513
|
-
owner_int.is_a?(
|
514
|
-
TypeError, "can't convert String into Integer"
|
513
|
+
owner_int.is_a?(Integer) || raise(
|
514
|
+
TypeError, "can't convert String into Integer"
|
515
|
+
)
|
515
516
|
@file.uid = owner_int
|
516
517
|
|
517
|
-
group_int.is_a?(
|
518
|
-
TypeError, "can't convert String into Integer"
|
518
|
+
group_int.is_a?(Integer) || raise(
|
519
|
+
TypeError, "can't convert String into Integer"
|
520
|
+
)
|
519
521
|
@file.gid = group_int
|
520
522
|
end
|
521
523
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
end
|
524
|
+
def self.realpath(*args)
|
525
|
+
RealFile.realpath(*args)
|
526
|
+
end
|
526
527
|
|
527
|
-
|
528
|
-
|
529
|
-
|
528
|
+
def binmode?
|
529
|
+
raise NotImplementedError
|
530
|
+
end
|
530
531
|
|
531
|
-
|
532
|
-
|
533
|
-
|
532
|
+
def close_on_exec=(_bool)
|
533
|
+
raise NotImplementedError
|
534
|
+
end
|
534
535
|
|
535
|
-
|
536
|
-
|
537
|
-
|
536
|
+
def close_on_exec?
|
537
|
+
raise NotImplementedError
|
538
|
+
end
|
538
539
|
|
539
|
-
|
540
|
-
|
541
|
-
end
|
540
|
+
def to_path
|
541
|
+
@path
|
542
542
|
end
|
543
543
|
|
544
|
-
|
545
|
-
|
546
|
-
RealFile.absolute_path(file_name, dir_name)
|
547
|
-
end
|
544
|
+
def self.absolute_path(file_name, dir_name = Dir.getwd)
|
545
|
+
RealFile.absolute_path(file_name, dir_name)
|
548
546
|
end
|
549
547
|
|
550
|
-
|
551
|
-
attr_accessor :autoclose
|
548
|
+
attr_accessor :autoclose
|
552
549
|
|
553
|
-
|
554
|
-
|
555
|
-
|
550
|
+
def autoclose?
|
551
|
+
@autoclose ? true : false
|
552
|
+
end
|
556
553
|
|
557
|
-
|
554
|
+
alias fdatasync flush
|
558
555
|
|
559
|
-
|
560
|
-
|
561
|
-
|
556
|
+
def size
|
557
|
+
File.size(@path)
|
558
|
+
end
|
562
559
|
|
563
|
-
|
564
|
-
|
565
|
-
end
|
560
|
+
def self.realdirpath(*args)
|
561
|
+
RealFile.realdirpath(*args)
|
566
562
|
end
|
567
563
|
|
568
|
-
|
569
|
-
def advise(_advice, _offset = 0, _len = 0)
|
570
|
-
end
|
564
|
+
def advise(_advice, _offset = 0, _len = 0); end
|
571
565
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
else
|
579
|
-
mode = open_args[:mode] || mode
|
580
|
-
args = [filename, mode, open_args]
|
581
|
-
end
|
566
|
+
def self.write(filename, contents, offset = nil, open_args = {})
|
567
|
+
offset, open_args = nil, offset if offset.is_a?(Hash)
|
568
|
+
mode = offset ? 'a' : 'w'
|
569
|
+
if open_args.any?
|
570
|
+
if open_args[:open_args]
|
571
|
+
args = [filename, *open_args[:open_args]]
|
582
572
|
else
|
583
|
-
|
573
|
+
mode = open_args[:mode] || mode
|
574
|
+
args = [filename, mode, open_args]
|
584
575
|
end
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
576
|
+
else
|
577
|
+
args = [filename, mode]
|
578
|
+
end
|
579
|
+
if offset
|
580
|
+
open(*args) do |f| # rubocop:disable Security/Open
|
581
|
+
f.seek(offset)
|
582
|
+
f.write(contents)
|
583
|
+
end
|
584
|
+
else
|
585
|
+
open(*args) do |f| # rubocop:disable Security/Open
|
586
|
+
f << contents
|
594
587
|
end
|
595
|
-
|
596
|
-
contents.length
|
597
588
|
end
|
589
|
+
|
590
|
+
contents.length
|
598
591
|
end
|
599
592
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
fail Errno::ENOENT
|
606
|
-
end
|
593
|
+
def self.birthtime(path)
|
594
|
+
if exists?(path)
|
595
|
+
FileSystem.find(path).birthtime
|
596
|
+
else
|
597
|
+
raise Errno::ENOENT
|
607
598
|
end
|
599
|
+
end
|
608
600
|
|
609
|
-
|
610
|
-
|
611
|
-
end
|
601
|
+
def birthtime
|
602
|
+
self.class.birthtime(@path)
|
612
603
|
end
|
613
604
|
|
614
605
|
def read(length = nil, buf = '')
|
615
606
|
read_buf = super(length, buf)
|
616
|
-
|
617
|
-
if read_buf.respond_to?(:force_encoding) && binary_mode?
|
618
|
-
read_buf = read_buf.force_encoding('ASCII-8BIT')
|
619
|
-
end
|
607
|
+
read_buf.force_encoding('ASCII-8BIT') if binary_mode?
|
620
608
|
read_buf
|
621
609
|
end
|
622
610
|
|
@@ -627,13 +615,14 @@ module FakeFS
|
|
627
615
|
end
|
628
616
|
|
629
617
|
def binary_mode?
|
630
|
-
@mode.is_a?(String) && (
|
631
|
-
|
632
|
-
|
618
|
+
@mode.is_a?(String) && (
|
619
|
+
@mode.include?('b') ||
|
620
|
+
@mode.include?('binary')
|
621
|
+
) && !@mode.include?('bom')
|
633
622
|
end
|
634
623
|
|
635
624
|
def check_file_existence!
|
636
|
-
|
625
|
+
raise Errno::ENOENT, @path unless @file
|
637
626
|
end
|
638
627
|
|
639
628
|
def file_creation_mode?
|
@@ -641,9 +630,11 @@ module FakeFS
|
|
641
630
|
end
|
642
631
|
|
643
632
|
def mode_in?(list)
|
644
|
-
|
645
|
-
|
646
|
-
|
633
|
+
if @mode.respond_to?(:include?)
|
634
|
+
list.any? do |element|
|
635
|
+
@mode.include?(element)
|
636
|
+
end
|
637
|
+
end
|
647
638
|
end
|
648
639
|
|
649
640
|
def mode_in_bitmask?(mask)
|
@@ -653,7 +644,7 @@ module FakeFS
|
|
653
644
|
# Create a missing file if the path is valid.
|
654
645
|
#
|
655
646
|
def create_missing_file
|
656
|
-
|
647
|
+
raise Errno::EISDIR, path if File.directory?(@path)
|
657
648
|
|
658
649
|
return if File.exist?(@path) # Unnecessary check, probably.
|
659
650
|
dirname = RealFile.dirname @path
|
@@ -661,7 +652,7 @@ module FakeFS
|
|
661
652
|
unless dirname == '.'
|
662
653
|
dir = FileSystem.find dirname
|
663
654
|
|
664
|
-
|
655
|
+
raise Errno::ENOENT, path unless dir.is_a? FakeDir
|
665
656
|
end
|
666
657
|
|
667
658
|
@file = FileSystem.add(path, FakeFile.new)
|