How to Copy Folders Recursively With Ruby
Ruby, out of the box, provides many useful classes for working with files and directories. Most of these handy-dandy methods can be found on the FileUtils class. Ruby even makes it easy to copy directories recursively. Since recursive directory copying is the topic of the day, I thought I’d burn a few lines talking about just that. The FileUtils.cp_r method is a fine way to copy directories recursively. It works exactly as advertised.
The FileUtils class, IMHO, has a missing a method. It’s a method very similar in behavior to cp_r, that accepts a list of files to ignore/exclude recursively. If for some wacky reason you also have a need for this behavior, then you’re in luck.
Below you’ll find a tiny script that allows you to do just that. You can initialize the object with an array of files or patterns to exclude, then invoke the solitary copy method. That’s all there is to it. The script will recursively copy the source directory to the destination directory and compare each file against your exclude list.
require 'FileUtils'
class DaCopier
def initialize(exclude)
@exclude = exclude
end
def copy src, dest
stage dest
Dir.foreach(src) do |file|
next if exclude?(file)
s = File.join(src, file)
d = File.join(dest, file)
if File.directory?(s)
FileUtils.mkdir(d)
copy s, d
else
FileUtils.cp(s, d)
end
puts d
end
end
private
def stage dest
if File.directory?(dest)
FileUtils.rm_rf(dest)
end
FileUtils.mkdir(dest)
end
def exclude? file
@exclude.each do |s|
if file.match(/#{s}/i)
return true
end
end
false
end
end
src = '/Users/Emilio/Dropbox'
dest = '/Users/Emilio/Dropbox 2'
exclude = ["^\\.", "_old", "cheese.jpg"]
dc = DaCopier.new(exclude)
dc.copy src, dest
DISCLAIMER: This script is not battle tested and you’ll probably want to run it through your own tests before using it in any production scenario.