diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | lib/fileutils.rb | 133 | ||||
-rw-r--r-- | test/fileutils/test_fileutils.rb | 23 |
3 files changed, 152 insertions, 9 deletions
@@ -1,3 +1,8 @@ +Sat Dec 4 20:45:52 2004 Minero Aoki <aamine@loveruby.net> + + * lib/fileutils.rb (mkdir, mkdir_p): should chmod explicitly. + [ruby-core:03881] + Sat Dec 4 18:54:09 2004 Kouhei Sutou <kou@cozmixng.org> * lib/rss/rss.rb: removed empty lines from output. diff --git a/lib/fileutils.rb b/lib/fileutils.rb index 20177a048c..9684ebf31a 100644 --- a/lib/fileutils.rb +++ b/lib/fileutils.rb @@ -73,6 +73,8 @@ # <tt>:verbose</tt> flags to methods in FileUtils. # +require 'find' + module FileUtils @@ -148,9 +150,8 @@ module FileUtils fu_output_message "mkdir #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose] return if options[:noop] - mode = options[:mode] || (0777 & ~File.umask) list.each do |dir| - Dir.mkdir dir.sub(%r</\z>, ''), mode + fu_mkdir dir, options[:mode] end end @@ -176,11 +177,10 @@ module FileUtils fu_output_message "mkdir -p #{options[:mode] ? ('-m %03o ' % options[:mode]) : ''}#{list.join ' '}" if options[:verbose] return *list if options[:noop] - mode = options[:mode] || (0777 & ~File.umask) list.map {|path| path.sub(%r</\z>, '') }.each do |path| # optimize for the most common case begin - Dir.mkdir path, mode + fu_mkdir path, options[:mode] next rescue SystemCallError next if File.directory?(path) @@ -193,7 +193,7 @@ module FileUtils end stack.reverse_each do |path| begin - Dir.mkdir path, mode + fu_mkdir path, options[:mode] rescue SystemCallError => err raise unless File.directory?(path) end @@ -206,6 +206,17 @@ module FileUtils alias mkpath mkdir_p alias makedirs mkdir_p + def fu_mkdir(path, mode) + path = path.sub(%r</\z>, '') + if mode + Dir.mkdir path, mode + File.chmod mode, path + else + Dir.mkdir path + end + end + private :fu_mkdir + # # Options: noop, verbose @@ -795,6 +806,115 @@ module FileUtils # # Options: noop verbose # + # Changes permission bits on the named files and directories (in +list+) + # to the bit pattern represented by +mode+. + # + # FileUtils.chmod 0700, '/home/test/.ssh', :verbose => true + # + def chmod_R(mode, list, options = {}) + fu_check_options options, :noop, :verbose + list = fu_list(list) + fu_output_message sprintf('chmod -R %o %s', + mode, list.join(' ')) if options[:verbose] + return if options[:noop] + list.each do |prefix| + Find.find(prefix) do |path| + File.chmod mode, path + end + end + end + + + # + # Options: noop verbose + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group. +user+ and +group+ + # may be an ID (Integer/String) or a name (String). + # If +user+ or +group+ is nil, this method does not change + # the attribute. + # + # FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby' + # FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), :verbose => true + # + def chown(user, group, list, options = {}) + fu_check_options options, :noop, :verbose + list = fu_list(list) + fu_output_message sprintf('chown %s%s', + [user,group].compact.join(':') + ' ', + list.join(' ')) if options[:verbose] + return if options[:noop] + File.chown fu_get_uid(user), fu_get_gid(group), *list + end + + + # + # Options: noop verbose + # + # Changes owner and group on the named files (in +list+) + # to the user +user+ and the group +group. +user+ and +group+ + # may be an ID (Integer/String) or a name (String). + # If +user+ or +group+ is nil, this method does not change + # the attribute. + # + # FileUtils.chmod_R 'www', 'www', '/var/www/htdocs' + # FileUtils.chmod_R 'cvs', 'cvs', '/var/cvs', :verbose => true + # + def chown_R(mode, list, options = {}) + fu_check_options options, :noop, :verbose + list = fu_list(list) + fu_output_message sprintf('chown -R %s%s', + [user,group].compact.join(':') + ' ', + list.join(' ')) if options[:verbose] + return if options[:noop] + uid = fu_get_uid(user) + gid = fu_get_gid(group) + return unless uid or gid + list.each do |prefix| + Find.find(prefix) do |path| + File.chown uid, gid, path + end + end + end + + begin + require 'etc' + + def fu_get_uid(user) + return nil unless user + user = user.to_s + if /\A\d+\z/ =~ user + then user.to_i + else Etc.getpwnam(user).uid + end + end + private :fu_get_uid + + def fu_get_gid(group) + return nil unless group + if /\A\d+\z/ =~ group + then group.to_i + else Etc.getgrnam(group).gid + end + end + private :fu_get_gid + + rescue LoadError + # need Win32 support??? + + def fu_get_uid(user) + user # FIXME + end + + def fu_get_gid(group) + group # FIXME + end + end + + + # + # Options: noop verbose + # # Updates modification time (mtime) and access time (atime) of file(s) in # +list+. Files are created if they don't exist. # @@ -918,6 +1038,9 @@ module FileUtils 'cd' => %w( noop verbose ), 'chdir' => %w( noop verbose ), 'chmod' => %w( noop verbose ), + 'chmod_R' => %w( noop verbose ), + 'chown' => %w( noop verbose ), + 'chown_R' => %w( noop verbose ), 'copy' => %w( noop verbose preserve ), 'cp' => %w( noop verbose preserve ), 'cp_r' => %w( noop verbose preserve ), diff --git a/test/fileutils/test_fileutils.rb b/test/fileutils/test_fileutils.rb index edafcd14e6..303c1b42a0 100644 --- a/test/fileutils/test_fileutils.rb +++ b/test/fileutils/test_fileutils.rb @@ -16,7 +16,7 @@ Dir.mkdir tmproot unless File.directory?(tmproot) Dir.chdir tmproot def have_drive_letter? - /djgpp|mswin(?!ce)|mingw|bcc|emx/ === RUBY_PLATFORM + /djgpp|mswin(?!ce)|mingw|bcc|emx/ =~ RUBY_PLATFORM end def have_file_perm? @@ -579,10 +579,17 @@ end assert_equal 0700, (File.stat('tmp/tmp').mode & 0777) if have_file_perm? Dir.rmdir 'tmp/tmp' +if have_file_perm? + mkdir 'tmp/tmp', :mode => 07777 + assert_directory 'tmp/tmp' + assert_equal 07777, (File.stat('tmp/tmp').mode & 07777) + Dir.rmdir 'tmp/tmp' +end + if lf_in_path_allowed? - mkdir "tmp-first-line\ntmp-second-line" - assert_directory "tmp-first-line\ntmp-second-line" - Dir.rmdir "tmp-first-line\ntmp-second-line" + mkdir "tmp-first-line\ntmp-second-line" + assert_directory "tmp-first-line\ntmp-second-line" + Dir.rmdir "tmp-first-line\ntmp-second-line" end # pathname @@ -641,6 +648,14 @@ end Dir.rmdir 'tmp/tmp' Dir.rmdir 'tmp' +if have_file_perm? + mkdir_p 'tmp/tmp/tmp', :mode => 07777 + assert_directory 'tmp/tmp/tmp' + assert_equal 07777, (File.stat('tmp/tmp/tmp').mode & 07777) + Dir.rmdir 'tmp/tmp/tmp' + Dir.rmdir 'tmp/tmp' +end + # pathname assert_nothing_raised { mkdir_p Pathname.new('tmp/tmp/tmp') |