Create a zip file using Rake::PackageTask

1.3k views Asked by At

I am trying to package up a zip file in my rake file and I am pretty inexperienced with Rake and ruby, so I am having a hard time identifying why this is failing.

This is what I have tried:

def create_zip_file(targetDirectory, projectToZip)
    puts "target:" + targetDirectory
    puts "Zipping " + projectToZip
    semver_contents = get_contents_of('SEMVER')
    zipFileName = 'ProjectName.' + semver_contents
    puts zipFileName
    files_to_include = "../"+ projectToZip + "/bin/" + BUILD_CONFIG + "/**"
    puts "Including the following files: " + files_to_include
    Rake::PackageTask.new(zipFileName, semver_contents) do |p|
        p.need_zip = true
        p.package_files.include(files_to_include)
    end
end

My task invocation looks like this:

exec(:package_zip) {create_zip_file DEPLOY_DIRECTORY, 'ProjectName'} 

And I am calling it like so:

bundle exec rake package_zip

Now, the command window that I am running this from lists the contents of all of the put statements I have in the script, so I assume that the failure is occurring internally to the PackageTask task.

The error output in the console looks like this:

Exec failed, see the build log for more details.
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/albacore-1.0.0/lib/albacore/support/failure.rb:12:in `fail_with_message'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/albacore-1.0.0/lib/albacore/exec.rb:18:in `execute'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/albacore-1.0.0/lib/albacore/support/createtask.rb:24:in `block in exec'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:240:in `call'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:240:in `block in execute'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:235:in `each'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:235:in `execute'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:179:in `block in invoke_with_call_chain'
C:/tools/ruby200/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:172:in `invoke_with_call_chain'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:201:in `block in invoke_prerequisites'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:199:in `each'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:199:in `invoke_prerequisites'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:178:in `block in invoke_with_call_chain'
C:/tools/ruby200/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:172:in `invoke_with_call_chain'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/task.rb:165:in `invoke'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:150:in `invoke_task'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:106:in `block (2 levels) in top_level'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:106:in `each'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:106:in `block in top_level'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:115:in `run_with_threads'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:100:in `top_level'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:78:in `block in run'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/lib/rake/application.rb:75:in `run'
C:/tools/ruby200/lib/ruby/gems/2.0.0/gems/rake-10.4.2/bin/rake:33:in `<top (required)>'
C:/tools/ruby200/bin/rake:23:in `load'
C:/tools/ruby200/bin/rake:23:in `<main>'
Tasks: TOP => package => package_zip

The likelyhood is I have missed something pretty obvious or done something stupid, just having a hard time catching it.

2

There are 2 answers

0
David Watts On BEST ANSWER

After talking with a few people around the office, trying lots of different things relating to Pauls answer, I finally found a solution, and that was to not use the package task at all. Instead, we used rubyzip.

Here is what we ended up with

def create_zip_file(targetDirectory, projectToZip)
    semver_contents = get_contents_of('SEMVER')
    zipFileName = "#{targetDirectory}/#{projectToZip}.#{semver_contents}.zip"
    filesToZip =  FileList["../#{projectToZip}/bin/#{BUILD_CONFIG}/**"]   
    Zip::File.open(zipFileName, Zip::File::CREATE) do |zipFile|
        filesToZip.each do |filename|
            zipFile.add(filename, filename)
        end
    end     
end
1
Paul D'Ambra On

the exec task tells rake to run things at the command line / shell. Not to run a task.

you probably want to:

task :package_zip do
    create_zip_file DEPLOY_DIRECTORY, 'ProjectName'
end

also all of your variable should be snake case. it's not a big deal though just more easily readable Ruby.

and you really want to look into string interpolation which will make your life easy

so for example

puts "target: #{target_directory}"
puts "Zipping #{project_to_zip}"
semver_contents = get_contents_of('SEMVER')
zipFileName = "ProjectName.#{semver_contents}"

(code sample provided without running it so beware!)


Ah, also, looking at the docs for PackageTask

Your code that runs Rake::PackageTask.new only creates other tasks - it doesn't actually run them!

This article shows an example of usage

    # Have to keep a reference to the PackageTask object
package_task = Rake::PackageTask.new("gliffy-php-client",GLIFFY_VERSION) do |p|
    p.need_tar = true
    p.need_zip = true
    # Executed BEFORE any other tasks; DOC_FILES don't exist  yet
    p.package_files = SRC_FILES + EXAMPLE_FILES
end

file package_task.package_dir_path => DOC_DIR

file DOC_DIR => SRC_FILES + EXAMPLE_FILES do |t|
    system("phpdoc #{PHP_DOC_ARGS}");
    doc_files = FileList.new(DOC_DIR + "/**/**");
    # Have to add these files to the package_task file list
    package_task.package_files = package_task.package_files + doc_files
end

However, if you look at the source of the task it ultimately just calls into the shell with a filelist and the zip command. If you know that zip is on the path on whatever machine will be running your task (or where it is installed) you might be better simply running something like:

task :make_zip do
  semver_contents = get_contents_of('SEMVER')
  zipFileName = "ProjectName.#{semver_contents}"
  targetDir = "../#{projectToZip}/bin/#{BUILD_CONFIG}/**"
 `zip -r #{zipFileName} #{targetDir}`
end