问题
Is it possible to download gradle dependencies using only build.gradle file?
What I am trying to accomplish is the following:
I have a set of unit tests and I want to execute them (as part of CI process) inside a docker container. Initially, I used the openjdk:8-jdk image from docker hub as base image for my tests. So, docker compose file contains the following:
version: '3.2'
services:
unit:
image: openjdk:8-jdk
volumes:
- ..:/usr/test
working_dir: /usr/test
command: sh -c "exec ./gradlew junitPlatformTest -Punit -p moduleA/"
Whole project is mounted on /usr/test directory inside the container. When the container starts, it executes the junitPlatformTest task against moduleA. The problem with openjdk:8-jdk image is that gradle and its dependencies are downloaded every time I run the unit service.
To solve this, I decided to create a new image which would have gradle and my project dependencies already downloaded. The Dockerfile is the following:
FROM openjdk:8-jdk
COPY . /usr/test
WORKDIR /usr/test
RUN apt-get -y install wget unzip
RUN wget https://services.gradle.org/distributions/gradle-4.1-bin.zip
RUN mkdir /opt/gradle
RUN unzip -d /opt/gradle gradle-4.1-bin.zip
RUN /opt/gradle/gradle-4.1/bin/gradle dependencies
The build.gradle file is located in same folder as Dockerfile so the command COPY . /usr/test copies it in the working directory.
However, executing the gradle dependencies command does not download the libraries. After built the image, ran a container and entered into it (with docker exec), it seems that ~/.gradle/caches/modules-2/files-2.1/ directory contains only pom files, not jars.
I'm not use if gradle dependencies is the correct command. Any suggestions?
EDIT - Gradle file
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
jcenter()
}
ext.versions = new Properties()
file("./versions.properties").withInputStream {
stream -> ext.versions.load(stream)
}
dependencies {
testCompile("org.junit.jupiter:junit-jupiter-api:$versions.junitJupiterVersion")
testCompile("org.junit.jupiter:junit-jupiter-engine:$versions.junitJupiterVersion")
testCompile("org.junit.jupiter:junit-jupiter-params:$versions.junitJupiterVersion")
testCompile("org.mockito:mockito-core:'$versions.mockitoCore")
testCompile("org.junit.platform:junit-platform-launcher:1.0.0-RC3")
compile("com.google.inject:guice:$versions.guice")
....
}
回答1:
Add below to your gradle file
task download (type: Exec) {
configurations.testCompile.files
commandLine 'echo', 'Downloaded all dependencies'
}
Also change
RUN /opt/gradle/gradle-4.1/bin/gradle dependencies
to
RUN /opt/gradle/gradle-4.1/bin/gradle
This will cache all dependencies to ~/.gradle when you run the gradle command. It will download the jars also and not just poms. And if you want to cache further you can even use a named volume for gradle folder
version: '3.2'
services:
unit:
image: openjdk:8-jdk
volumes:
- ..:/usr/test
- gradlecache:/root/.gradle/
working_dir: /usr/test
command: sh -c "exec ./gradlew junitPlatformTest -Punit -p moduleA/"
volumes:
gradlecache: {}
回答2:
Your idea is right but the approach is wrong. First of all, there is no need to download and install Gradle manually, that's exactly what the Gradle Wrapper does for you. Second of all, there is no need to hack Gradle to force download dependencies - it doesn't make any sense. Just check out/clone your test project from inside the container and run your tests with ./gradlew clean test. There is no need for a local /usr/test directory, which is flies in the face of CI, because it uses a relative location, and hence only works when you've laid out files in an exact manner.
Edit:
If you don't want to download Gradle or the dependencies for every build, you can start the container by volume mapping the$HOME/.m2 directory to the host, so that dependencies downloaded once stay in the Maven local cache. To avoid downloading Gradle, you can build your own Docker image with Gradle in it.
来源:https://stackoverflow.com/questions/46057457/download-dependencies-given-only-the-build-gradle-file