From: dblack@... Date: 2007-08-29T08:57:08+09:00 Subject: Re: Deleting empty directories Hi -- On Wed, 29 Aug 2007, Paul van Delst wrote: > Hello, > > I'm putting together a script to automatically update a repository working > copy. The scenario is such that the versioned working copy itself is not > being modified, but I am simply rsync'ing changes from an unversioned source > (i.e. just a bunch of directories), and then committing (and then tagging) > those files. It sounds weird, I know, but it's just temporary. Honest. > > Anyway, the need has arisen to delete empty directory heirarchies (rsync will > delete the files but not the directories because of the .svn subdirs). What > I've done so far is this: > > require 'fileutils' > > def empty_dirs > @current.collect do |f| > f if (File.directory?(f) && Dir.glob("#{f}/*").empty?) > end.compact > end > > def remove_empty_dirs > while not empty_dirs.empty? > empty_dirs.each {|d| FileUtils.rm_rf(d)} > end > end > > where the @current contains the updated list of files in my versioned working > copy after I rsync'd, but before I started comparing the changes in my > working copy. I created a dummy repository with a relatively complicated > heirarchy of directories to test the above and it seems to work. However, two > things bug me: > > Firstly, in empty_dirs, I think > > f if (File.directory?(f) && Dir.glob("#{f}/*").empty?) > > looks ugly. My limited experience is that if something looks ugly it can > usually be expressed better. I haven't used collect too much either, so its > intricacies escape me. You're currently using collect plus compact, but you can actually just use select. (That's not a general equivalence, but in this case it applies.) @current.select do |f| File.directory?(f) && Dir["#{f}/*"].empty? end I'd be inclined to break things out a little. (Untested code follows -- please test on expendable data :-) require 'fileutils' def dirs @current.select {|f| File.dir?(f) } end def empty_dirs dirs.select {|d| Dir["#{d}/*"].empty? } end def non_empty_dirs dirs - empty_dirs end def remove_empty_dirs non_empty_dirs.each {|d| FileUtils.rm_rf(d) } end > Secondly, I prefer not to test for negatives, as in > > while not empty_dirs.empty? You can use until instead of while not. > I also would rather not have an open loop either, but if a directory contains > empty subdirectories, the parent directory is not considered empty, and etc. > etc. As you can probably tell, recursion is not my strong point. > > Would any kind soul out there care to provide any pointers for cleaning up > the methods above? > > Thanks for any info, > > cheers, > > paulv > > p.s. BTW, I think the remove_empty_dirs method still needs to remove the > deleted directories from @current to prevent them being tested again in the > next call to empty_dirs. Or you can reset @current before each call, or some combination. I haven't done either in my sample code; I'm just assuming that @current is what it should be, but you'll definitely have to factor that in. David -- * Books: RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242) RUBY FOR RAILS (http://www.manning.com/black) * Ruby/Rails training & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)