Skip to content

Commit

Permalink
Add support for the renamed Develocity Maven Extension (#624)
Browse files Browse the repository at this point in the history
The Gradle Enterprise Maven Extension was renamed to the Develocity Maven
Extension in version 1.21.  The API was also updated for the product name
change. Unfortunately, this broke compatibility with the Build Validation
Scripts. This commit fixes the incompatibility.

The fix works by updating the configure-gradle-enterprise-maven-extension to
define and register two listeners: a GradleEnterpriseListener and a
DevelocityListener.  If an older version of the Gradle Enterprise Maven
Extension is used, it will load the GradleEnterpriseListener.  If a newer
version of the Develocity Maven Extension is used, then it will load the
DevelocityListener. The Develocity Maven Extension Adapters are used to
eliminate duplication between the two different listeners.

This commit also creates a "fat jar" so that the develocity-maven-extention-adapters jar
does not have to be manually added to the classpath.

The project compiles agianst an older version of Maven to ensure compatibility
with projects using an older version of Maven.

**Remove unused variables and suppress deprecation warnings**

Unused warnings were previously suppressed because the main classes aren't used
directly. However, this suppressed other unused warnings and hid a few things
that are not actually used.  So this commit un-supresses unused warnings and
removes the unused variables and parameters.

The attempt to suppress deprecation warnings on the ConfigureGradleEnterprise
class wasn't working because the deprecated classes are referenced in import
statements. The class was updated to use the fully qualified name of the
deprecated classes.

---------

Signed-off-by: Jim Hurne <[email protected]>
Co-authored-by: Eric Haag <[email protected]>
Co-authored-by: Brian Demers <[email protected]>
  • Loading branch information
3 people committed Jun 14, 2024
1 parent 418f05a commit b51d887
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 119 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ updates:
# Update only patch version of GE Maven extension
- dependency-name: "com.gradle:gradle-enterprise-maven-extension"
update-types: ["version-update:semver-major", "version-update:semver-minor"]
# intentionally compiling against an older version to preserve compatibility with older versions of Maven
- dependency-name: "org.apache.maven:maven-core"
schedule:
interval: "daily"
time: "02:00"
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ repositories {
}
}
mavenCentral()

}

val isDevelopmentRelease = !hasProperty("finalRelease")
Expand Down Expand Up @@ -66,7 +66,7 @@ dependencies {
argbash("argbash:argbash:2.10.0@zip")
develocityComponents("com.gradle:build-scan-summary:$buildScanSummaryVersion")
develocityMavenComponents("com.gradle:gradle-enterprise-maven-extension:1.18.4")
mavenComponents(project(":configure-gradle-enterprise-maven-extension"))
mavenComponents(project(path = ":configure-gradle-enterprise-maven-extension", configuration = "shadow"))
thirdPartyMavenComponents("com.gradle:common-custom-user-data-maven-extension:1.13")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "8.1.1"
}

repositories {
mavenCentral()
}

dependencies {
compileOnly("org.apache.maven:maven-core:3.9.7")
compileOnly("org.apache.maven:maven-core:3.6.3") // intentionally compiling against an older version to preserve compatibility with older versions of Maven
compileOnly("org.codehaus.plexus:plexus-component-annotations:2.2.0")
compileOnly("com.gradle:gradle-enterprise-maven-extension:1.18.4")
compileOnly("com.gradle:develocity-maven-extension:1.21.4")
implementation("com.gradle:develocity-maven-extension-adapters:1.0")
}

description = "Maven extension to capture the build scan URL"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.gradle;

import com.gradle.develocity.agent.maven.adapters.develocity.DevelocityApiAdapter;
import com.gradle.develocity.agent.maven.api.DevelocityApi;
import com.gradle.develocity.agent.maven.api.DevelocityListener;
import org.apache.maven.execution.MavenSession;

import javax.inject.Inject;

