Skip to content

Commit af675af

Browse files
committed
Fix #install with "X" mode option
`FileUtils#install` methed raises an unexpected `TypeError`, when called with `mode:` option which has `"X"`. ``` $ ruby -rfileutils -e 'FileUtils.install("tmp/a", "tmp/b", mode: "o+X")' /opt/local/lib/ruby/2.7.0/fileutils.rb:942:in `directory?': no implicit conversion of File::Stat into String (TypeError) from /opt/local/lib/ruby/2.7.0/fileutils.rb:942:in `block (3 levels) in symbolic_modes_to_i' from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `each_char' from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `each' from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `inject' from /opt/local/lib/ruby/2.7.0/fileutils.rb:933:in `block (2 levels) in symbolic_modes_to_i' from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `each' from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `each_slice' from /opt/local/lib/ruby/2.7.0/fileutils.rb:931:in `block in symbolic_modes_to_i' from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `each' from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `inject' from /opt/local/lib/ruby/2.7.0/fileutils.rb:926:in `symbolic_modes_to_i' from /opt/local/lib/ruby/2.7.0/fileutils.rb:973:in `fu_mode' from /opt/local/lib/ruby/2.7.0/fileutils.rb:883:in `block in install' from /opt/local/lib/ruby/2.7.0/fileutils.rb:1588:in `block in fu_each_src_dest' from /opt/local/lib/ruby/2.7.0/fileutils.rb:1604:in `fu_each_src_dest0' from /opt/local/lib/ruby/2.7.0/fileutils.rb:1586:in `fu_each_src_dest' from /opt/local/lib/ruby/2.7.0/fileutils.rb:877:in `install' from -e:1:in `<main>' ``` In spite of that `symbolic_modes_to_i` considers the `File::Stat` `path` case at the beginning, in `"X"` case, `path` is passed to `FileTest.directory?` method which requires a `String`. In such case, the mode in `path` should be examined instead.
1 parent 563a383 commit af675af

File tree

2 files changed

+5
-6
lines changed

2 files changed

+5
-6
lines changed

lib/fileutils.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -917,11 +917,8 @@ def apply_mask(mode, user_mask, op, mode_mask) #:nodoc:
917917
private_module_function :apply_mask
918918

919919
def symbolic_modes_to_i(mode_sym, path) #:nodoc:
920-
mode = if File::Stat === path
921-
path.mode
922-
else
923-
File.stat(path).mode
924-
end
920+
path = File.stat(path) unless File::Stat === path
921+
mode = path.mode
925922
mode_sym.split(/,/).inject(mode & 07777) do |current_mode, clause|
926923
target, *actions = clause.split(/([=+-])/)
927924
raise ArgumentError, "invalid file mode: #{mode_sym}" if actions.empty?
@@ -938,7 +935,7 @@ def symbolic_modes_to_i(mode_sym, path) #:nodoc:
938935
when "x"
939936
mask | 0111
940937
when "X"
941-
if FileTest.directory? path
938+
if path.directory?
942939
mask | 0111
943940
else
944941
mask

test/fileutils/test_fileutils.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,8 @@ def test_install_mode_option
11821182
assert_filemode 04500, 'tmp/j'
11831183
install 'tmp/j', 'tmp/k', :mode => "+s"
11841184
assert_filemode 06500, 'tmp/k'
1185+
install 'tmp/a', 'tmp/l', :mode => "o+X"
1186+
assert_equal_filemode 'tmp/a', 'tmp/l'
11851187
end if have_file_perm?
11861188

11871189
def test_chmod

0 commit comments

Comments
 (0)