diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtension.java b/rewrite-maven/src/main/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtension.java
index a95fb2cae8b..99834d3c7a6 100644
--- a/rewrite-maven/src/main/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtension.java
+++ b/rewrite-maven/src/main/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtension.java
@@ -15,12 +15,18 @@
*/
package org.openrewrite.maven;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.intellij.lang.annotations.Language;
import org.openrewrite.*;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.internal.lang.Nullable;
+import org.openrewrite.maven.internal.MavenXmlMapper;
import org.openrewrite.xml.*;
import org.openrewrite.xml.tree.Xml;
@@ -40,58 +46,80 @@ public class AddGradleEnterpriseMavenExtension extends Recipe {
@Language("xml")
private static final String EXTENSIONS_XML_FORMAT = "\n" +
- "\n" +
- "";
+ "\n" +
+ "";
@Language("xml")
private static final String ENTERPRISE_TAG_FORMAT = "\n" +
- " com.gradle\n" +
- " gradle-enterprise-maven-extension\n" +
- " %s\n" +
- "";
+ " com.gradle\n" +
+ " gradle-enterprise-maven-extension\n" +
+ " %s\n" +
+ "";
@Language("xml")
private static final String ENTERPRISE_TAG_FORMAT_WITHOUT_VERSION = "\n" +
- " com.gradle\n" +
- " gradle-enterprise-maven-extension\n" +
- "";
-
- @Language("xml")
- private static final String GRADLE_ENTERPRISE_XML_FORMAT = "\n" +
- "\n" +
- " \n" +
- " %s\n" +
- " %b\n" +
- " \n" +
- " \n" +
- " false\n" +
- " ALWAYS\n" +
- " \n" +
- "";
+ " com.gradle\n" +
+ " gradle-enterprise-maven-extension\n" +
+ "";
@Option(displayName = "Plugin version",
- description = "An exact version number or node-style semver selector used to select the gradle-enterprise-maven-extension version.",
- example = "1.x")
+ description = "An exact version number or node-style semver selector used to select the gradle-enterprise-maven-extension version.",
+ example = "1.x")
@Nullable
String version;
@Option(displayName = "Server URL",
- description = "The URL of the Gradle Enterprise server.",
- example = "https://scans.gradle.com/")
+ description = "The URL of the Gradle Enterprise server.",
+ example = "https://scans.gradle.com/")
String server;
@Option(displayName = "Allow untrusted server",
- description = "When set to `true` the plugin will be configured to allow unencrypted http connections with the server. " +
- "If set to `false` or omitted, the plugin will refuse to communicate without transport layer security enabled.",
- required = false,
- example = "true")
+ description = "When set to `true` the extension will be configured to allow unencrypted http connections with the server. " +
+ "If set to `false` or omitted, the extension will refuse to communicate without transport layer security enabled.",
+ required = false,
+ example = "true")
@Nullable
Boolean allowUntrustedServer;
+ @Option(displayName = "Capture goal input files",
+ description = "When set to `true` the extension will capture additional information about the inputs to Maven goals. " +
+ "This increases the size of build scans, but is useful for diagnosing issues with goal caching. ",
+ required = false,
+ example = "true")
+ @Nullable
+ Boolean captureGoalInputFiles;
+
+ @Option(displayName = "Upload in background",
+ description = "When set to `false` the extension will not upload build scan in the background. " +
+ "By default, build scans are uploaded in the background after the build has finished to avoid blocking the build process.",
+ required = false,
+ example = "false")
+ @Nullable
+ Boolean uploadInBackground;
+
+ @Option(displayName = "Publish Criteria",
+ description = "When set to `always` the extension will publish build scans of every single build. " +
+ "This is the default behavior when omitted." +
+ "When set to `failure` the extension will only publish build scans when the build fails. " +
+ "When set to `demand` the extension will only publish build scans when explicitly requested.",
+ required = false,
+ valid = {"always", "failure", "demand"},
+ example = "true")
+ @Nullable
+ PublishCriteria publishCriteria;
+
+ public enum PublishCriteria {
+ Always("ALWAYS"),
+ Failure("ON_FAILURE"),
+ Demand("ON_DEMAND");
+
+ private final String xmlName;
+
+ PublishCriteria(String xmlName) {
+ this.xmlName = xmlName;
+ }
+ }
+
@Override
public String getDisplayName() {
return "Add Gradle Enterprise Maven Extension to maven projects";
@@ -100,8 +128,8 @@ public String getDisplayName() {
@Override
public String getDescription() {
return "To integrate gradle enterprise maven extension into maven projects, ensure that the " +
- "`gradle-enterprise-maven-extension` is added to the `.mvn/extensions.xml` file if not already present. " +
- "Additionally, configure the extension by adding the `.mvn/gradle-enterprise.xml` configuration file.";
+ "`gradle-enterprise-maven-extension` is added to the `.mvn/extensions.xml` file if not already present. " +
+ "Additionally, configure the extension by adding the `.mvn/gradle-enterprise.xml` configuration file.";
}
@Override
@@ -132,15 +160,14 @@ protected List visit(List before, ExecutionContext ctx)
return before;
}
- Xml.Document gradleEnterpriseXml = createNewXml(GRADLE_ENTERPRISE_XML_PATH,
- String.format(GRADLE_ENTERPRISE_XML_FORMAT, server, allowUntrustedServer != null ? allowUntrustedServer : Boolean.FALSE));
+ Xml.Document gradleEnterpriseXml = createNewXml(GRADLE_ENTERPRISE_XML_PATH, gradleEnterpriseConfiguration());
if (matchingExtensionsXmlFile.get() != null) {
if (!(matchingExtensionsXmlFile.get() instanceof Xml.Document)) {
throw new RuntimeException("The extensions.xml is not xml document type");
}
- Xml.Document extensionsXml = ( Xml.Document) matchingExtensionsXmlFile.get();
+ Xml.Document extensionsXml = (Xml.Document) matchingExtensionsXmlFile.get();
// find `gradle-enterprise-maven-extension` extension, do nothing if it already exists,
boolean hasEnterpriseExtension = findExistingEnterpriseExtension(extensionsXml);
@@ -158,6 +185,59 @@ protected List visit(List before, ExecutionContext ctx)
return ListUtils.concat(ListUtils.concat(before, extensionsXml), gradleEnterpriseXml);
}
+ @JacksonXmlRootElement(localName = "gradleEnterprise")
+ @Value
+ private static class GradleEnterpriseConfiguration {
+ ServerConfiguration server;
+ @Nullable
+ BuildScanConfiguration buildScan;
+ }
+
+ @Value
+ private static class ServerConfiguration {
+ String url;
+ @Nullable
+ Boolean allowUntrusted;
+ }
+
+ @Value
+ private static class BuildScanConfiguration {
+ @Nullable
+ Boolean backgroundBuildScanUpload;
+ @Nullable
+ String publish;
+ @Nullable
+ Capture capture;
+ }
+
+ @Value
+ private static class Capture {
+ Boolean goalInputFiles;
+ }
+
+ private String gradleEnterpriseConfiguration() {
+ BuildScanConfiguration buildScanConfiguration = buildScanConfiguration();
+ ServerConfiguration serverConfiguration = new ServerConfiguration(server, allowUntrustedServer);
+ try {
+ ObjectMapper objectMapper = MavenXmlMapper.writeMapper();
+ objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+ objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
+ return objectMapper.writeValueAsString(new GradleEnterpriseConfiguration(serverConfiguration, buildScanConfiguration));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Nullable
+ private BuildScanConfiguration buildScanConfiguration() {
+ if (uploadInBackground != null || publishCriteria != null || captureGoalInputFiles != null) {
+ return new BuildScanConfiguration(uploadInBackground,
+ publishCriteria != null ? publishCriteria.xmlName : null,
+ captureGoalInputFiles != null ? new Capture(captureGoalInputFiles) : null);
+ }
+ return null;
+ }
+
private static Xml.Document createNewXml(String filePath, String fileContents) {
XmlParser parser = new XmlParser();
Xml.Document brandNewFile = parser.parse(fileContents).get(0);
@@ -195,8 +275,8 @@ private Xml.Document addEnterpriseExtension(Xml.Document extensionsXml, Executio
@Language("xml")
String tagSource = version != null ? String.format(ENTERPRISE_TAG_FORMAT, version) : ENTERPRISE_TAG_FORMAT_WITHOUT_VERSION;
AddToTagVisitor addToTagVisitor = new AddToTagVisitor<>(
- extensionsXml.getRoot(),
- Xml.Tag.build(tagSource));
+ extensionsXml.getRoot(),
+ Xml.Tag.build(tagSource));
return (Xml.Document) addToTagVisitor.visit(extensionsXml, ctx);
}
}
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtensionTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtensionTest.java
index 88a5ac88457..1d1f8e966d5 100644
--- a/rewrite-maven/src/test/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtensionTest.java
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/AddGradleEnterpriseMavenExtensionTest.java
@@ -27,7 +27,8 @@
class AddGradleEnterpriseMavenExtensionTest implements RewriteTest {
@Override
public void defaults(RecipeSpec spec) {
- spec.recipe(new AddGradleEnterpriseMavenExtension("1.17", "https://foo", true));
+ spec.recipe(new AddGradleEnterpriseMavenExtension("1.17", "https://foo", null,
+ null, null, null));
}
private static final SourceSpecs POM_XML_SOURCE_SPEC = pomXml(
@@ -74,18 +75,10 @@ void addGradleEnterpriseMavenExtensionToExistingExtensionsXmlFile() {
xml(
null,
"""
-
-
+
https://foo
- true
-
- false
- ALWAYS
-
""",
spec -> spec.path(".mvn/gradle-enterprise.xml")
@@ -114,19 +107,11 @@ void createNewExtensionsXmlFileIfNotExist() {
xml(
null,
"""
-
-
-
- https://foo
- true
-
-
- false
- ALWAYS
-
-
+
+
+ https://foo
+
+
""",
spec -> spec.path(".mvn/gradle-enterprise.xml")
)
@@ -138,7 +123,7 @@ void createNewExtensionsXmlFileIfNotExist() {
@Test
void noVersionSpecified() {
rewriteRun(
- spec -> spec.recipe(new AddGradleEnterpriseMavenExtension(null, "https://foo", true)),
+ spec -> spec.recipe(new AddGradleEnterpriseMavenExtension(null, "https://foo", null, null, null, null)),
POM_XML_SOURCE_SPEC,
xml(
null,
@@ -156,18 +141,10 @@ void noVersionSpecified() {
xml(
null,
"""
-
-
+
https://foo
- true
-
- false
- ALWAYS
-
""",
spec -> spec.path(".mvn/gradle-enterprise.xml")
@@ -190,4 +167,46 @@ void noChangeIfGradleEnterpriseXmlExists() {
)
);
}
+
+ @Test
+ void allSettings() {
+ rewriteRun(
+ spec -> spec.recipe(new AddGradleEnterpriseMavenExtension("1.17", "https://foo", true, true, false, AddGradleEnterpriseMavenExtension.PublishCriteria.Failure)),
+ POM_XML_SOURCE_SPEC,
+ xml(
+ null,
+ """
+
+
+
+ com.gradle
+ gradle-enterprise-maven-extension
+ 1.17
+
+
+ """,
+ spec -> spec.path(".mvn/extensions.xml")
+ ),
+ xml(
+ null,
+ """
+
+
+ https://foo
+ true
+
+
+ false
+ ON_FAILURE
+
+ true
+
+
+
+ """,
+ spec -> spec.path(".mvn/gradle-enterprise.xml")
+ )
+ );
+ }
+
}