FileUtils head-scratcher

In one of my projects I need to move all files and subdirectories in a
particular directory up on level.

e.g. mv * …

When I wrote this in Ruby using FileUtils, it works the first time but
subsequent runs fail and I don’t understand why. The error doesn’t make
sense because the file/directory it is complaining about is always
already there.

Here’s the code:

require ‘fileutils’

def makedir(name)
FileUtils.mkdir name unless File.exists?(name) && File.directory?(name)
end

makedir(‘dir’)
Dir.chdir(‘dir’) do
makedir(‘subdir’)
Dir.chdir(‘subdir’) do
5.times { |i| FileUtils.touch i.to_s }
makedir(‘subsubdir’)
Dir.chdir(‘subsubdir’) do
5.times { |i| FileUtils.touch i.to_s }
end
end

subdir = Dir.glob(“subdir/*”)
FileUtils.mv subdir, ‘.’, :verbose => true
end

The first run works. The second run fails.

cremes$ ruby a.rb
mv subdir/0 subdir/1 subdir/2 subdir/3 subdir/4 subdir/subsubdir .
cremes$ ruby a.rb
mv subdir/0 subdir/1 subdir/2 subdir/3 subdir/4 subdir/subsubdir .
An exception occurred running a.rb
File exists - . (Errno::EEXIST)

Backtrace:
{ } in FileUtils.mv at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:500
{ } in FileUtils.fu_each_src_dest at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:1402
{ } in FileUtils.fu_each_src_dest0 at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:1411
Array#each at kernel/bootstrap/array.rb:66
FileUtils.fu_each_src_dest0 at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:1409
FileUtils.fu_each_src_dest at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:1400
FileUtils.mv at
/Volumes/spiff/cremes/dev/ruby/rubinius
/lib/18/fileutils.rb:495
{ } in Object#script at a.rb:19
Dir.chdir at kernel/common/dir.rb:68
Object#script at a.rb:8
Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:65
Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:107
Rubinius::Loader#script at kernel/loader.rb:618
Rubinius::Loader#main at kernel/loader.rb:772

How do I get this to work every time?

cr

On 9/25/2011 12:22 PM, Chuck R. wrote:

5.times {|i|  FileUtils.touch i.to_s }
makedir('subsubdir')
Dir.chdir('subsubdir') do
  5.times {|i|  FileUtils.touch i.to_s }
end

end

subdir = Dir.glob(“subdir/*”)
FileUtils.mv subdir, ‘.’, :verbose => true
end
add

:force => true

to the call to
FileUtils.mv subdir, ‘.’, :verbose => true

On Sun, Sep 25, 2011 at 6:58 PM, Reid T. [email protected]
wrote:

makedir(‘subdir’)
end

add

:force => true

to the call to
FileUtils.mv subdir, ‘.’, :verbose => true

Chuck, you should also be aware that you move directories up one level
as well. Is this what you want?

Kind regards

robert

On Sep 26, 2011, at 6:04 AM, Robert K. wrote:

Dir.chdir(‘dir’) do
FileUtils.mv subdir, ‘.’, :verbose => true
as well. Is this what you want?
Robert, yes, my original message (first line) said that was my goal.

BTW, adding the :force => true option made this work. I am still puzzled
as to why (I should probably look at the underlying implementation) but
I am satisfied for now.

Thanks all for the help.

cr