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?
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).
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
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).