public class ConfigureDevelocity implements DevelocityListener {

private final ConfigureDevelocityAdaptor configureDevelocityAdaptor;

@Inject
public ConfigureDevelocity(ConfigureDevelocityAdaptor configureDevelocityAdaptor, RootProjectExtractor rootProjectExtractor) {
this.configureDevelocityAdaptor = configureDevelocityAdaptor;
}

@Override
public void configure(DevelocityApi api, MavenSession session) {
configureDevelocityAdaptor.configure(new DevelocityApiAdapter(api), session);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.gradle;

import com.gradle.develocity.agent.maven.adapters.BuildScanApiAdapter;
import com.gradle.develocity.agent.maven.adapters.DevelocityAdapter;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.logging.Logger;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import static java.lang.Boolean.parseBoolean;
import static java.nio.file.StandardOpenOption.*;

public class ConfigureDevelocityAdaptor {

private static final String EXPERIMENT_DIR = System.getProperty("com.gradle.enterprise.build-validation.expDir");

private final RootProjectExtractor rootProjectExtractor;
private final Logger logger;

@Inject
public ConfigureDevelocityAdaptor(RootProjectExtractor rootProjectExtractor, Logger logger) {
this.rootProjectExtractor = rootProjectExtractor;
this.logger = logger;
}

public void configure(DevelocityAdapter api, MavenSession session) {
logger.debug("Configuring build scan published event...");

BuildScanApiAdapter buildScan = api.getBuildScan();

String geUrl = System.getProperty("gradle.enterprise.url");
String geAllowUntrustedServer = System.getProperty("gradle.enterprise.allowUntrustedServer");

if (geUrl != null && !geUrl.isEmpty()) {
buildScan.setServer(geUrl);
}
if (geAllowUntrustedServer != null && !geAllowUntrustedServer.isEmpty()) {
buildScan.setAllowUntrustedServer(Boolean.parseBoolean(geAllowUntrustedServer));
}

String rootProjectName = rootProjectExtractor.extractRootProject(session).getName();

registerBuildScanActions(buildScan, rootProjectName);
configureBuildScanPublishing(buildScan);
}

private static void registerBuildScanActions(BuildScanApiAdapter buildScan, String rootProjectName) {
buildScan.buildFinished(buildResult -> {
// communicate via error file that no GE server is set
boolean omitServerUrlValidation = parseBoolean(System.getProperty("com.gradle.enterprise.build-validation.omitServerUrlValidation"));
if (buildScan.getServer() == null && !omitServerUrlValidation) {
buildScan.publishAlwaysIf(false); // disable publishing, otherwise scans.gradle.com will be used
File errorFile = new File(EXPERIMENT_DIR, "errors.txt");
append(errorFile, "The Gradle Enterprise server URL has not been configured in the project or on the command line.");
}
});

buildScan.buildFinished(buildResult -> {
String expId = System.getProperty("com.gradle.enterprise.build-validation.expId");
addCustomValueAndSearchLink(buildScan, "Experiment id", expId);
buildScan.tag(expId);

String runId = System.getProperty("com.gradle.enterprise.build-validation.runId");
addCustomValueAndSearchLink(buildScan, "Experiment run id", runId);

String scriptsVersion = System.getProperty("com.gradle.enterprise.build-validation.scriptsVersion");
buildScan.value("Build validation scripts", scriptsVersion);
});

buildScan.buildScanPublished(scan -> {
String runNum = System.getProperty("com.gradle.enterprise.build-validation.runNum");
URI buildScanUri = scan.getBuildScanUri();
String buildScanId = scan.getBuildScanId();
String port = buildScanUri.getPort() != -1 ? ":" + buildScanUri.getPort() : "";
String baseUrl = String.format("%s://%s%s", buildScanUri.getScheme(), buildScanUri.getHost(), port);

File scanFile = new File(EXPERIMENT_DIR, "build-scans.csv");
append(scanFile, String.format("%s,%s,%s,%s,%s\n", runNum, rootProjectName, baseUrl, buildScanUri, buildScanId));
});
}

private static void configureBuildScanPublishing(BuildScanApiAdapter buildScan) {
buildScan.publishAlways();
buildScan.capture(t -> t.setGoalInputFiles(true)); // also set via sys prop
buildScan.setUploadInBackground(false);
}

private static void addCustomValueAndSearchLink(BuildScanApiAdapter buildScan, String label, String value) {
buildScan.value(label, value);
if (buildScan.getServer() != null) {
String server = buildScan.getServer();
String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value);
String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}");
buildScan.link(label + " build scans", url);
}
}

private static String appendIfMissing(String str, String suffix) {
return str.endsWith(suffix) ? str : str + suffix;
}

private static String urlEncode(String str) {
try {
return URLEncoder.encode(str, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}

private static void append(File file, String text) {
try {
Files.write(file.toPath(), text.getBytes(), CREATE, WRITE, APPEND);
} catch (IOException e) {
throw new RuntimeException(String.format("Unable to write to file %s: %s", file.getName(), e.getMessage()), e);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,128 +1,23 @@
package com.gradle;

import com.gradle.maven.extension.api.GradleEnterpriseApi;
import com.gradle.maven.extension.api.GradleEnterpriseListener;
import com.gradle.maven.extension.api.scan.BuildScanApi;
import com.gradle.develocity.agent.maven.adapters.enterprise.GradleEnterpriseApiAdapter;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.logging.Logger;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import static java.lang.Boolean.parseBoolean;
import static java.nio.file.StandardOpenOption.*;
// Using fully qualified class names to avoid deprecation warnings on import statements
@SuppressWarnings({"deprecation"})
public class ConfigureGradleEnterprise implements com.gradle.maven.extension.api.GradleEnterpriseListener {

@SuppressWarnings("unused")
public class ConfigureGradleEnterprise implements GradleEnterpriseListener {

private static final String EXPERIMENT_DIR = System.getProperty("com.gradle.enterprise.build-validation.expDir");

private final RootProjectExtractor rootProjectExtractor;
private final Logger logger;
private final ConfigureDevelocityAdaptor configureDevelocityAdaptor;

@Inject
public ConfigureGradleEnterprise(RootProjectExtractor rootProjectExtractor, Logger logger) {
this.rootProjectExtractor = rootProjectExtractor;
this.logger = logger;
public ConfigureGradleEnterprise(ConfigureDevelocityAdaptor configureDevelocityAdaptor) {
this.configureDevelocityAdaptor = configureDevelocityAdaptor;
}

@Override
public void configure(GradleEnterpriseApi api, MavenSession session) {
logger.debug("Configuring build scan published event...");

BuildScanApi buildScan = api.getBuildScan();

String geUrl = System.getProperty("gradle.enterprise.url");
String geAllowUntrustedServer = System.getProperty("gradle.enterprise.allowUntrustedServer");

if (geUrl != null && !geUrl.isEmpty()) {
buildScan.setServer(geUrl);
}
if (geAllowUntrustedServer != null && !geAllowUntrustedServer.isEmpty()) {
buildScan.setAllowUntrustedServer(Boolean.parseBoolean(geAllowUntrustedServer));
}

String rootProjectName = rootProjectExtractor.extractRootProject(session).getName();

registerBuildScanActions(buildScan, rootProjectName);
configureBuildScanPublishing(buildScan);
public void configure(com.gradle.maven.extension.api.GradleEnterpriseApi api, MavenSession session) {
configureDevelocityAdaptor.configure(new GradleEnterpriseApiAdapter(api), session);
}

private static void registerBuildScanActions(BuildScanApi buildScan, String rootProjectName) {
buildScan.buildFinished(buildResult -> {
// communicate via error file that no GE server is set
boolean omitServerUrlValidation = parseBoolean(System.getProperty("com.gradle.enterprise.build-validation.omitServerUrlValidation"));
if (buildScan.getServer() == null && !omitServerUrlValidation) {
buildScan.publishAlwaysIf(false); // disable publishing, otherwise scans.gradle.com will be used
File errorFile = new File(EXPERIMENT_DIR, "errors.txt");
append(errorFile, "The Gradle Enterprise server URL has not been configured in the project or on the command line.");
}
});

buildScan.buildFinished(buildResult -> {
String expId = System.getProperty("com.gradle.enterprise.build-validation.expId");
addCustomValueAndSearchLink(buildScan, "Experiment id", expId);
buildScan.tag(expId);

String runId = System.getProperty("com.gradle.enterprise.build-validation.runId");
addCustomValueAndSearchLink(buildScan, "Experiment run id", runId);

String scriptsVersion = System.getProperty("com.gradle.enterprise.build-validation.scriptsVersion");
buildScan.value("Build validation scripts", scriptsVersion);
});

buildScan.buildScanPublished(scan -> {
String runNum = System.getProperty("com.gradle.enterprise.build-validation.runNum");
URI buildScanUri = scan.getBuildScanUri();
String buildScanId = scan.getBuildScanId();
String port = buildScanUri.getPort() != -1 ? ":" + buildScanUri.getPort() : "";
String baseUrl = String.format("%s://%s%s", buildScanUri.getScheme(), buildScanUri.getHost(), port);

File scanFile = new File(EXPERIMENT_DIR, "build-scans.csv");
append(scanFile, String.format("%s,%s,%s,%s,%s\n", runNum, rootProjectName, baseUrl, buildScanUri, buildScanId));
});
}

private static void configureBuildScanPublishing(BuildScanApi buildScan) {
buildScan.publishAlways();
buildScan.capture(t -> t.setGoalInputFiles(true)); // also set via sys prop
buildScan.setUploadInBackground(false);
}

private static void addCustomValueAndSearchLink(BuildScanApi buildScan, String label, String value) {
buildScan.value(label, value);
if (buildScan.getServer() != null) {
String server = buildScan.getServer();
String searchParams = "search.names=" + urlEncode(label) + "&search.values=" + urlEncode(value);
String url = appendIfMissing(server, "/") + "scans?" + searchParams + "#selection.buildScanB=" + urlEncode("{SCAN_ID}");
buildScan.link(label + " build scans", url);
}
}

private static String appendIfMissing(String str, String suffix) {
return str.endsWith(suffix) ? str : str + suffix;
}

private static String urlEncode(String str) {
try {
return URLEncoder.encode(str, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}

private static void append(File file, String text) {
try {
Files.write(file.toPath(), text.getBytes(), CREATE, WRITE, APPEND);
} catch (IOException e) {
throw new RuntimeException(String.format("Unable to write to file %s: %s", file.getName(), e.getMessage()), e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,12 @@
<description>Configures Gradle Enterprise</description>
<isolated-realm>false</isolated-realm>
</component>
<component>
<role>com.gradle.develocity.agent.maven.api.DevelocityListener</role>
<role-hint>configure-develocity</role-hint>
<implementation>com.gradle.ConfigureDevelocity</implementation>
<description>Configures Develocity</description>
<isolated-realm>false</isolated-realm>
</component>
</components>
</component-set>
2 changes: 1 addition & 1 deletion components/scripts/lib/maven.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ find_versioned_jar() {
find "${dir_to_search}" -name "${base_name}*" -type f -print -quit
}

CONFIGURE_GRADLE_ENTERPRISE_JAR="${LIB_DIR}/maven-libs/configure-gradle-enterprise-maven-extension-${SCRIPT_VERSION}.jar"
CONFIGURE_GRADLE_ENTERPRISE_JAR="${LIB_DIR}/maven-libs/configure-gradle-enterprise-maven-extension-${SCRIPT_VERSION}-all.jar"
GRADLE_ENTERPRISE_MAVEN_EXTENSION_JAR="$(find_versioned_jar "${SCRIPT_DIR}/lib/develocity" "gradle-enterprise-maven-extension")"
COMMON_CUSTOM_USER_DATA_MAVEN_EXTENSION_JAR="$(find_versioned_jar "${SCRIPT_DIR}/lib/third-party" "common-custom-user-data-maven-extension")"
readonly CONFIGURE_GRADLE_ENTERPRISE_JAR GRADLE_ENTERPRISE_MAVEN_EXTENSION_JAR COMMON_CUSTOM_USER_DATA_MAVEN_EXTENSION_JAR
Expand Down

0 comments on commit b51d887

Please sign in to comment.