fakefs 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2bfa54005c100676feb93956681fe9cd686030fe16e3dab3a54109e5c29b2361
4
- data.tar.gz: 30c51f9bcf1e221ca4cd3fbb43ee987979c7fa57b2aa1865f9387bfab755d66b
3
+ metadata.gz: 2615742cb54b7cea91ad40e51e1b1baf037ea9295eff338b0432fc20f1ea9483
4
+ data.tar.gz: e9e136d1eb2d10a18b0470ed45c8058b88656af040d45136f78a53fb21bf42c0
5
5
  SHA512:
6
- metadata.gz: 6929e502b22c9f1f632b0d98379caad07a7abcda53c658fb258d321dda15e53d60e4c927365beb6ec62d2e9d30c77aa70e746e0cd693bf6f02256c64eb4ab5a2
7
- data.tar.gz: 2d80c942fbfea67e1dfa031f1b859115cefe783e9cb35a246a7f44b6f1d55511c40a758782dafad2557eefcbf7cabcea7f338c35a6f207a7ea94ec204bb99aea
6
+ metadata.gz: 790f25734bd4b9bf2c4b82750421bbe40114a591efa327b909b61e0ef341360f5bdbde7c5d99c06a3931f46d655710f1fc7c302a24b67590cb849e506e750450
7
+ data.tar.gz: 73578d236fa95d8307311c87c9fba693c101295bdc915b2bc6adda0c074e9ea5eb782121af5cc3c3446cf8292d57a6ed8dd5c6979a4cdee9be2fb11053c4b65c
@@ -119,7 +119,7 @@ module FakeFS
119
119
 
120
120
  def self.glob(pattern, flags = 0, &block)
121
121
  matches_for_pattern = lambda do |matcher|
122
- [FileSystem.find(matcher, flags) || []].flatten.map do |e|
122
+ [FileSystem.find(matcher, flags, true) || []].flatten.map do |e|
123
123
  if Dir.pwd.match(%r{\A/?\z}) ||
