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);