gradle - download and unzip file from url
Solution 1
There isn't currently a Gradle API for downloading from a URL. You can implement this using Ant, Groovy, or, if you do want to benefit from Gradle's dependency resolution/caching features, by pretending it's an Ivy repository with a custom artifact URL. The unzipping can be done in the usual Gradle way (copy
method or Copy
task).
Solution 2
Let's say you want to download this zip file as a dependency:
https://github.com/jmeter-gradle-plugin/jmeter-gradle-plugin/archive/1.0.3.zip
You define your ivy repo as:
repositories {
ivy {
url 'https://github.com/'
patternLayout {
artifact '/[organisation]/[module]/archive/[revision].[ext]'
}
// This is required in Gradle 6.0+ as metadata file (ivy.xml)
// is mandatory. Docs linked below this code section
metadataSources { artifact() }
}
}
reference for required metadata here
The dependency can then be used as:
dependencies {
compile 'jmeter-gradle-plugin:jmeter-gradle-plugin:1.0.3@zip'
//This maps to the pattern: [organisation]:[module]:[revision]:[classifier]@[ext]
}
To unzip:
task unzip(type: Copy) {
def zipPath = project.configurations.compile.find {it.name.startsWith("jmeter") }
println zipPath
def zipFile = file(zipPath)
def outputDir = file("${buildDir}/unpacked/dist")
from zipTree(zipFile)
into outputDir
}
optional:
If you have more than one repository in your project, it may also help (for build time and somewhat security) to restrict dependency search with relevant repositories.
Gradle 6.2+:
repositories {
mavenCentral()
def github = ivy {
url 'https://github.com/'
patternLayout {
artifact '/[organisation]/[module]/archive/[revision].[ext]'
}
metadataSources { artifact() }
}
exclusiveContent {
forRepositories(github)
filter { includeGroup("jmeter-gradle-plugin") }
}
}
Earlier gradle versions:
repositories {
mavenCentral {
content { excludeGroup("jmeter-gradle-plugin") }
}
ivy {
url 'https://github.com/'
patternLayout {
artifact '/[organisation]/[module]/archive/[revision].[ext]'
}
metadataSources { artifact() }
content { includeGroup("jmeter-gradle-plugin") }
}
}
Solution 3
plugins {
id 'de.undercouch.download' version '4.0.0'
}
/**
* The following two tasks download a ZIP file and extract its
* contents to the build directory
*/
task downloadZipFile(type: Download) {
src 'https://github.com/gradle-download-task/archive/1.0.zip'
dest new File(buildDir, '1.0.zip')
}
task downloadAndUnzipFile(dependsOn: downloadZipFile, type: Copy) {
from zipTree(downloadZipFile.dest)
into buildDir
}
https://github.com/michel-kraemer/gradle-download-task
Solution 4
Unzipping using the copy task works like this:
task unzip(type: Copy) {
def zipFile = file('src/dists/dist.zip')
def outputDir = file("${buildDir}/unpacked/dist")
from zipTree(zipFile)
into outputDir
}
http://mrhaki.blogspot.de/2012/06/gradle-goodness-unpacking-archive.html
Solution 5
This works with Gradle 5 (tested with 5.5.1):
task download {
doLast {
def f = new File('file_path')
new URL('url').withInputStream{ i -> f.withOutputStream{ it << i }}
}
}
Calling gradle download
downloads the file from url
to file_path
.
You can use the other methods from other answers to unzip the file if necessary.
Related videos on Youtube
Peter Butkovic
Updated on May 19, 2021Comments
-
Peter Butkovic about 3 years
What would be the proper gradle way of downloading and unzipping the file from url (
http
)?If possible, I'd like to prevent re-downloading each time I run the task (in
ant.get
can be achieved byskipexisting: 'true'
).My current solution would be:
task foo { ant.get(src: 'http://.../file.zip', dest: 'somedir', skipexisting: 'true') ant.unzip(src: 'somedir' + '/file.zip', dest: 'unpackdir') }
still, I'd expect ant-free solution. Any chance to achieve that?
-
Peter Niederwieser about 10 yearsDon't forget to wrap the execution part of a task with
doLast { ... }
(same mistake as in your previous question). -
CMPS over 8 years~~BOUNTY~~ Can anyone provide an example for the answer below: "if you do want to benefit from Gradle's dependency resolution/caching features, by pretending it's an Ivy repository with a custom artifact URL" ?
-
koppor over 4 yearsnetflix has released some plugin: github.com/nebula-plugins/nebula-core - not sure, why this is not maintained anymore.
-
-
xpmatteo about 9 yearsI would appreciate an example... I'm a total gradle newbie!
-
CMPS over 8 years~~BOUNTY~~ Can anyone provide an example for this answer "if you do want to benefit from Gradle's dependency resolution/caching features, by pretending it's an Ivy repository with a custom artifact URL" ?
-
RaGe over 8 years@CMPS why you no groovy?
-
CMPS over 8 years@RaGe my current solution is using groovy and it works fine, but I wanted one using repository to benefit from the caching system.
-
RaGe over 8 years@CMPS Ah, caching! Posted an answer below.
-
addy over 8 years@RaGe how does 1.0.3:class@zip get matched to [revision].[ext] ?
-
RaGe over 8 years@addy
class
in that string is a classifier. It is optional, and here it isn't being used in the ivy url at all.1.0.3
is revision andzip
is ext. -
peuhse about 8 yearsIs this for android or java? I'm trying to use it but it seems like "project.configuration.compile" does not exist? I've tried to add apply java before in the script, but that does not make a difference. Can't find it in the documentation either. Using com.android.tools.build:gradle:2.1.0 and version 2.10 of gradle.
-
RaGe about 8 years@peuhse it should be
project.configurations
, mind thes
in configurations. The android plugin implicitly adds the java plugin to a project. It shouldn't matter if you add it explicitly again. -
peuhse about 8 yearsIt was a spelling mistake by me. When I write project.configurations and let the IDE autofill the possibilites the compile isn't one of them. And then I get a build error. Commenting out the line makes it build again.
-
RaGe about 8 yearsplease raise a new question, and refer to this one.
-
Akom about 7 yearsUnfortunately URLs with query strings cannot be accessed this way, '?' is encoded by github.com/gradle/gradle/blob/master/subprojects/resources/src/…
-
Sourav Bhattacharjee almost 6 yearsWhen I am trying this rather than looking for .zip file it is looking for a .xml file. Any way around for this? I followed exactly the same instruction.
-
Victor Lyuboslavsky almost 6 yearsDoesn't work for me. Gradle is looking for an ivy.xml file in addition to the artifact.
-
dexter2305 over 5 yearsI tried moving the
from zipTree() & into outputDir
to the execution phase by moving them todoLast { }
. What I did not understand was that it never worked. Even theprintln
code indoLast
did not work. However, this code works in the gradle configuration phase. Why? -
barfuin about 5 yearsUnfortunately, this solution also has Gradle looking for an Ivy XML file.
-
Michael S. over 4 yearsThis is not really a good solution compared to Ant as it is really slow. 26 minutes download instead of 2 minutes with Chrome.
-
Vampire over 4 yearsBecause it configures the task. The execution still is done during execution phase. Changing the configuration during the execution phase should not be done actually and in your case the execution phase would not be executed at all, as the task thinks there is nothing to copy, so the task execution is skipped. But actually this answer is not related to the question anyway, as this does not work with an HTTP URL.
-
Abhijit Sarkar over 3 yearsDoes work, as others have stated, Gradle looks for
.xml
file. -
Andy Brown over 3 yearsThis is a great answer. I would only add that the dependency should probably be compileOnly to prevent the raw zip ending up in the runtime artifacts.
-
camikiller almost 3 yearsAlso works in gradle 4.7. In case someone needs it.
-
Greg Domjan almost 3 yearsgradle 7 now changing configurations - 'compile' removed. adding a configuration in replacement or updating to the new names still worked.
-
rios0rios0 over 2 yearsDoesn't work. Gradle 7.2 is looking for a normal maven dependency.
-
rios0rios0 over 2 yearsDoesn't work. Gradle 7.2 is looking for a normal maven dependency.
-
RaGe over 2 years@rios0rios0 I'd expect gradle to look in all available repositories for all dependencies. If you want to restrict certain deps to certain repos, see the
optional
section in the answer -
elect over 2 yearsI can confirm this works with 7.2, @rios0rios0 have you resolved?
-
rios0rios0 over 2 years@elect I solved it in another way. Because I spent a lot of time trying to work with this approach. Community on Gradle's Slack said a better way to handle my original issue. But thanks for confirming that's working. Here Gradle wasn't recognizing the pattern "/[organisation]/[module]/archive/[revision].[ext]" on dependencies.