fakefs 0.18.0 → 0.18.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9479bf3a7bc17238053ebfe0489449a54eaf93975c253873caa817cb608a6e12
4
- data.tar.gz: e0071c3db4a4b16278a995b0f1ecce76a6781ce23847ef67194a0edb2f2999e2
3
+ metadata.gz: 1b8f0d4485537e8357f305f9d095421de79719f65ada17d30c21443d8f331649
4
+ data.tar.gz: f2cc6f45b43483d18552d92aa2fcc39e8112bb0a0ed5ce17ed05c8ae92410903
5
5
  SHA512:
6
- metadata.gz: 03be56fc4d1a9f05d410e75f2292cb498c0522f9a40508a28763ec757a5b6bf011be8c1462b52292987ea5f594ed54f04f64e1a4baefac2768c4db318ae5f389
7
- data.tar.gz: 7fdd408a1814b6629271d4de1c9610c77836e9d1d8a3dfec8c7c4667bfa4d5fd02e5ed5b85aa111de3e5d5a84808c97b8ced730d2c4cbbad995cb87b703b3014
6
+ metadata.gz: 4fadd520bccc2df062eec7b09324c2d80e3df433d74a969b965dc362e2e7b853ee4f5975688b8eceb325ed4170b580583bebfa34a43e3a8a7d77ca7376f4cc52
7
+ data.tar.gz: 7646dfab7046723fae643785d606ef9a2ab366231780aa63d4e6bce2a20c38688332688f4890573a51df5641dbeade4c6f5a73da38aac9571e9d9b2df92a500e
data/lib/fakefs/file.rb CHANGED
@@ -283,15 +283,16 @@ module FakeFS
283
283
  RealFile.split(path)
284
284
  end
285
285
 
286
- def self.chmod(mode, filename)
286
+ def self.chmod(new_mode, filename)
287
287
  # chmod's mode can either be passed in in absolute mode, or symbolic mode
288
288
  # for reference: https://ruby-doc.org/stdlib-2.2.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-chmod
289
289
  # if the mode is passed in symbolic mode we must convert it to absolute mode
290
- is_absolute_mode = mode.is_a? Numeric
290
+ is_absolute_mode = new_mode.is_a? Numeric
291
291
  unless is_absolute_mode
292
- mode = convert_symbolic_chmod_to_absolute mode
292
+ current_mode = FileSystem.find(filename).mode
293
+ new_mode = convert_symbolic_chmod_to_absolute(new_mode, current_mode)
293
294
  end
294
- FileSystem.find(filename).mode = 0o100000 + mode
295
+ FileSystem.find(filename).mode = 0o100000 + new_mode
295
296
  end
296
297
 
297
298
  # Not exactly right, returns true if the file is chmod +x for owner. In the
@@ -576,15 +577,16 @@ module FakeFS
576
577
  self.class.mtime(@path)
577
578
  end
578
579
 
579
- def chmod(mode)
580
+ def chmod(new_mode)
580
581
  # chmod's mode can either be passed in in absolute mode, or symbolic mode
581
582
  # for reference: https://ruby-doc.org/stdlib-2.2.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-chmod
582
583
  # if the mode is passed in symbolic mode we must convert it to absolute mode
583
- is_absolute_mode = mode.is_a? Numeric
584
+ is_absolute_mode = new_mode.is_a? Numeric
584
585
  unless is_absolute_mode
585
- mode = convert_symbolic_chmod_to_absolute mode
586
+ current_mode = @file.mode
587
+ new_mode = convert_symbolic_chmod_to_absolute(new_mode, current_mode)
586
588
  end
587
- @file.mode = 0o100000 + mode
589
+ @file.mode = 0o100000 + new_mode
588
590
  end
589
591
 
590
592
  def chown(owner_int, group_int)
@@ -688,10 +690,10 @@ module FakeFS
688
690
  read_buf
689
691
  end
690
692
 
691
- def self.convert_symbolic_chmod_to_absolute(mode)
693
+ def self.convert_symbolic_chmod_to_absolute(new_mode, current_mode)
692
694
  # mode always must be of form <GROUP1>=<FLAGS>,<GROUP2>=<FLAGS,...
693
695
  # e.g.: u=wr,go=x
694
- chmod_pairs = mode.split(',')
696
+ chmod_pairs = new_mode.split(',')
695
697
 
696
698
  # - duplicating groups is OK ( e.g.: 'ugouuoouu' is valid and is interpretted as 'ugo' )
697
699
  # - duplicating modes is OK ( e.g.: 'wwwwwwwww' is interpreted as 'w' )
@@ -707,38 +709,56 @@ module FakeFS
707
709
  # or else an error is raised
708
710
  # - in the example above, the following error is raised: 'invalid `who' symbol in file mode: z (ArgumentError)'
