From a1a7f5c0519f1a80f93973a08d12cb9442784db1 Mon Sep 17 00:00:00 2001 From: Toon Geens Date: Fri, 26 Jul 2019 15:38:49 +0200 Subject: [PATCH] Adding DE support --- ...ensionsProjectGenerationConfiguration.java | 5 - .../build/gradle/CustomGradleBuildWriter.java | 69 ++++++++++++++ ...ensionsProjectGenerationConfiguration.java | 93 +++++++++++++++++++ src/main/resources/META-INF/spring.factories | 1 + src/main/resources/application.yaml | 3 +- .../build/gradle/GradleBuildAssert.java | 10 ++ .../build/gradle/GradleBuildParser.java | 75 +++++++++++++-- .../build/gradle/GradleTaskAssertion.java | 18 ++++ .../integration/DynamicExtensionsTests.java | 40 +++++++- 9 files changed, 297 insertions(+), 17 deletions(-) delete mode 100644 src/main/java/eu/xenit/alfred/initializr/generator/alfresco/extensions/DynamicExtensionsProjectGenerationConfiguration.java create mode 100644 src/main/java/eu/xenit/alfred/initializr/generator/extensions/dynext/DynamicExtensionsProjectGenerationConfiguration.java create mode 100644 src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleTaskAssertion.java diff --git a/src/main/java/eu/xenit/alfred/initializr/generator/alfresco/extensions/DynamicExtensionsProjectGenerationConfiguration.java b/src/main/java/eu/xenit/alfred/initializr/generator/alfresco/extensions/DynamicExtensionsProjectGenerationConfiguration.java deleted file mode 100644 index e232e27..0000000 --- a/src/main/java/eu/xenit/alfred/initializr/generator/alfresco/extensions/DynamicExtensionsProjectGenerationConfiguration.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.xenit.alfred.initializr.generator.alfresco.extensions; - -public class DynamicExtensionsProjectGenerationConfiguration { - -} diff --git a/src/main/java/eu/xenit/alfred/initializr/generator/build/gradle/CustomGradleBuildWriter.java b/src/main/java/eu/xenit/alfred/initializr/generator/build/gradle/CustomGradleBuildWriter.java index f7919c3..f4a0b20 100644 --- a/src/main/java/eu/xenit/alfred/initializr/generator/build/gradle/CustomGradleBuildWriter.java +++ b/src/main/java/eu/xenit/alfred/initializr/generator/build/gradle/CustomGradleBuildWriter.java @@ -4,17 +4,29 @@ import io.spring.initializr.generator.buildsystem.Dependency; import io.spring.initializr.generator.buildsystem.Dependency.Exclusion; import io.spring.initializr.generator.buildsystem.gradle.GradleBuild; +import io.spring.initializr.generator.buildsystem.gradle.GradleBuild.TaskCustomization; +import io.spring.initializr.generator.buildsystem.gradle.GradleBuild.TaskCustomization.Invocation; import io.spring.initializr.generator.buildsystem.gradle.GroovyDslGradleBuildWriter; import io.spring.initializr.generator.io.IndentingWriter; import io.spring.initializr.generator.version.VersionProperty; import io.spring.initializr.generator.version.VersionReference; +import java.util.Collection; import java.util.Map; +import java.util.function.Consumer; /** * Adapted from {@link io.spring.initializr.generator.buildsystem.gradle.GradleBuildWriter} * * Original class hides utility methods as private, which makes it hard to simply override the {@link * #writeTo(IndentingWriter writer, GradleBuild build)} method + * + * Customisations: + * */ public class CustomGradleBuildWriter extends GroovyDslGradleBuildWriter { @@ -92,4 +104,61 @@ private String dependencyExclusionAsString(Exclusion exclusion) { return "exclude group: '" + exclusion.getGroupId() + "', module: '" + exclusion.getArtifactId() + "'"; } + + @Override + protected void writeTaskCustomizations(IndentingWriter writer, GradleBuild build) { + Map taskCustomizations = build.getTaskCustomizations(); + + taskCustomizations.forEach((name, customization) -> { + writer.println(); + writer.println(name + " {"); + writer.indented(() -> writeAutoFormattedTaskCustomization(writer, customization)); + writer.println("}"); + }); + } + + protected void writeAutoFormattedTaskCustomization(IndentingWriter writer, TaskCustomization customization) { + writeCollection(writer, customization.getInvocations(), writeTaskInvocation(writer)); + writeMap(writer, customization.getAssignments(), (key, value) -> key + " = " + value); + customization.getNested().forEach((property, nestedCustomization) -> { + writer.println(property + " {"); + writer.indented(() -> writeAutoFormattedTaskCustomization(writer, nestedCustomization)); + writer.println("}"); + }); + } + + private Consumer writeTaskInvocation(IndentingWriter writer) { + return invocation -> { + String arguments = String.join(", ", invocation.getArguments()); + + int argumentsCount = invocation.getArguments().size(); + if (argumentsCount == 0) { + arguments = "()"; + } else if (argumentsCount == 1) { + arguments = " " + arguments; + } else { + arguments = "(" + arguments + ")"; + } + + writer.println(invocation.getTarget() + arguments); + }; + } + + protected void writeCollection(IndentingWriter writer, Collection collection, + Consumer callback) { + writeCollection(writer, collection, callback, null); + } + + protected void writeCollection(IndentingWriter writer, Collection collection, + Consumer callback, Runnable beforeWriting) { + if (!collection.isEmpty()) { + if (beforeWriting != null) { + beforeWriting.run(); + } + collection.forEach(callback::accept); + } + } + + + } \ No newline at end of file diff --git a/src/main/java/eu/xenit/alfred/initializr/generator/extensions/dynext/DynamicExtensionsProjectGenerationConfiguration.java b/src/main/java/eu/xenit/alfred/initializr/generator/extensions/dynext/DynamicExtensionsProjectGenerationConfiguration.java new file mode 100644 index 0000000..d42fb26 --- /dev/null +++ b/src/main/java/eu/xenit/alfred/initializr/generator/extensions/dynext/DynamicExtensionsProjectGenerationConfiguration.java @@ -0,0 +1,93 @@ +package eu.xenit.alfred.initializr.generator.extensions.dynext; + +import static org.springframework.util.StringUtils.quote; + +import eu.xenit.alfred.initializr.generator.alfresco.platform.PlatformBuild; +import eu.xenit.alfred.initializr.generator.build.BuildCustomizer; +import eu.xenit.alfred.initializr.generator.build.gradle.platform.PlatformGradleBuild; +import eu.xenit.alfred.initializr.generator.build.gradle.root.RootGradleBuild; +import eu.xenit.alfred.initializr.generator.condition.ConditionalOnRequestedFacet; +import eu.xenit.alfred.initializr.generator.packaging.amp.AmpPackaging; +import eu.xenit.alfred.initializr.generator.sdk.alfred.AlfredSdk; +import eu.xenit.alfred.initializr.generator.sdk.alfred.AlfredSdk.Configurations; +import io.spring.initializr.generator.buildsystem.Dependency; +import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem; +import io.spring.initializr.generator.buildsystem.gradle.GradleDependency; +import io.spring.initializr.generator.condition.ConditionalOnBuildSystem; +import io.spring.initializr.generator.condition.ConditionalOnPackaging; +import io.spring.initializr.generator.project.ProjectGenerationConfiguration; +import io.spring.initializr.generator.project.ResolvedProjectDescription; +import io.spring.initializr.generator.version.VersionReference; +import io.spring.initializr.metadata.support.MetadataBuildItemResolver; +import org.springframework.context.annotation.Bean; + +@ProjectGenerationConfiguration +@ConditionalOnRequestedFacet("dynamic-extensions") +public class DynamicExtensionsProjectGenerationConfiguration { + + private final static String DYN_EXT = "dynamic-extensions"; + + private final MetadataBuildItemResolver resolver; + + public DynamicExtensionsProjectGenerationConfiguration(MetadataBuildItemResolver resolver) { + this.resolver = resolver; + } + + @Bean + @ConditionalOnBuildSystem(GradleBuildSystem.ID) + public BuildCustomizer addRootDynamicExtensionsAmp(MetadataBuildItemResolver resolver) { + return (build) -> { + + String dynamicExtensionVersion = this.getDynamicExtensionsDependency().getVersion().getValue(); + build.ext("dynamicExtensionsVersion", quote(dynamicExtensionVersion)); + + Dependency alfrescoAmp = GradleDependency.from(this.getDynamicExtensionsDependency()) + .type("amp") + .version(VersionReference.ofProperty("dynamic-extensions-version")) + .configuration(Configurations.ALFRESCO_AMP) + .build(); + build.dependencies().add(DYN_EXT, alfrescoAmp); + }; + } + + @Bean + @ConditionalOnBuildSystem(GradleBuildSystem.ID) + @ConditionalOnPackaging(AmpPackaging.ID) + public BuildCustomizer packageDynamicExtensionBundleAsAmp() { + return (build) -> { + + build.customizeTask("sourceSets", sourceSets -> { + sourceSets.nested("main", main -> { + main.nested("amp", amp -> { + amp.invoke("dynamicExtension"); + }); + }); + }); + }; + } + + @Bean + @ConditionalOnBuildSystem(GradleBuildSystem.ID) + public BuildCustomizer platformConfigureDynamicExtensionsPlugin( + ResolvedProjectDescription project) { + return (build) -> { + + String pluginVersion = this.getDynamicExtensionsDependency().getVersion().getValue(); + build.addPlugin("eu.xenit.de", pluginVersion); + + // dependencies on -webscripts and -annotations are added by the plugin + // TODO review we want to change this ?! + + build.customizeTask("jar", jar -> { + jar.invoke("bnd", + "'Alfresco-Spring-Configuration': '"+project.getPackageName()+"'" + ); + }); + }; + } + + private Dependency getDynamicExtensionsDependency() { + return resolver.resolveDependency("dynamic-extensions"); + } + +} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories index 66ea181..9128be1 100644 --- a/src/main/resources/META-INF/spring.factories +++ b/src/main/resources/META-INF/spring.factories @@ -11,6 +11,7 @@ eu.xenit.alfred.initializr.generator.sdk.alfred.docker.DockerBuildGenerationConf eu.xenit.alfred.initializr.generator.sdk.alfred.docker.AlfredSdkComposeProjectGenerationConfiguration,\ eu.xenit.alfred.initializr.generator.alfresco.platform.AlfrescoModuleProjectGenerationConfiguration,\ eu.xenit.alfred.initializr.generator.docker.compose.DockerComposeProjectGenerationConfiguration,\ +eu.xenit.alfred.initializr.generator.extensions.dynext.DynamicExtensionsProjectGenerationConfiguration,\ eu.xenit.alfred.initializr.generator.extensions.alfred.telemetry.AlfredTelemetryProjectGenerationConfiguration,\ eu.xenit.alfred.initializr.generator.extensions.alfred.telemetry.grafana.GrafanaDockerComposeProjectGenerationConfiguration,\ eu.xenit.alfred.initializr.generator.extensions.alfred.telemetry.graphite.GraphiteProjectGenerationConfiguration diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 93b3e93..9ecbc40 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -55,8 +55,7 @@ initializr: - name: Dynamic Extensions id: dynamic-extensions facets: - - platform - - alfrescoAmp + - dynamic-extensions groupId: eu.xenit artifactId: alfresco-dynamic-extensions-repo version: 2.0.1 diff --git a/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildAssert.java b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildAssert.java index d8daa16..6bf5dfc 100644 --- a/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildAssert.java +++ b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildAssert.java @@ -1,10 +1,14 @@ package eu.xenit.alfred.initializr.asserts.build.gradle; +import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem; +import java.util.function.Consumer; import lombok.Getter; import org.assertj.core.api.AbstractStringAssert; public class GradleBuildAssert extends AbstractStringAssert { + + public GradleBuildAssert(String content) { super(content, GradleBuildAssert.class); } @@ -61,4 +65,10 @@ public GradleBuildAssert hasDependency(String configuration, String dependency) @Getter(lazy=true) private final DependenciesAssert dependencies = new DependenciesAssert(this.actual); + public GradleBuildAssert assertTask(String task, Consumer callback) + { + String section = GradleBuildParser.extractSection(task, this.actual); + callback.accept(new GradleTaskAssertion(section)); + return this; + } } diff --git a/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildParser.java b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildParser.java index e08f63f..5bd00cd 100644 --- a/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildParser.java +++ b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleBuildParser.java @@ -21,14 +21,41 @@ public static String extractSection(String name, String content) { content = content.substring(openPluginsIndex + name.length() + " {".length()).trim(); + // FIXME here we should start tracking the level ? we could open a few more 'sections' + // now 'content' contains the start of the section - // the assumption here is that the closing brace is on a separate line + // we start tracking the 'depth', to support nested sections + // + // ASSUMPTION: the matching closing brace is: + // 1. at the end of a line (after trimming) + // 2. alone on a new line (is that the same as case (1) ? + // This is to avoid running into variables in strings like "${foo}" + List section = new ArrayList<>(); - for(String line : content.split(System.lineSeparator())) { - if ("}".equalsIgnoreCase(line.trim())) - { - // found end of section on a new line - return String.join(System.lineSeparator(), section); + int depth = 1; + for (String line : content.split(System.lineSeparator())) { + + if (line.trim().matches("^\\w+\\s\\{.*$")) { + depth++; + } +// else if (line.trim().startsWith("}")) { +// depth--; +// } + + if (line.trim().endsWith("}")) { + depth--; + + if (depth == 0) { + + if (!line.trim().equalsIgnoreCase("}")) + { + // there is useful content before the closing '}' + // Example: maven { url 'https://artifacts.alfresco.com/nexus/content/groups/public/' } + + section.add(line.substring(0, line.indexOf("}")).trim()); + } + return String.join(System.lineSeparator(), section); + } } section.add(line); @@ -36,7 +63,7 @@ public static String extractSection(String name, String content) { // if we end up here, something went wrong // the matching closing brace was not found ?! - throw new IllegalStateException("matching closing brace not found for section "+name); + throw new IllegalStateException("matching closing brace not found for section " + name); } @@ -95,5 +122,39 @@ public void testUnbalancedBraces() { String result = extractSection("plugins", missingClosingBrace); } + + @Test + public void testNested() { + String gradle = String.join("\n", + "sourceSets {", + " main {", + " amp {", + " dynamicExtension()", + " }", + " }", + "}"); + + String sourceSets = extractSection("sourceSets", gradle); + String main = extractSection("main", sourceSets); + String amp = extractSection("amp", main); + + assertThat(amp).isEqualTo("dynamicExtension()"); + } + + @Test + public void testOnSingleLine() { + String gradle = String.join("\n", + "repositories {", + " mavenCentral()", + " maven { url 'https://artifacts.alfresco.com/nexus/content/groups/public/' }", + "}", + "" + ); + + String repositories = extractSection("repositories", gradle); + String maven = extractSection("maven", repositories); + + assertThat(maven).isEqualTo("url 'https://artifacts.alfresco.com/nexus/content/groups/public/'"); + } } } diff --git a/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleTaskAssertion.java b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleTaskAssertion.java new file mode 100644 index 0000000..64465ff --- /dev/null +++ b/src/test/java/eu/xenit/alfred/initializr/asserts/build/gradle/GradleTaskAssertion.java @@ -0,0 +1,18 @@ +package eu.xenit.alfred.initializr.asserts.build.gradle; + +import java.util.function.Consumer; +import org.assertj.core.api.AbstractStringAssert; + +public class GradleTaskAssertion extends AbstractStringAssert { + + public GradleTaskAssertion(String actual) { + super(actual, GradleTaskAssertion.class); + } + + public GradleTaskAssertion nested(String task, Consumer callback) + { + String section = GradleBuildParser.extractSection(task, this.actual); + callback.accept(new GradleTaskAssertion(section)); + return this; + } +} diff --git a/src/test/java/eu/xenit/alfred/initializr/integration/DynamicExtensionsTests.java b/src/test/java/eu/xenit/alfred/initializr/integration/DynamicExtensionsTests.java index bc19d3b..5586dec 100644 --- a/src/test/java/eu/xenit/alfred/initializr/integration/DynamicExtensionsTests.java +++ b/src/test/java/eu/xenit/alfred/initializr/integration/DynamicExtensionsTests.java @@ -1,12 +1,13 @@ package eu.xenit.alfred.initializr.integration; import eu.xenit.alfred.initializr.asserts.build.gradle.GradleMultiProjectAssert; +import eu.xenit.alfred.initializr.asserts.build.gradle.GradleTaskAssertion; import io.spring.initializr.web.project.ProjectRequest; +import org.assertj.core.api.AbstractCharSequenceAssert; import org.junit.Test; public class DynamicExtensionsTests extends BaseGeneratorTests { - private static final String DE_RELEASE = "2.0.1"; @Test public void testDefaultBuild() { ProjectRequest request = createProjectRequest("dynamic-extensions"); @@ -14,11 +15,44 @@ public void testDefaultBuild() { GradleMultiProjectAssert result = generateGradleBuild(request); result.rootGradleBuild() - .hasDependency("alfrescoAmp", quote("eu.xenit:alfresco-dynamic-extensions-repo-52:"+DE_RELEASE+"@amp")); + .hasDependency("alfrescoAmp", quote("eu.xenit:alfresco-dynamic-extensions-repo-52:${dynamicExtensionsVersion}@amp")); + // Only packaging .amp result.platformGradleBuild() - .hasDependency("implementation", quote("eu.xenit:alfresco-dynamic-extensions-repo-52:"+DE_RELEASE)); + .hasPlugin("eu.xenit.de") + .assertTask("sourceSets", sourceSets -> { + sourceSets.isNotBlank(); + sourceSets.nested("main", main -> { + main.nested("amp", amp -> { + amp.isEqualTo("dynamicExtension()"); + }); + }); + }); + + } + + @Test + public void testDynamicExtensionsWithJarPackaging() { + ProjectRequest request = createProjectRequest("dynamic-extensions"); + request.setPackaging("jar"); + + GradleMultiProjectAssert result = generateGradleBuild(request); + + result.rootGradleBuild() + .hasDependency("alfrescoAmp", quote("eu.xenit:alfresco-dynamic-extensions-repo-52:${dynamicExtensionsVersion}@amp")); + + + // This should NOT be present for .jar packaging + result.platformGradleBuild() + .hasPlugin("eu.xenit.de") + .assertTask("sourceSets", sourceSets -> { + sourceSets.nested("main", main -> { + main.nested("amp", amp -> { + amp.doesNotContain("dynamicExtension()"); + }); + }); + }); } } \ No newline at end of file