diff --git a/pom.xml b/pom.xml
index 7e51a9c..cd85853 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,6 +140,10 @@
${version.gradle.7}
${version.groovy}
+
+ ${project.build.directory}
+ ${version.gradle.8}
+
diff --git a/src/it/gradle-tooling-api/invoker.properties b/src/it/gradle-tooling-api/invoker.properties
new file mode 100644
index 0000000..3c10d00
--- /dev/null
+++ b/src/it/gradle-tooling-api/invoker.properties
@@ -0,0 +1 @@
+invoker.goals.1=verify
diff --git a/src/it/gradle-tooling-api/pom.xml b/src/it/gradle-tooling-api/pom.xml
new file mode 100644
index 0000000..fa29176
--- /dev/null
+++ b/src/it/gradle-tooling-api/pom.xml
@@ -0,0 +1,37 @@
+
+
+ 4.0.0
+ com.marcnuri.plugins.it
+ no-action
+ 0.1-SNAPSHOT
+ Maven Integration Test :: Gradle API :: Gradle Tooling API
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ ${version.groovy}
+ pom
+ provided
+
+
+ org.gradle
+ gradle-all
+ ${version.gradle.8}
+ provided
+
+
+
+
+
+
+ com.marcnuri.plugins
+ gradle-api-maven-plugin
+ @project.version@
+ true
+
+
+
+
diff --git a/src/it/gradle-tooling-api/verify.groovy b/src/it/gradle-tooling-api/verify.groovy
new file mode 100644
index 0000000..b94ab2b
--- /dev/null
+++ b/src/it/gradle-tooling-api/verify.groovy
@@ -0,0 +1,18 @@
+import java.util.jar.JarFile
+
+def gradleToolingApiJar = new File(projectBuildDirectory,
+ "local-repo/org/gradle/gradle-tooling-api/${versionGradle8}/gradle-tooling-api-${versionGradle8}.jar")
+assert gradleToolingApiJar.exists()
+def jar = new JarFile(gradleToolingApiJar)
+def containsManifest = false
+def containsGradleApi = false
+jar.entries().each {
+ if (it.name == 'META-INF/MANIFEST.MF') {
+ containsManifest = true
+ }
+ if (it.name.startsWith('org/gradle/api/')) {
+ containsGradleApi = true
+ }
+}
+assert containsManifest
+assert containsGradleApi
diff --git a/src/it/maven.settings.https-auth-proxy/verify.groovy b/src/it/maven.settings.https-auth-proxy/verify.groovy
index bb821d0..37bc304 100644
--- a/src/it/maven.settings.https-auth-proxy/verify.groovy
+++ b/src/it/maven.settings.https-auth-proxy/verify.groovy
@@ -8,3 +8,4 @@ new FileWriter(new File(basedir, 'access.log')).withWriter { it << logOut }
assert logOut.toString().contains('CONNECT services.gradle.org:443')
def buildLog = new File(basedir, 'build.log').text
assert buildLog.contains('Gradle 8.2.1 download complete')
+assert buildLog.contains('Gradle Tooling API 8.2.1 download complete')
diff --git a/src/it/system.properties.https-auth-proxy/verify.groovy b/src/it/system.properties.https-auth-proxy/verify.groovy
index bb821d0..37bc304 100644
--- a/src/it/system.properties.https-auth-proxy/verify.groovy
+++ b/src/it/system.properties.https-auth-proxy/verify.groovy
@@ -8,3 +8,4 @@ new FileWriter(new File(basedir, 'access.log')).withWriter { it << logOut }
assert logOut.toString().contains('CONNECT services.gradle.org:443')
def buildLog = new File(basedir, 'build.log').text
assert buildLog.contains('Gradle 8.2.1 download complete')
+assert buildLog.contains('Gradle Tooling API 8.2.1 download complete')
diff --git a/src/it/system.properties.https-proxy/verify.groovy b/src/it/system.properties.https-proxy/verify.groovy
index f4e9b5b..14d734f 100644
--- a/src/it/system.properties.https-proxy/verify.groovy
+++ b/src/it/system.properties.https-proxy/verify.groovy
@@ -8,3 +8,4 @@ new FileWriter(new File(basedir, 'access.log')).withWriter { it << logOut }
assert logOut.toString().contains('CONNECT services.gradle.org:443')
def buildLog = new File(basedir, 'build.log').text
assert buildLog.contains('Gradle 8.2.1 download complete')
+assert buildLog.contains('Gradle Tooling API 8.2.1 download complete')
diff --git a/src/main/java/com/marcnuri/plugins/gradle/api/GradleApi.java b/src/main/java/com/marcnuri/plugins/gradle/api/GradleApi.java
index e7ee561..c3aaabe 100644
--- a/src/main/java/com/marcnuri/plugins/gradle/api/GradleApi.java
+++ b/src/main/java/com/marcnuri/plugins/gradle/api/GradleApi.java
@@ -24,7 +24,9 @@ public class GradleApi implements Callable> {
static final String GRADLE_GROUP_ID = "org.gradle";
static final String GRADLE_ALL_ARTIFACT_ID = "gradle-all";
+ static final String GRADLE_TOOLING_API_ARTIFACT_ID = "gradle-tooling-api";
static final String GRADLE_DISTRIBUTION_BASE_URL = "https://services.gradle.org/distributions/";
+ static final String GRADLE_LIB_RELEASES_BASE_URL = "https://repo.gradle.org/artifactory/libs-releases/";
private final GradleApiLog log;
private final Proxy proxy;
private final boolean forceUpdate;
@@ -45,25 +47,18 @@ public GradleApi(GradleApiLog log, Proxy proxy, boolean forceUpdate, String grad
@Override
public final Collection call() {
if (forceUpdate || !gradleBinZip.toFile().exists()) {
- download();
+ downloadDistribution();
+ downloadGradleToolingApi();
}
return extract();
}
- private void download() {
+ private void downloadDistribution() {
log.info("Downloading Gradle " + gradleVersion + "...");
try {
- final URL remoteBin = new URL(GRADLE_DISTRIBUTION_BASE_URL + gradleBinZip.toFile().getName());
- // Connection
- final InputStream stream;
- if (proxy == null) {
- stream = remoteBin.openStream();
- } else {
- log.info("Using proxy");
- stream = remoteBin.openConnection(proxy).getInputStream();
- }
Files.createDirectories(resolveGroupDir());
- writeToFile(stream, gradleBinZip);
+ final InputStream gradleBinStream = streamUrl(GRADLE_DISTRIBUTION_BASE_URL + gradleBinZip.toFile().getName());
+ writeToFile(gradleBinStream, gradleBinZip);
writePom(GRADLE_ALL_ARTIFACT_ID, "pom");
log.info("Gradle " + gradleVersion + " download complete");
} catch (IOException e) {
@@ -71,6 +66,27 @@ private void download() {
}
}
+ /*
+ * Gradle tooling api artifact needs to be downloaded from the Maven repository.
+ * This artifact is published by Gradle to https://repo.gradle.org/ui/native/libs-releases/
+ * The published artifact is different from that included in the Gradle official distribution.
+ * It's published to Maven to add support for IDEs and other tools to interact with Gradle,
+ * and includes additional classes that are not included in the Gradle distribution.
+ * (org.gradle.wrapper, org.gradle.internal, org.gradle.api, and more)
+ */
+ private void downloadGradleToolingApi() {
+ log.info("Downloading Gradle Tooling API " + gradleVersion + "...");
+ try {
+ final InputStream gradleToolingApi = streamUrl(GRADLE_LIB_RELEASES_BASE_URL +"org/gradle/gradle-tooling-api/" +
+ gradleVersion + "/" + GRADLE_TOOLING_API_ARTIFACT_ID + "-" + gradleVersion + ".jar");
+ writeToFile(gradleToolingApi, resolveArtifactJar(GRADLE_TOOLING_API_ARTIFACT_ID));
+ writePom(GRADLE_TOOLING_API_ARTIFACT_ID, "jar");
+ log.info("Gradle Tooling API " + gradleVersion + " download complete");
+ } catch (IOException e) {
+ throw new IllegalStateException("Couldn't download Gradle Tooling API " + gradleVersion, e);
+ }
+ }
+
private Set extract() {
log.info("Extracting Gradle " + gradleVersion + " to local Maven repository...");
final Set artifactIds = new HashSet<>();
@@ -80,6 +96,8 @@ private Set extract() {
final Set applicableEntries = zipFile.stream()
.filter(e -> e.getName().indexOf("gradle-", e.getName().lastIndexOf('/') + 1) >= 0)
.filter(e -> e.getName().endsWith("-" + gradleVersion + ".jar"))
+ // Gradle Tooling API requires special treatment
+ .filter(e -> !e.getName().endsWith("gradle-tooling-api-" + gradleVersion + ".jar"))
.collect(Collectors.toSet());
for (ZipEntry entry : applicableEntries) {
final String artifactJar = entry.getName().substring(entry.getName().lastIndexOf('/') + 1);
@@ -110,6 +128,19 @@ private Path resolveGroupDir() {
return repositoryBaseDir.resolve("org").resolve("gradle");
}
+ private InputStream streamUrl(String url) throws IOException {
+ final URL remoteBin = new URL(url);
+ // Connection
+ final InputStream stream;
+ if (proxy == null) {
+ stream = remoteBin.openStream();
+ } else {
+ log.info("Using proxy");
+ stream = remoteBin.openConnection(proxy).getInputStream();
+ }
+ return stream;
+ }
+
private void writePom(String artifact, String packaging) throws IOException {
final Path pom = resolveArtifactDir(artifact).resolve(artifact + "-" + gradleVersion + ".pom");
Files.deleteIfExists(pom);