709
711
  valid_groups_to_numeric_vals = { 'u' => 0o100, 'g' => 0o10, 'o' => 0o1 }
712
+
713
+ # make sure we preload the current group values.
714
+ # chmod works by calculating new permissions based off of existing permissions
710
715
  current_groups_to_vals = { 0o100 => 0o0, 0o10 => 0o0, 0o1 => 0o0 }
711
- valid_modes_to_numeric_vals = { 'r' => 0o4, 'w' => 0o2, 'x' => 0o1 }
716
+ [0o100, 0o10, 0o1].each do |group_num|
717
+ perm_amt = get_perms_for_group(current_mode, group_num)
718
+ current_groups_to_vals[group_num] = perm_amt
719
+ end
720
+
712
721
  chmod_pairs.each do |pair|
713
- groups = pair.rpartition('=').first
714
- modes = pair.rpartition('=').last
715
-
716
- # if we give no modes, then we are removing all permission
717
- chmod_perm_num = 0o0
718
- if modes != ''
719
- # make sure there are no invalid flags in the modes
720
- # and that we discard duplicates as chmod does
721
- given_modes = modes.split('')
722
- given_modes = given_modes.uniq
723
- given_modes.each do |specific_mode|
724
- # ensure that the mode is valid
725
- unless valid_modes_to_numeric_vals.key? specific_mode
726
- raise ArgumentError, "Invalid `perm' symbol in file mode: #{specific_mode}"
727
- end
722
+ # see if we are dealing with +/- ( granting or removing permissions ) or = ( assigning permissions )
723
+ # note that it IS valid to mix assignment and granting/revoking perissions ( things like u=wrx,g+x are valid )
724
+ assign_perms = '='
725
+ remove_perms = '-'
726
+ add_perms = '+'
727
+ assignment_mode = nil
728
+ if pair.include? remove_perms
729
+ assignment_mode = remove_perms
730
+ elsif pair.include? add_perms
731
+ assignment_mode = add_perms
732
+ elsif pair.include? assign_perms
733
+ assignment_mode = assign_perms
734
+ end
728
735
 
729
- chmod_addend = valid_modes_to_numeric_vals[specific_mode]
730
- chmod_perm_num += chmod_addend
731
- end
736
+ # if we can't find a mode, then raise an exception as real `chmod` would
737
+ if assignment_mode.nil?
738
+ raise ArgumentError, "Invalid file mode: #{mode}"
732
739
  end
740
+ adding_removing_perms = [add_perms, remove_perms].include?(assignment_mode)
741
+
742
+ groups = pair.rpartition(assignment_mode).first
743
+ modes = pair.rpartition(assignment_mode).last
744
+
745
+ # get the numeric chmod value associated with the symbolic entry
746
+ chmod_perm_num = calculate_chmod_amt_for_mode modes
733
747
 
734
748
  # if we give no groups, then we are giving all groups
735
749
  if groups == ''
736
- current_groups_to_vals[0o100] = chmod_perm_num
737
- current_groups_to_vals[0o10] = chmod_perm_num
738
- current_groups_to_vals[0o1] = chmod_perm_num
750
+ if adding_removing_perms
751
+ [0o100, 0o10, 0o1].each do |group_num|
752
+ perm_amt = set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num)
753
+ current_groups_to_vals[group_num] = perm_amt
754
+ end
755
+ else
756
+ [0o100, 0o10, 0o1].each do |group_num|
757
+ current_groups_to_vals[group_num] = chmod_perm_num
758
+ end
759
+ end
739
760
  else
740
- # make sure there are no invalid flags in the groups
741
- # and that we discard duplicates as chmod does
761
+ # make sure there are no invalid flags in the groups and that we discard duplicates as chmod does
742
762
  given_groups = groups.split('')
743
763
  given_groups = given_groups.uniq
744
764
  given_groups.each do |specific_group|
@@ -747,9 +767,15 @@ module FakeFS
747
767
  raise ArgumentError, "Invalid `who' symbol in file mode: #{specific_group}"
748
768
  end
749
769
 
750
- # take the current chmod amt from earlier and assosciate that as the current chmod factor for the group
770
+ # take the current chmod amt from earlier and associate that as the current chmod factor for the group
771
+ # if we are adding or removing groups ( via +/- ) then we must make sure that we adjust
772
+ # the current chmod perm number for the group
751
773
  group_num = valid_groups_to_numeric_vals[specific_group]
752
- current_groups_to_vals[group_num] = chmod_perm_num
774
+ adjusted_chmod = chmod_perm_num
775
+ if adding_removing_perms
776
+ adjusted_chmod = set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num)
777
+ end
778
+ current_groups_to_vals[group_num] = adjusted_chmod
753
779
  end
