1

In Rake, I can use the following syntax to declare that task charlie requires tasks alpha and bravo to have been completed first.

task :charlie => [:alpha, :bravo]

This seems to work fine if charlie is a typical Rake task or a file task but I cannot figure out how to do this for a Rake::PackageTask. Here are the relevant parts of the rakefile so far:

require 'rake/packagetask'

file :package_jar => [:compile] do
   puts("Packaging library.jar...")
   # code omitted for brevity, but this bit works fine
end

Rake::PackageTask.new("library", "1.0") do |pt|
   puts("Packaging library distribution artefact...")
   pt.need_tar = true
   pt.package_files = ["target/library.jar"]
end
task :package => :package_jar

What's happening here is that, for a clean build, it complains that it doesn't "know how to build task 'target/library.jar'". I have to run rake package_jar from the command line manually to get it to work, which is a bit of a nuisance. Is there any way I can make package depend on package_jar?

For what it's worth, I am using Rake version 0.9.2.2 with Ruby 1.8.7 on Linux.

ATG
  • 1,679
  • 14
  • 25

3 Answers3

1

When you run rake package (without previously running anything else to create any needed files) Rake sees that the package task needs the file target/library.jar. Since this file doesn’t yet exist Rake checks to see if it knows how to create it. It doesn’t know of any rules that will create this file, so it fails with the error you see.

Rake does have a task that it thinks will create a file named package_jar, and that task in fact creates the file target/library.jar, but it doesn’t realise this.

The fix is to tell Rake exactly what file is created in the file task. Rake will then automatically find the dependency.

Change

file :package_jar => [:compile] do

to

file 'target/library.jar' => [:compile] do

and then remove the line

task :package => :package_jar

since package_jar no longer exists and Rake will find the dependency on the file by itself.

matt
  • 78,533
  • 8
  • 163
  • 197
  • This works, thanks. It does seem crazy, though, that you're forced to name your tasks after the artefact they produce rather than what they actually do! I don't suppose there's a way around this, is there? – ATG Dec 18 '13 at 02:01
  • @ATG In the case of `file` tasks I think it makes sense to name them after the file being created. You’re telling Rake “this is what you do to create this file”, and this means that if Rake needs to create the file (like in this case) it knows what to do. You could always add `task :package_jar => 'target/library.jar'` if you wanted to be able to call that task by itself with an easier name. – matt Dec 18 '13 at 03:32
  • I understand your point, but I'm used to being able to give my tasks/methods etc. meaningful names that describe what they do. It also seems strange given that conventional build tasks such as "compile" and "test" are named after the action being performed rather than the result of the operation. Anyway, thanks for your help! – ATG Dec 18 '13 at 17:03
0

In general in rake, if you want to add a dependency to a task, you need that task's name. So you need to figure out the name of the actual rake task that Rake::PackageTask is registering.

The easiest way to do this is by running with --trace — it lists each task's name as it is executing.

(I believe the name of a buildr package task is the filename of the package it produces, but I don't remember for certain. Use --trace to find out.)

Rhett Sutphin
  • 1,045
  • 8
  • 15
  • Running 'rake package --trace' yields the following after the stack trace: Tasks: TOP => package => target/library-1.0.tgz and adding 'task "target/library-1.0.tgz" => :package_jar' to the rakefile doesn't change anything. It still seems to be looking for the actual JAR file as a prerequisite task, oddly. – ATG Dec 17 '13 at 05:18
0

You can add a dependency to any task by writing,

someTask.enhance [other, tasks]

where other and tasks can be either task names or task objects.

So in your case, you could write:

library = Rake::PackageTask.new(...) do
  ...
end

task(:package).enhance([library])
Alex Boisvert
  • 2,850
  • 2
  • 19
  • 18
  • This doesn't work, I'm afraid. It fails with: "Don't know how to build task '#'", which seems to suggest that Rake::PackageTask isn't even a proper rake task! Any ideas? – ATG Dec 17 '13 at 05:45