How do I define a list for an Exec task to act upon individually?


(Nho Jotom) #1

I need to download a set of files from URLs if they aren’t already download and then extract (e.g. unzip) them if they haven’t already been extracted. What I’d like to do is to define downloadArchives and extractArchives tasks and be able to pass a list to them or configure a variable that they can use. The exec would not execute if it was not needed. How would I do this?


(Peter Niederwieser) #2

For ‘extractArchives’ you’d use a ‘Copy’ task together with a ‘zipTree’ (see “16. Working with files” in the Gradle User Guide). The ‘Copy’ task will automatically make sure that it only runs when necessary. If the tasks were to share some state, you’d use a local variable (‘def’) in the main script, or an ‘extra property’ on one of the tasks (see “6.9. Extra task properties” in the Gradle User Guide).


(Nho Jotom) #3

Hi Peter,

thanks for the quick reply. For the downloadArchives task, what I’ve done is something like this:

# In Properties file
archives = ["a","b","c"]
  # In build script download.gradle
  task downloadArchives << {
   archives.each {def archive ->
      archiveFile = new File("$archive")
        if (archiveFile.exists()) {
         downloadArchive(archive)
      }
   }
}
  def downloadArchive(String archiveName) {
   def archiveFos = new FileOutputStream(archiveName)
   def out = new BufferedOutputStream(archiveFos)
   out << new URL("http://wherever/" + archiveName).openStream()
   out.close()
}

I was hoping to use a task for this but I don’t know how to pass the archive name to a downloadArchive task. Does this approach look like a best practices approach?

Thanks


(Peter Niederwieser) #4

If all archives are always required, it’s OK to use a single task to download them. The implementation of the task could be improved: the input stream isn’t closed, the output stream isn’t closed if an exception occurs (instead you could just use ‘archiveFile << inputStream’), ‘archiveFile’ should be used instead of ‘archiveName’ for the destination file, ‘project.file’ should (always) be used instead of ‘new File’ (the former interprets relative paths relative to the project dir, the latter relative to the process working dir).