124
124
  !e.to_s.match(%r{\A#{Dir.pwd}/?})
125
125
  e.to_s
@@ -53,16 +53,20 @@ module FakeFS
53
53
  class << self
54
54
  alias exists? exist?
55
55
 
56
- # Assuming that everyone can read and write files
57
- alias readable? exist?
58
- alias writable? exist?
59
-
60
56
  # Assume nothing is sticky.
61
57
  def sticky?(_path)
62
58
  false
63
59
  end
64
60
  end
65
61
 
62
+ def self.readable?(path)
63
+ File.lstat(path).readable?
64
+ end
65
+
66
+ def self.writable?(path)
67
+ File.lstat(path).writable?
68
+ end
69
+
66
70
  def self.mtime(path)
67
71
  if exists?(path)
68
72
  FileSystem.find(path).mtime
@@ -363,13 +367,28 @@ module FakeFS
363
367
  'file'
364
368
  end
365
369
 
366
- # assumes, like above, that all files are readable and writable.
367
370
  def readable?
368
- true
371
+ # a file is readable if, and only if, it has the following bits:
372
+ # 4 ( read permission )
373
+ # 5 ( read + execute permission )
374
+ # 6 ( read + write permission )
375
+ # 7 ( read + write + execute permission )
376
+ # for each group we will isolate the wanted numbers ( for owner, world, or group )
377
+ # and see if the third bit is set ( as that is the bit for read )
378
+ read_bit = 4
379
+ check_if_bit_set(read_bit)
369
380
  end
370
381
 
371
382
  def writable?
372
- true
383
+ # a file is writable if, and only if, it has the following bits:
384
+ # 2 ( write permission )
385
+ # 3 ( write + execute permission )
386
+ # 6 ( read + write permission )
387
+ # 7 ( read + write + execute permission )
388
+ # for each group we will isolate the wanted numbers ( for owner, world, or group )
389
+ # and see if the second bit is set ( as that is the bit for write )
390
+ write_bit = 2
391
+ check_if_bit_set(write_bit)
373
392
  end
374
393
 
375
394
  # Assume nothing is sticky.
@@ -412,6 +431,41 @@ module FakeFS
412
431
  def <=>(other)
413
432
  @mtime <=> other.mtime
414
433
  end
434
+
435
+ private
436
+
437
+ def check_if_bit_set(bit)
438
+ # get user's group and user ids
439
+ # NOTE: I am picking `Process` over `Etc` as we use `Process`
440
+ # when instaniating file classes. It may be worth it to ensure
441
+ # our Process/Group detection scheme is robust in all cases
442
+ uid = Process.uid
443
+ gid = Process.gid
444
+
445
+ # check if bit set for owner
446
+ owner_bits = (@mode >> 6) & 0o7
447
+ if uid == @uid
448
+ # the user is locked out of the file if they are owner of the file
449
+ # but do not have the bit set at the user level
450
+ return true if owner_bits & bit == bit
451
+ return false
452
+ end
453
+
454
+ # check if bit set for group
455
+ group_bits = (@mode >> 3) & 0o7
456
+ if gid == @gid
457
+ # the user is locked out of the file if they are in the group that
458
+ # owns the file but do not have the bit set at the group level
459
+ return true if group_bits & bit == bit
460
+ return false
461
+ end
462
+
463
+ # check if bit set for world
464
+ world_bits = @mode & 0o7
465
+ return true if world_bits & bit == bit
466
+
467
+ false
468
+ end
415
469
  end
416
470
 
417
471
  attr_reader :path
@@ -20,13 +20,13 @@ module FakeFS
20
20
  fs.entries
21
21
  end
22
22
 
23
- def find(path, find_flags = 0)
23
+ def find(path, find_flags = 0, gave_char_class = false)
24
24
  parts = path_parts(normalize_path(path))
25
25
  return fs if parts.empty? # '/'
26
26
 
27
27
  entries = Globber.expand(path).flat_map do |pattern|
28
28
  parts = path_parts(normalize_path(pattern))
29
- find_recurser(fs, parts, find_flags).flatten
29
+ find_recurser(fs, parts, find_flags, gave_char_class).flatten
30
30
  end
31
31
 
32
32
  case entries.length
@@ -88,6 +88,7 @@ module FakeFS
88
88
  dir_levels.push dir if blk
89
89
 
90
90
  raise Errno::ENOENT, dir unless new_dir
91
+ raise Errno::ENOTDIR, dir unless File.directory? new_dir
91
92
 
92
93
  dir_levels.push dir unless blk
93
94
  yield(dir) if blk
@@ -116,7 +117,7 @@ module FakeFS
116
117
 
117
118
  private
118
119
 
119
- def find_recurser(dir, parts, find_flags = 0)
120
+ def find_recurser(dir, parts, find_flags = 0, gave_char_class = false)
120
121
  return [] unless dir.respond_to? :[]
121
122
  pattern, *parts = parts
122
123
  matches =
@@ -139,14 +140,14 @@ module FakeFS
139
140
  end
140
141
  else
141
142
  Globber.expand(pattern).flat_map do |subpattern|
142
- dir.matches(Globber.regexp(subpattern, find_flags))
143
+ dir.matches(Globber.regexp(subpattern, find_flags, gave_char_class))
143
144
  end
144
145
  end
145
146
 
146
147
  if parts.empty? # we're done recursing
147
148
  matches
148
149
  else
149
- matches.map { |entry| find_recurser(entry, parts, find_flags) }
150
+ matches.map { |entry| find_recurser(entry, parts, find_flags, gave_char_class) }
150
151
  end
151
152
  end
152
153
 
@@ -60,7 +60,7 @@ module FakeFS
60
60
  drop_root(result).reject(&:empty?)
61
61
  end
62
62
 
63
- def regexp(pattern, find_flags = 0)
63
+ def regexp(pattern, find_flags = 0, gave_char_class = false)
64
64
  pattern = pattern.to_s
65
65
 
66
66
  regex_body =
@@ -73,6 +73,12 @@ module FakeFS
73
73
  .gsub(')', '\)')
74
74
  .gsub('$', '\$')
75
75
 
76
+ # unless we're expecting character class contructs in regexes, escape all brackets
77
+ # since if we're expecting them, the string should already be properly escaped
78
+ unless gave_char_class
79
+ regex_body = regex_body.gsub('[', '\[').gsub(']', '\]')
80
+ end
81
+
76
82
  # This matches nested braces and attempts to do something correct most of the time
77
83
  # There are known issues (i.e. {,*,*/*}) that cannot be resolved with out a total
78
84
  # refactoring
@@ -1,7 +1,7 @@
1
1
  module FakeFS
2
2
  # Version module
3
3
  module Version
4
- VERSION = '0.16.0'.freeze
4
+ VERSION = '0.17.0'.freeze
5
5
 
6
6
  def self.to_s
7
7
  VERSION
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fakefs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2018-07-11 00:00:00.000000000 Z
15
+ date: 2018-07-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bump