754
780
  end
755
781
  end
@@ -758,7 +784,64 @@ module FakeFS
758
784
  0o100 * current_groups_to_vals[0o100] + 0o10 * current_groups_to_vals[0o10] + current_groups_to_vals[0o1]
759
785
  end
760
786
 
761
- private_class_method :convert_symbolic_chmod_to_absolute
787
+ # return the group mode for group num based off the provided current_file_mode
788
+ def self.get_perms_for_group(current_file_mode, group_num)
789
+ # get the current recorded mode of the group and return it to the caller
790
+ # note we don't shift for 'o' since that is the bottom 3 bits
791
+ # note we multiply by 7 since the group num is 1, and octal represents digits 1-7 and we want all 3 bits
792
+ current_group_mode = current_file_mode & (group_num * 7)
793
+ if group_num == 0o100
794
+ current_group_mode = current_group_mode >> 6
795
+ elsif group_num == 0o10
796
+ current_group_mode = current_group_mode >> 3
797
+ end
798
+
799
+ current_group_mode
800
+ end
801
+
802
+ # given the current chmod values for a file return the result of adding or removing chmod_perm_num from the
803
+ # requested groups permissions ( so performing <GROUP>+<PERMS> or <GROUP>-<PERMS>
804
+ def self.set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num)
805
+ # get the current recorded mode of the group
806
+ current_group_mode = current_groups_to_vals[group_num]
807
+
808
+ # now that we have the current value of the group, add or remove bits accordingly
809
+ if assignment_mode == '+'
810
+ current_group_mode | chmod_perm_num
811
+ elsif assignment_mode == '-'
812
+ current_group_mode & ~chmod_perm_num
813
+ else
814
+ raise ArguementError "Unknown assignment mode #{assignment_mode}"
815
+ end
816
+ end
817
+
818
+ # given a list of modes [rwx] (a) ensure all modes are valid and (b) return the numeric value
819
+ # associated with the modes
820
+ def self.calculate_chmod_amt_for_mode(modes)
821
+ valid_modes_to_numeric_vals = { 'r' => 0o4, 'w' => 0o2, 'x' => 0o1 }
822
+
823
+ # if we give no modes, then we are removing all permission
824
+ chmod_perm_num = 0o0
825
+ if modes != ''
826
+ # make sure there are no invalid flags in the modes and that we discard duplicates as chmod does
827
+ given_modes = modes.split('')
828
+ given_modes = given_modes.uniq
829
+ given_modes.each do |specific_mode|
830
+ # ensure that the mode is valid
831
+ unless valid_modes_to_numeric_vals.key? specific_mode
832
+ raise ArgumentError, "Invalid `perm' symbol in file mode: #{specific_mode}"
833
+ end
834
+
835
+ chmod_perm_num += valid_modes_to_numeric_vals[specific_mode]
836
+ end
837
+ end
838
+
839
+ chmod_perm_num
840
+ end
841
+
842
+ # split the private class method decleration so rubocop doesn't complain the line is too long
843
+ private_class_method :convert_symbolic_chmod_to_absolute, :calculate_chmod_amt_for_mode
844
+ private_class_method :get_perms_for_group, :set_perms_for_group
762
845
 
763
846
  private
764
847
 
@@ -876,9 +876,9 @@ module FakeFS
876
876
  FileTest.setgid?(@path)
877
877
  end
878
878
 
879
- # See <tt>FileTest.size</tt>.
879
+ # See <tt>FileTest.size?</tt>.
880
880
  def size
881
- FileTest.size(@path)
881
+ FileTest.size?(@path)
882
882
  end
883
883
 
884
884
  # See <tt>FileTest.size?</tt>.
@@ -1,7 +1,7 @@
1
1
  module FakeFS
2
2
  # Version module
3
3
  module Version
4
- VERSION = '0.18.0'.freeze
4
+ VERSION = '0.18.1'.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.18.0
4
+ version: 0.18.1
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-23 00:00:00.000000000 Z
15
+ date: 2019-01-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bump
@@ -28,20 +28,6 @@ dependencies:
28
28
  - - "~>"
29
29
  - !ruby/object:Gem::Version
30
30
  version: 0.5.3
31
- - !ruby/object:Gem::Dependency
32
- name: bundler
33
- requirement: !ruby/object:Gem::Requirement
34
- requirements:
35
- - - "~>"
36
- - !ruby/object:Gem::Version
37
- version: '1.3'
38
- type: :development
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- requirements:
42
- - - "~>"
43
- - !ruby/object:Gem::Version
44
- version: '1.3'
45
31
  - !ruby/object:Gem::Dependency
46
32
  name: minitest
47
33
  requirement: !ruby/object:Gem::Requirement