Thursday, November 22, 2007

Zip A Directory With Ruby


I just found a new gem called rubyzip. Which is nice for creating regular old zip files. Ruby comes with zlib, but that is for gzip files which are not too friendly for windows users. Not that I condone the practice of using windows... Anyway. To install just type 'gem install rubyzip'. Here is some code I am using to zip up an entire directory called 'src', excluding hidden files. Just remove the Find.prune line if you don't want to exclude anything.


require 'rubygems'
require 'zip/zip'
require 'find'
require 'fileutils'
include FileUtils

root = pwd+'/src'
new_zip_file = pwd+'/newzipfile.zip'

Zip::ZipFile.open(new_zip_file, Zip::ZipFile::CREATE)do |zipfile|
Find.find(root) do |path|
Find.prune if File.basename(path)[0] == ?.
dest = /src\/(\w.*)/.match(path)
zipfile.add(dest[1],path) if dest
end
end


By the way sorry for no code formatting or highlighting. If only blogger had support for such useful stuff. I bet devastatin dave has code highlighting on his website. Hmm, I wonder what devastatin dave has been doing since 1986?

2 comments:

Unknown said...

hi cuberick,

i used your code in my app.
everything goes well when zipping files without japanese files/folders.
however when there is japanese, zip failed.

i have a question in this part "zipfile.add(dest[1],path) if dest"

what is the purpose of checking "if dest". when i trace the code dest == path. why dest[1]?
i am sorry but i'm new to ruby.

thanks in advance.

Shlomo said...

Hey vernick,

I couldn't say for sure what your problem is without seeing the exact code you are using and what the specific error was.

Dest is a match object that is the result of calling the match method on that regex. If you notice the parens in the regex, those are creating a group. The 0th element of the match object is the entire matched string. The 1st element is just what was matched by the first group (google regex grouping if you don't understand this). Dest is going to be nil if there is no match so the if dest is a guard clause that will prevent me trying to index into a nil object.

Hope that helps. Like i said if you still can't figure this out provide more specific error messages and context to the problem and i'll try to help.