views:

345

answers:

2

I need to delete a bunch of subdirectories that only contain other directories, and ".svn" directories.

If you look at it like a tree, the "leaves" contain only ".svn" directories, so it should be possible to delete the leaves, then step back up a level, delete the new leaves, etc.

I think this code should do it, but I'm stuck on what to put in "something".

Find.find('./com/') do |path|
    if File.basename(path) == 'something'
        FileUtils.remove_dir(path, true)
        Find.prune
    end
end

Any suggestions?

A: 

This would do the job... however it doesn't take into consideration, that the it's own run could create new leaves

#!/usr/bin/env ruby

require 'fileutils'

def remove_leaves(dir=".")
  Dir.chdir(dir) do 
    entries=Dir.entries(Dir.pwd).reject { |e| e=="." or e==".."}
    if entries.size == 1 and entries.first == ".svn"
      puts "Removing #{Dir.pwd}"
      FileUtils.rm_rf(Dir.pwd)
    else
      entries.each do |e|
        if File.directory? e
          remove_leaves(e)
        end
      end
    end
  end
end

remove_leaves

Greets Seb

flitzwald
+1  A: 

This one takes new leaves into account (sort.reverse for entries means that /a/b/.svn is processed before /a/b; thus if /a/b is otherwise empty, it will be removed and size<=2 is because with FNM_DOTMATCH glob will always return a minimum of 2 entries ('.' and '..'))

require 'fileutils'

def delete_leaves(dirname)
    Dir.glob(dirname+"/**/",File::FNM_DOTMATCH).sort.reverse.each do |d|
        FileUtils.rm_rf(d) if d.match(/.svn/) or Dir.glob(d+"/*",File::FNM_DOTMATCH).size<=2  
    end  
end
delete_leaves(ARGV[0])
This worked quite nicely, thanks!
kraryal