From bcf2a138e4e685dd276779167a14af285e5469ce Mon Sep 17 00:00:00 2001 From: John Blum Date: Thu, 27 Jan 2022 13:57:14 -0800 Subject: [PATCH] Review, refactor and polish (local) Spring Build Conventions Gradle Plugins. Remove the gradle/maven-pom-editor.gradle build script as this logic (concern) is handled by the MavenPlushingConventionsPlugin. Clean up associated Gradle project build scripts affected by the Gradle Plugin changes. --- build.gradle | 8 -- buildSrc/build.gradle | 29 ++-- .../AbstractSpringJavaPlugin.groovy | 78 ++++++++--- .../convention/ArtifactoryPlugin.groovy | 24 +++- .../gradle/convention/CheckstylePlugin.groovy | 14 +- .../convention/DependencySetPlugin.groovy | 13 +- .../convention/IntegrationTestPlugin.groovy | 131 +++++++++--------- .../gradle/convention/JacocoPlugin.groovy | 11 +- .../convention/JavadocOptionsPlugin.groovy | 14 +- .../ManagementConfigurationPlugin.java | 15 +- .../gradle/convention/MavenBomPlugin.groovy | 2 +- .../RepositoryConventionPlugin.groovy | 7 +- .../convention/RootProjectPlugin.groovy | 68 +++++---- ...ependencyManagementConventionPlugin.groovy | 34 +++-- .../convention/SpringModulePlugin.groovy | 24 +++- .../convention/SpringSampleBootPlugin.groovy | 11 +- .../convention/SpringSamplePlugin.groovy | 8 +- .../convention/SpringSampleWarPlugin.groovy | 20 +-- .../gradle/convention/SpringTestPlugin.groovy | 9 +- .../TestsConfigurationPlugin.groovy | 31 ++--- .../io/spring/gradle/convention/Utils.groovy | 9 +- .../gradle/CopyPropertiesPlugin.java | 22 ++- .../MavenPublishingConventionsPlugin.java | 97 +++++++------ .../maven/PublishAllJavaComponentsPlugin.java | 34 +++-- .../gradle/maven/PublishArtifactsPlugin.java | 55 ++++++-- .../gradle/maven/PublishLocalPlugin.java | 59 +++++--- .../gradle/maven/SpringMavenPlugin.java | 10 +- .../maven/SpringNexusPublishPlugin.java | 18 ++- .../gradle/maven/SpringSigningPlugin.java | 84 ++++++++--- gradle/maven-pom-editor.gradle | 33 ----- spring-geode-bom/spring-geode-bom.gradle | 4 +- 31 files changed, 606 insertions(+), 370 deletions(-) delete mode 100644 gradle/maven-pom-editor.gradle diff --git a/build.gradle b/build.gradle index 9490307c..cac2a2c1 100644 --- a/build.gradle +++ b/build.gradle @@ -28,8 +28,6 @@ allprojects { repositories { - mavenCentral() - if (version.contains('-')) { maven { url "https://repo.spring.io/milestone" } } @@ -37,10 +35,6 @@ allprojects { maven { url "https://repo.spring.io/snapshot" } } } - - configurations.all { - resolutionStrategy.cacheChangingModulesFor 0, "minutes" - } } nohttp { @@ -57,5 +51,3 @@ description = 'Spring Boot for Apache Geode' ext.snapshotBuild = Utils.isSnapshot(project) ext.milestoneBuild = Utils.isMilestone(project) ext.releaseBuild = Utils.isRelease(project) - -ext.MAVEN_POM_EDITOR_GRADLE = "$rootDir/gradle/maven-pom-editor.gradle" diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index f5e2a12c..71bcdc07 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -4,21 +4,23 @@ plugins { id "groovy" } -sourceCompatibility = JavaVersion.VERSION_17 - repositories { mavenCentral() gradlePluginPortal() - maven { url 'https://repo.spring.io/plugins-release/' } + maven { + url 'https://repo.spring.io/plugins-release/' + } } +sourceCompatibility = JavaVersion.VERSION_17 + sourceSets { main { java { srcDirs = [] } groovy { - srcDirs += ["src/main/java"] + srcDirs += [ "src/main/java" ] } } } @@ -29,10 +31,6 @@ gradlePlugin { id = "io.spring.convention.management-configuration" implementationClass = "io.spring.gradle.convention.ManagementConfigurationPlugin" } - sagan { - id = "org.springframework.security.sagan" - implementationClass = "org.springframework.gradle.sagan.SaganPlugin" - } githubMilestone { id = "org.springframework.github.milestone" implementationClass = "org.springframework.gradle.github.milestones.GitHubMilestonePlugin" @@ -41,6 +39,10 @@ gradlePlugin { id = "org.springframework.propdeps" implementationClass = "org.springframework.gradle.propdeps.PropDepsPlugin" } + sagan { + id = "org.springframework.sagan" + implementationClass = "org.springframework.gradle.sagan.SaganPlugin" + } } } @@ -56,14 +58,11 @@ dependencies { implementation 'com.apollographql.apollo:apollo-runtime:2.4.5' implementation 'com.google.code.gson:gson:2.8.8' - implementation 'com.github.ben-manes:gradle-versions-plugin:0.38.0' - implementation 'com.github.spullara.mustache.java:compiler:0.9.10' implementation 'io.github.gradle-nexus:publish-plugin:1.1.0' - implementation 'io.projectreactor:reactor-core:3.4.11' - implementation 'io.spring.nohttp:nohttp-gradle:0.0.9' - implementation 'io.spring.gradle:dependency-management-plugin:1.0.10.RELEASE' - implementation 'net.sourceforge.htmlunit:htmlunit:2.55.0' - implementation 'net.sourceforge.saxon:saxon:9.1.0.8' + implementation 'io.spring.javaformat:spring-javaformat-checkstyle:0.0.29' + implementation 'io.spring.nohttp:nohttp-checkstyle:0.0.10' + implementation 'io.spring.nohttp:nohttp-gradle:0.0.10' + implementation 'io.spring.gradle:dependency-management-plugin:1.0.11.RELEASE' implementation 'org.asciidoctor:asciidoctor-gradle-jvm:3.3.2' implementation 'org.asciidoctor:asciidoctor-gradle-jvm-pdf:3.3.2' implementation 'org.jfrog.buildinfo:build-info-extractor-gradle:4.24.20' diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy index 0ec21f22..7048e3c5 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -28,7 +28,11 @@ import org.springframework.gradle.propdeps.PropDepsIdeaPlugin import org.springframework.gradle.propdeps.PropDepsPlugin /** - * Base Gradle API Plugin for all Spring Java project Gradle Plugins. + * Abstract base Gradle {@link Plugin} for all Spring Java & Groovy Gradle Plugins used by SBDG. + * + * This abstract base Gradle {@link Plugin} primarily serves to apply a common set of Gradle {@link Plugin Plugins), + * such as the {@link JavaPlugin} and {@link GroovyPlugin} for the various SBDG project Spring modules as well as other + * Spring Gradle {@link Plugin Plugins} to manage builds, IDE integration, releases and so on. * * @author Rob Winch * @author John Blum @@ -40,31 +44,67 @@ abstract class AbstractSpringJavaPlugin implements Plugin { @Override final void apply(Project project) { - PluginManager pluginManager = project.getPluginManager() + applyPlugins(project) + setJarManifestAttributes(project) - pluginManager.apply(JavaPlugin.class) - pluginManager.apply(ManagementConfigurationPlugin.class) - - if (project.file("src/main/groovy").exists() - || project.file("src/test/groovy").exists() - || project.file("src/integration-test/groovy").exists()) { - - pluginManager.apply(GroovyPlugin.class) + project.test { + useJUnitPlatform() } - pluginManager.apply("io.spring.convention.repository") + applyAdditionalPlugins(project) + } + + private void applyPlugins(Project project) { + + PluginManager pluginManager = project.getPluginManager() + + applyJavaPlugin(pluginManager) + applyGroovyPlugin(project) + applyIdePlugins(pluginManager) + applySpringPlugins(pluginManager) + } + + @SuppressWarnings("all") + private void applyGroovyPlugin(Project project) { + + if (project.file("src/main/groovy").exists() + || project.file("src/test/groovy").exists() + || project.file("src/integration-test/groovy").exists()) { + + project.getPluginManager().apply(GroovyPlugin.class) + } + } + + @SuppressWarnings("all") + private void applyIdePlugins(PluginManager pluginManager) { + pluginManager.apply(EclipseWtpPlugin) pluginManager.apply(IdeaPlugin) + } + + @SuppressWarnings("all") + private void applyJavaPlugin(PluginManager pluginManager) { + pluginManager.apply(JavaPlugin.class) + } + + @SuppressWarnings("all") + private void applySpringPlugins(PluginManager pluginManager) { + pluginManager.apply(PropDepsPlugin) pluginManager.apply(PropDepsEclipsePlugin) pluginManager.apply(PropDepsIdeaPlugin) + pluginManager.apply("io.spring.convention.springdependencymangement") + pluginManager.apply("io.spring.convention.dependency-set") + pluginManager.apply("io.spring.convention.repository") + pluginManager.apply("io.spring.convention.javadoc-options") pluginManager.apply("io.spring.convention.tests-configuration") pluginManager.apply("io.spring.convention.integration-test") - pluginManager.apply("io.spring.convention.springdependencymangement") - pluginManager.apply("io.spring.convention.dependency-set") - pluginManager.apply("io.spring.convention.javadoc-options") + pluginManager.apply("io.spring.convention.jacoco"); pluginManager.apply("io.spring.convention.checkstyle") pluginManager.apply(CopyPropertiesPlugin) + } + + private void setJarManifestAttributes(Project project) { project.jar { manifest.attributes["Created-By"] = "${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})" @@ -72,14 +112,8 @@ abstract class AbstractSpringJavaPlugin implements Plugin { manifest.attributes["Implementation-Version"] = project.version manifest.attributes["Automatic-Module-Name"] = project.name.replace('-', '.') } - - project.test { - useJUnitPlatform() - } - - additionalPlugins(project); } - protected abstract void additionalPlugins(Project project); + protected abstract void applyAdditionalPlugins(Project project); } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy index 16810d5f..936f8e2a 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -19,8 +19,13 @@ import org.gradle.api.Plugin import org.gradle.api.Project /** + * Applies the JFrag Artifactory Gradle {@link Plugin} to publish Gradle {@link Project} artifacts to + * the Spring Artifactory Repositories. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class ArtifactoryPlugin implements Plugin { @@ -29,16 +34,11 @@ class ArtifactoryPlugin implements Plugin { project.plugins.apply('com.jfrog.artifactory') - boolean isSnapshot = Utils.isSnapshot(project); - boolean isMilestone = Utils.isMilestone(project); - project.artifactory { contextUrl = 'https://repo.spring.io' publish { repository { - repoKey = isSnapshot ? 'libs-snapshot-local' - : isMilestone ? 'libs-milestone-local' - : 'libs-release-local' + repoKey = resolveRepositoryKey(project) if (project.hasProperty('artifactoryUsername')) { username = artifactoryUsername password = artifactoryPassword @@ -50,4 +50,14 @@ class ArtifactoryPlugin implements Plugin { } } } + + private String resolveRepositoryKey(Project project) { + + boolean isSnapshot = Utils.isSnapshot(project); + boolean isMilestone = Utils.isMilestone(project); + + return isSnapshot ? 'libs-snapshot-local' + : isMilestone ? 'libs-milestone-local' + : 'libs-release-local' + } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy index 4482103e..6c98bc24 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -20,10 +20,12 @@ import org.gradle.api.Project import org.gradle.api.plugins.JavaPlugin /** - * Adds and configures Checkstyle plugin. + * Configures and applies the Checkstyle Gradle {@link Plugin}. * * @author Vedran Pavic * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class CheckstylePlugin implements Plugin { @@ -36,13 +38,11 @@ class CheckstylePlugin implements Plugin { def checkstyleDirectory = project.rootProject.file(CHECKSTYLE_PATHNAME) - if (checkstyleDirectory.exists() && checkstyleDirectory.directory) { + if (checkstyleDirectory?.isDirectory()) { project.getPluginManager().apply('checkstyle') - project.dependencies.add('checkstyle', - 'io.spring.javaformat:spring-javaformat-checkstyle:0.0.29') - project.dependencies.add('checkstyle', - 'io.spring.nohttp:nohttp-checkstyle:0.0.3.RELEASE') + project.dependencies.add('checkstyle', 'io.spring.javaformat:spring-javaformat-checkstyle') + project.dependencies.add('checkstyle', 'io.spring.nohttp:nohttp-checkstyle') project.checkstyle { configDirectory = checkstyleDirectory diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy index ed70f174..5f5798e5 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -20,17 +20,24 @@ import org.gradle.api.Project import org.gradle.api.plugins.JavaPlugin /** - * Adds sets of dependencies to make it easy to add a grouping of dependencies. The - * dependencies added are: + * Defines sets of dependencies to make it easy to add a related group of dependencies to a Gradle {@link Project}. + * + * The dependencies set defined include: * *
    *
  • jstlDependencies
  • *
  • seleniumDependencies
  • *
  • slf4jDependencies
  • + *
  • testDependencies
  • *
* + *{@literal testDependencies} are automatically added to Java projects + * ({@lin Project Projects} with the {@link JavaPlugin} applied). + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class DependencySetPlugin implements Plugin { diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy index d8591f1c..d89301d7 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -26,17 +26,21 @@ import org.gradle.plugins.ide.idea.IdeaPlugin import org.springframework.gradle.propdeps.PropDepsPlugin /** - * Adds support for integration tests to Java projects. + * Adds Integration Test support to Java projects. * *
    *
  • Adds integrationTestCompile and integrationTestRuntime configurations
  • - *
  • A new source test folder of src/integration-test/java has been added
  • - *
  • A task to run integration tests named integrationTest is added
  • - *
  • If Groovy plugin is added a new source test folder src/integration-test/groovy is added
  • + *
  • Adds new source test folder of src/integration-test/java
  • + *
  • Adds a task to run integration tests named integrationTest
  • + *
  • Adds a new source test folder src/integration-test/groovy if the Groovy Plugin was added
  • *
* * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + * @see org.gradle.api.Task + * @see org.gradle.api.tasks.testing.Test */ class IntegrationTestPlugin implements Plugin { @@ -47,79 +51,82 @@ class IntegrationTestPlugin implements Plugin { } } - private applyJava(Project project) { + private void applyJava(Project project) { - if (!project.file('src/integration-test/').exists()) { - // Do not add any configuration if there are no (integration) tests to avoid adding Gretty. - return - } + // Do not add any configuration if there are no (integration) tests to avoid adding Gretty. + if (isIntegrationTestSourceAvailable(project)) { - project.configurations { - integrationTestCompile { - extendsFrom testImplementation - } - integrationTestRuntime { - extendsFrom integrationTestCompile, testRuntime, testRuntimeOnly - } - } - - project.sourceSets { - integrationTest { - java.srcDir project.file('src/integration-test/java') - resources.srcDir project.file('src/integration-test/resources') - compileClasspath = project.sourceSets.main.output + project.sourceSets.test.output + project.configurations.integrationTestCompile - runtimeClasspath = output + compileClasspath + project.configurations.integrationTestRuntime - } - } - - Task integrationTestTask = project.tasks.create("integrationTest", Test) { - group = 'Verification' - description = 'Runs the integration tests.' - dependsOn 'jar' - testClassesDirs = project.sourceSets.integrationTest.output.classesDirs - classpath = project.sourceSets.integrationTest.runtimeClasspath - shouldRunAfter project.tasks.test - useJUnitPlatform() - } - - project.tasks.check.dependsOn integrationTestTask - - project.plugins.withType(IdeaPlugin) { - project.idea { - module { - testSourceDirs += project.file('src/integration-test/java') - scopes.TEST.plus += [ project.configurations.integrationTestCompile ] + project.configurations { + integrationTestCompile { + extendsFrom testImplementation + } + integrationTestRuntime { + extendsFrom integrationTestCompile, testRuntime, testRuntimeOnly } } - } - project.plugins.withType(GroovyPlugin) { project.sourceSets { integrationTest { - groovy.srcDirs project.file('src/integration-test/groovy') + java.srcDir project.file('src/integration-test/java') + resources.srcDir project.file('src/integration-test/resources') + compileClasspath = project.sourceSets.main.output + project.sourceSets.test.output + project.configurations.integrationTestCompile + runtimeClasspath = output + compileClasspath + project.configurations.integrationTestRuntime } } + + Task integrationTestTask = project.tasks.create("integrationTest", Test) { + group = 'Verification' + description = 'Runs Integration Tests' + dependsOn 'jar' + testClassesDirs = project.sourceSets.integrationTest.output.classesDirs + classpath = project.sourceSets.integrationTest.runtimeClasspath + shouldRunAfter project.tasks.test + useJUnitPlatform() + } + + project.tasks.check.dependsOn integrationTestTask + + project.plugins.withType(EclipsePlugin) { + project.eclipse.classpath { + plusConfigurations += [ project.configurations.integrationTestCompile ] + } + } + project.plugins.withType(IdeaPlugin) { project.idea { module { - testSourceDirs += project.file('src/integration-test/groovy') + testSourceDirs += project.file('src/integration-test/java') + scopes.TEST.plus += [ project.configurations.integrationTestCompile ] + } + } + } + + project.plugins.withType(GroovyPlugin) { + project.sourceSets { + integrationTest { + groovy.srcDirs project.file('src/integration-test/groovy') + } + } + project.plugins.withType(IdeaPlugin) { + project.idea { + module { + testSourceDirs += project.file('src/integration-test/groovy') + } + } + } + } + + project.plugins.withType(PropDepsPlugin) { + project.configurations { + integrationTestCompile { + extendsFrom optional, provided } } } } + } - project.plugins.withType(PropDepsPlugin) { - project.configurations { - integrationTestCompile { - extendsFrom optional, provided - } - } - } - - project.plugins.withType(EclipsePlugin) { - project.eclipse.classpath { - plusConfigurations += [ project.configurations.integrationTestCompile ] - } - } + private boolean isIntegrationTestSourceAvailable(Project project) { + return project.file('src/integration-test/').exists() } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy index adae14fd..cf16f7ed 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -20,13 +20,18 @@ import org.gradle.api.Project import org.gradle.api.plugins.JavaPlugin /** - * Adds a version of jacoco to use and makes check depend on jacocoTestReport. + * Applies the Jacoco Gradle {@link Plugin} to the target Gradle {@link Project} + * and configures {@literal check} Gradle Task to depend on the {@literal jacocoTestReport} Gradle Task. * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class JacocoPlugin implements Plugin { + private static final String JACOCO_VERSION = '0.8.7'; + @Override void apply(Project project) { @@ -36,7 +41,7 @@ class JacocoPlugin implements Plugin { project.tasks.check.dependsOn project.tasks.jacocoTestReport project.jacoco { - toolVersion = '0.8.7' + toolVersion = JACOCO_VERSION } } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy index a968efc8..22e52def 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -20,15 +20,23 @@ import org.gradle.api.Project import org.gradle.api.tasks.javadoc.Javadoc /** + * Configures Javadoc (Gradle Task) to disable the DocLint tool by setting the {@literal -Xdoclint} JVM extension option + * to {@literal none} as well as setting the {@literal -quiet} Javadoc option thereby suppressing the output from + * the Javadoc tool. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + * @see org.gradle.api.tasks.javadoc.Javadoc */ class JavadocOptionsPlugin implements Plugin { @Override void apply(Project project) { - project.getTasks().withType(Javadoc).all { t-> - t.options.addStringOption('Xdoclint:none', '-quiet') + + project.getTasks().withType(Javadoc).all { task -> + task.options.addStringOption('Xdoclint:none', '-quiet') } } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java b/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java index a7e74108..238ed469 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package io.spring.gradle.convention; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ConfigurationContainer; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaTestFixturesPlugin; @@ -29,18 +30,22 @@ import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; import org.springframework.gradle.propdeps.PropDepsPlugin; /** - * Creates a Management configuration that is appropriate for adding a platform so that it is not exposed externally. + * Creates a {@literal Management} Gradle {@link Configuration} that is appropriate for adding a platform + * so that it is not exposed externally. * - * If the JavaPlugin is applied, the compileClasspath, runtimeClasspath, testCompileClasspath, and testRuntimeClasspath - * will extend from it. + * If the {@link JavaPlugin} is applied, then the {@literal compileClasspath}, {@literal runtimeClasspath}, + * {@literal testCompileClasspath}, and {@literal testRuntimeClasspath} will extend from it. * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ public class ManagementConfigurationPlugin implements Plugin { public static final String MANAGEMENT_CONFIGURATION_NAME = "management"; + // TODO: Understand why we don't want certain Configurations to be consumed, resolved or visible??? @Override public void apply(Project project) { @@ -66,7 +71,7 @@ public class ManagementConfigurationPlugin implements Plugin { configurations.getByName("testFixturesRuntimeClasspath").extendsFrom(management); }); - plugins.withType(MavenPublishPlugin.class, mavenPublish -> { + plugins.withType(MavenPublishPlugin.class, mavenPublishPlugin -> { PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy index c69e1e11..71ed5787 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy index f2ef3b0f..f862c68a 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -19,8 +19,13 @@ import org.gradle.api.Plugin import org.gradle.api.Project /** + * Declares Maven Repositories (for example: mavenLocal(), mavenCentral(), jcenter(), Spring Repositories, etc) + * based on a {@link Project Project's} release artifact(s). + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class RepositoryConventionPlugin implements Plugin { diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy index 8c7399db..b301d7ed 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -23,47 +23,35 @@ import org.gradle.api.plugins.PluginManager import org.springframework.gradle.maven.SpringNexusPublishPlugin /** + * The Gradle {@link Plugin} applied to the {@literal root} Gradle {@link Project} with functionality inherited by + * all Gradle {@link Project Projects} ({@literal sub-projects} in a multi-module project. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class RootProjectPlugin implements Plugin { @Override void apply(Project project) { - PluginManager pluginManager = project.getPluginManager() - - pluginManager.apply(BasePlugin) - pluginManager.apply(NoHttpPlugin) - pluginManager.apply(SchemaPlugin) - pluginManager.apply(SpringNexusPublishPlugin) - pluginManager.apply("org.sonarqube") - - project.repositories.mavenCentral() + applyPlugins(project) project.allprojects { configurations.all { resolutionStrategy { - cacheChangingModulesFor 0, "seconds" - cacheDynamicVersionsFor 0, "seconds" + cacheChangingModulesFor 0, 'seconds' + cacheDynamicVersionsFor 0, 'seconds' } } } - String projectName = Utils.getProjectName(project) + // Add Maven Central Repository (resolution) to the list of repositories used by this build + // to resolve dependencies. + project.repositories.mavenCentral() - project.sonarqube { - properties { - property "sonar.java.coveragePlugin", "jacoco" - property "sonar.projectName", projectName - property "sonar.jacoco.reportPath", "${project.buildDir.name}/jacoco.exec" - property "sonar.links.homepage", "https://spring.io/${projectName}" - property "sonar.links.ci", "https://jenkins.spring.io/job/${projectName}/" - property "sonar.links.issue", "https://github.com/spring-projects/${projectName}/issues" - property "sonar.links.scm", "https://github.com/spring-projects/${projectName}" - property "sonar.links.scm_dev", "https://github.com/spring-projects/${projectName}.git" - } - } + configureSonarQube(project) project.tasks.create("dependencyManagementExport", DependencyManagementExportTask) @@ -73,4 +61,34 @@ class RootProjectPlugin implements Plugin { finalizeDeployArtifacts.dependsOn project.tasks.closeAndReleaseOssrhStagingRepository } } + + @SuppressWarnings("all") + private void applyPlugins(Project project) { + + PluginManager pluginManager = project.getPluginManager() + + pluginManager.apply(BasePlugin) + pluginManager.apply(NoHttpPlugin) + pluginManager.apply(SchemaPlugin) + pluginManager.apply(SpringNexusPublishPlugin) + pluginManager.apply("org.sonarqube") + } + + private void configureSonarQube(Project project) { + + String projectName = Utils.getProjectName(project) + + project.sonarqube { + properties { + property "sonar.projectName", projectName + property "sonar.java.coveragePlugin", "jacoco" + property "sonar.jacoco.reportPath", "${project.buildDir.name}/jacoco.exec" + property "sonar.links.homepage", "https://spring.io/${projectName}" + property "sonar.links.ci", "https://jenkins.spring.io/job/${projectName}/" + property "sonar.links.issue", "https://github.com/spring-projects/${projectName}/issues" + property "sonar.links.scm", "https://github.com/spring-projects/${projectName}" + property "sonar.links.scm_dev", "https://github.com/spring-projects/${projectName}.git" + } + } + } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy index f6c7f989..efedc0e8 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -18,15 +18,19 @@ package io.spring.gradle.convention import io.spring.gradle.dependencymanagement.DependencyManagementPlugin import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.plugins.PluginManager /** - * Adds and configures {@link DependencyManagementPlugin}. - *

- * Additionally, if 'gradle/dependency-management.gradle' file is present it will be - * automatically applied file for configuring the dependencies. + * Applies and configures the Spring Gradle {@link DependencyManagementPlugin}. + * + * Additionally, if a {@literal gradle/dependency-management.gradle} file is present in a Gradle {@link Project}, + * then this file will be automatically applied in order to configure {@link Project} additional dependencies. * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + * @see org.gradle.api.plugins.PluginManager */ class SpringDependencyManagementConventionPlugin implements Plugin { @@ -35,8 +39,10 @@ class SpringDependencyManagementConventionPlugin implements Plugin { @Override void apply(Project project) { - project.getPluginManager().apply(ManagementConfigurationPlugin) - project.getPluginManager().apply(DependencyManagementPlugin) + PluginManager pluginManager = project.getPluginManager() + + pluginManager.apply(ManagementConfigurationPlugin) + pluginManager.apply(DependencyManagementPlugin) project.dependencyManagement { resolutionStrategy { @@ -44,16 +50,22 @@ class SpringDependencyManagementConventionPlugin implements Plugin { } } + applyDependencyManagementResources(project) + } + + private void applyDependencyManagementResources(Project project) { + File rootDir = project.rootDir - List dependencyManagementFiles = [project.rootProject.file(DEPENDENCY_MANAGEMENT_RESOURCE)] + + List dependencyManagementFiles = [ project.rootProject.file(DEPENDENCY_MANAGEMENT_RESOURCE) ] for (File dir = project.projectDir; dir != rootDir; dir = dir.parentFile) { dependencyManagementFiles.add(new File(dir, DEPENDENCY_MANAGEMENT_RESOURCE)) } - dependencyManagementFiles.each { f -> - if (f.exists()) { - project.apply from: f.absolutePath + dependencyManagementFiles.each { file -> + if (file.exists()) { + project.apply from: file.absolutePath } } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy index d6704bf7..1591c658 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -21,26 +21,38 @@ import org.gradle.api.plugins.PluginManager import org.springframework.gradle.maven.SpringMavenPlugin /** - * Defines the Gradle project as a proper Spring Module. + * Defines a Gradle {@link Project} as a proper Spring module. * * @author Rob Winch * @author John Blum + * @see io.spring.gradle.convention.AbstractSpringJavaPlugin + * @see org.gradle.api.Project */ class SpringModulePlugin extends AbstractSpringJavaPlugin { @Override - void additionalPlugins(Project project) { + void applyAdditionalPlugins(Project project) { + + applyPlugins(project); + configureDeployArtifactsTask(project) + } + + @SuppressWarnings("all") + private void applyPlugins(Project project) { PluginManager pluginManager = project.getPluginManager(); pluginManager.apply(JavaLibraryPlugin.class) pluginManager.apply(SpringMavenPlugin.class); - pluginManager.apply("io.spring.convention.jacoco"); + } + + @SuppressWarnings("all") + private void configureDeployArtifactsTask(Project project) { def deployArtifacts = project.task("deployArtifacts") - deployArtifacts.group = 'Deploy tasks' - deployArtifacts.description = "Deploys the artifacts to either Artifactory or Maven Central" + deployArtifacts.group = 'Deployments' + deployArtifacts.description = "Deploys project artifacts to either Artifactory or Maven Central" if (!Utils.isRelease(project)) { deployArtifacts.dependsOn project.tasks.artifactoryPublish diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy index 6b05495d..7719d425 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -16,7 +16,6 @@ package io.spring.gradle.convention import org.gradle.api.Project -import org.gradle.api.plugins.PluginManager /** * @author Rob Winch @@ -25,13 +24,11 @@ import org.gradle.api.plugins.PluginManager class SpringSampleBootPlugin extends SpringSamplePlugin { @Override - void additionalPlugins(Project project) { + void applyAdditionalPlugins(Project project) { - super.additionalPlugins(project); + super.applyAdditionalPlugins(project); - PluginManager pluginManager = project.getPluginManager(); - - pluginManager.apply("org.springframework.boot"); + project.getPluginManager().apply("org.springframework.boot"); project.repositories { maven { url 'https://repo.spring.io/snapshot' } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy index aaec8595..4996a0ed 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -19,13 +19,17 @@ import org.gradle.api.Project import org.sonarqube.gradle.SonarQubePlugin; /** + * Gradle Spring Java Plugin used to identify a Gradle {@link Project} as a {@literal Sample} and add configuration + * to skip Sonar Qube inspections. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Project */ class SpringSamplePlugin extends AbstractSpringJavaPlugin { @Override - void additionalPlugins(Project project) { + void applyAdditionalPlugins(Project project) { project.plugins.withType(SonarQubePlugin) { project.sonarqube.skipProject = true } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy index 4ae3e90f..9911549d 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -21,15 +21,19 @@ import org.gradle.api.plugins.PluginManager import org.gradle.api.tasks.testing.Test /** + * Spring Sample Gradle Plugin used to build Samples as a Java Web Application (WAR archive). + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Project + * @see org.gradle.api.Task */ class SpringSampleWarPlugin extends SpringSamplePlugin { @Override - void additionalPlugins(Project project) { + void applyAdditionalPlugins(Project project) { - super.additionalPlugins(project); + super.applyAdditionalPlugins(project); PluginManager pluginManager = project.getPluginManager(); @@ -44,10 +48,10 @@ class SpringSampleWarPlugin extends SpringSamplePlugin { Task prepareAppServerForIntegrationTests = project.tasks.create('prepareAppServerForIntegrationTests') { group = 'Verification' - description = 'Prepares the app server for integration tests' + description = 'Prepares the Web application server for Integration Testing' doFirst { project.gretty { - httpPort = getRandomFreePort() + httpPort = getRandomPort() httpsPort = getRandomPort() } } @@ -58,7 +62,7 @@ class SpringSampleWarPlugin extends SpringSamplePlugin { } project.tasks.withType(Test).all { task -> - if("integrationTest".equals(task.name)) { + if ("integrationTest".equals(task.name)) { applyForIntegrationTest(project, task) } } @@ -79,8 +83,8 @@ class SpringSampleWarPlugin extends SpringSamplePlugin { int port = isHttps ? httpsPort : httpPort - String host = project.gretty.host ?: 'localhost' - String contextPath = project.gretty.contextPath + String host = gretty.host ?: 'localhost' + String contextPath = gretty.contextPath String httpBaseUrl = "http://${host}:${httpPort}${contextPath}" String httpsBaseUrl = "https://${host}:${httpsPort}${contextPath}" String baseUrl = isHttps ? httpsBaseUrl : httpBaseUrl diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy index 9d9c842b..e9c67c19 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -13,18 +13,19 @@ * License for the specific language governing permissions and limitations under * the License. */ -package io.spring.gradle.convention; +package io.spring.gradle.convention -import org.gradle.api.Project; +import org.gradle.api.Project /** + * Gradle Plugin used to disable Sonar Qube inspection(s) during Spring project tests. * @author Rob Winch * @author John Blum */ class SpringTestPlugin extends AbstractSpringJavaPlugin { @Override - void additionalPlugins(Project project) { + void applyAdditionalPlugins(Project project) { project.sonarqube.skipProject = true } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy index 22151cb4..12163540 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -21,7 +21,7 @@ import org.gradle.api.plugins.JavaPlugin import org.gradle.jvm.tasks.Jar /** - * Adds the ability to depends on the test jar within other projects using: + * Adds ability to depend on the test JAR within other Gradle {@link Project Projects} using: * * * testImplementation project(path: ':foo', configuration: 'tests') @@ -29,29 +29,28 @@ import org.gradle.jvm.tasks.Jar * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ class TestsConfigurationPlugin implements Plugin { @Override void apply(Project project) { + project.plugins.withType(JavaPlugin) { - applyJavaProject(project) - } - } - private void applyJavaProject(Project project) { + project.configurations { + tests.extendsFrom testRuntime, testRuntimeClasspath + } - project.configurations { - tests.extendsFrom testRuntime, testRuntimeClasspath - } + project.tasks.create('testJar', Jar) { + archiveClassifier = 'test' + from project.sourceSets.test.output + } - project.tasks.create('testJar', Jar) { - classifier = 'test' - from project.sourceSets.test.output - } - - project.artifacts { - tests project.testJar + project.artifacts { + tests project.testJar + } } } } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy index 18bb8143..f36a9d2d 100644 --- a/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -18,8 +18,11 @@ package io.spring.gradle.convention; import org.gradle.api.Project; /** + * Utility class encapsulating common operations on Gradle {@link Project Projects}. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Project */ class Utils { @@ -52,4 +55,8 @@ class Utils { private static String projectVersion(Project project) { return String.valueOf(project.getVersion()); } + + static String findPropertyAsString(Project project, String propertyName) { + return (String) project.findProperty(propertyName); + } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/CopyPropertiesPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/CopyPropertiesPlugin.java index 78819fe5..0015c83e 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/CopyPropertiesPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/CopyPropertiesPlugin.java @@ -13,26 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.gradle; import org.gradle.api.Plugin; import org.gradle.api.Project; +/** + * Copies {@literal root} {@link Project} properties to the target ({@literal this}) {@link Project}, + * the {@link Project} for which {@literal this} Gadle {@link Plugin} is applied. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + */ public class CopyPropertiesPlugin implements Plugin { + @Override public void apply(Project project) { + copyPropertyFromRootProjectTo("group", project); copyPropertyFromRootProjectTo("version", project); copyPropertyFromRootProjectTo("description", project); } - private void copyPropertyFromRootProjectTo(String propertyName, Project project) { - Project rootProject = project.getRootProject(); - Object property = rootProject.findProperty(propertyName); - if(property != null) { - project.setProperty(propertyName, property); + + Object propertyValue = project.getRootProject().findProperty(propertyName); + + if (propertyValue != null) { + project.setProperty(propertyName, propertyValue); } } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/MavenPublishingConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/MavenPublishingConventionsPlugin.java index 8ed94c4c..6bbe45fc 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/MavenPublishingConventionsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/MavenPublishingConventionsPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -13,10 +13,8 @@ * License for the specific language governing permissions and limitations under * the License. */ - package org.springframework.gradle.maven; -import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlugin; @@ -31,68 +29,87 @@ import org.gradle.api.publish.maven.MavenPomScm; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; +/** + * Customizes the Maven POM generated from the Gradle {@link Project}. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + */ public class MavenPublishingConventionsPlugin implements Plugin { + @Override public void apply(Project project) { - project.getPlugins().withType(MavenPublishPlugin.class).all(new Action() { - @Override - public void execute(MavenPublishPlugin mavenPublish) { - PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - publishing.getPublications().withType(MavenPublication.class) - .all((mavenPublication) -> MavenPublishingConventionsPlugin.this.customizePom(mavenPublication.getPom(), project)); - MavenPublishingConventionsPlugin.this.customizeJavaPlugin(project); - } + + project.getPlugins().withType(MavenPublishPlugin.class).all(mavenPublishPlugin -> { + + PublishingExtension publishingExtension = project.getExtensions().getByType(PublishingExtension.class); + + publishingExtension.getPublications().withType(MavenPublication.class).all(mavenPublication -> + customizeMavenPom(project, mavenPublication.getPom())); + + customizeJavaPlugin(project); }); } - private void customizePom(MavenPom pom, Project project) { - pom.getUrl().set("https://spring.io/projects/spring-session"); + private void customizeJavaPlugin(Project project) { + + project.getPlugins().withType(JavaPlugin.class).all(javaPlugin -> { + + JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); + + extension.withJavadocJar(); + extension.withSourcesJar(); + }); + } + + private void customizeMavenPom(Project project, MavenPom pom) { + pom.getName().set(project.provider(project::getName)); pom.getDescription().set(project.provider(project::getDescription)); - pom.organization(this::customizeOrganization); + pom.getUrl().set("https://github.com/spring-projects/spring-boot-data-geode"); pom.licenses(this::customizeLicences); + pom.organization(this::customizeOrganization); pom.developers(this::customizeDevelopers); pom.scm(this::customizeScm); pom.issueManagement(this::customizeIssueManagement); } - private void customizeOrganization(MavenPomOrganization organization) { - organization.getName().set("Pivotal Software, Inc."); - organization.getUrl().set("https://spring.io"); + private void customizeDevelopers(MavenPomDeveloperSpec developers) { + + developers.developer(developer -> { + developer.getName().set("VMware"); + developer.getEmail().set("info@vmware.com"); + developer.getOrganization().set("VMware, Inc."); + developer.getOrganizationUrl().set("https://www.spring.io"); + }); + } + + private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { + + issueManagement.getSystem().set("GitHub"); + issueManagement.getUrl().set("https://github.com/spring-projects/spring-boot-data-geode/issues"); } private void customizeLicences(MavenPomLicenseSpec licences) { - licences.license((licence) -> { + + licences.license(licence -> { licence.getName().set("Apache License, Version 2.0"); licence.getUrl().set("https://www.apache.org/licenses/LICENSE-2.0"); }); } - private void customizeDevelopers(MavenPomDeveloperSpec developers) { - developers.developer((developer) -> { - developer.getName().set("Pivotal"); - developer.getEmail().set("info@pivotal.io"); - developer.getOrganization().set("Pivotal Software, Inc."); - developer.getOrganizationUrl().set("https://www.spring.io"); - }); + private void customizeOrganization(MavenPomOrganization organization) { + + organization.getName().set("VMware, Inc."); + organization.getUrl().set("https://spring.io"); } private void customizeScm(MavenPomScm scm) { - scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-session.git"); - scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-session.git"); - scm.getUrl().set("https://github.com/spring-projects/spring-session"); - } - private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { - issueManagement.getSystem().set("GitHub"); - issueManagement.getUrl().set("https://github.com/spring-projects/spring-session/issues"); - } - - private void customizeJavaPlugin(Project project) { - project.getPlugins().withType(JavaPlugin.class).all((javaPlugin) -> { - JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); - extension.withJavadocJar(); - extension.withSourcesJar(); - }); + scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-boot-data-geode.git"); + scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-boot-data-geode.git"); + scm.getUrl().set("https://github.com/spring-projects/spring-boot-data-geode"); } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishAllJavaComponentsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishAllJavaComponentsPlugin.java index 408d83e7..819a6aa9 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishAllJavaComponentsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishAllJavaComponentsPlugin.java @@ -1,32 +1,36 @@ package org.springframework.gradle.maven; - -import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlatformPlugin; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.publish.PublishingExtension; -import org.gradle.api.publish.VariantVersionMappingStrategy; -import org.gradle.api.publish.VersionMappingStrategy; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; +/** + * Adds the Java and JavaPlatform based projects to be published via Maven. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + */ public class PublishAllJavaComponentsPlugin implements Plugin { + @Override public void apply(Project project) { - project.getPlugins().withType(MavenPublishPlugin.class).all((mavenPublish) -> { + + project.getPlugins().withType(MavenPublishPlugin.class).all(mavenPublish -> { + PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - publishing.getPublications().create("mavenJava", MavenPublication.class, new Action() { - @Override - public void execute(MavenPublication maven) { - project.getPlugins().withType(JavaPlugin.class, (plugin) -> { - maven.from(project.getComponents().getByName("java")); - }); - project.getPlugins().withType(JavaPlatformPlugin.class, (plugin) -> { - maven.from(project.getComponents().getByName("javaPlatform")); - }); - } + + publishing.getPublications().create("mavenJava", MavenPublication.class, maven -> { + project.getPlugins().withType(JavaPlugin.class, + plugin -> maven.from(project.getComponents().getByName("java"))); + + project.getPlugins().withType(JavaPlatformPlugin.class, + plugin -> maven.from(project.getComponents().getByName("javaPlatform"))); }); }); } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishArtifactsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishArtifactsPlugin.java index ed3985e2..adf237af 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishArtifactsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishArtifactsPlugin.java @@ -1,25 +1,52 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ package org.springframework.gradle.maven; -import io.spring.gradle.convention.Utils; -import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Project; -import org.gradle.api.Task; +import io.spring.gradle.convention.Utils; + +/** + * Publishes Gradle {@link Project} artifacts to either Artifactory (Spring Repositories) or Maven Central + * through OSSRH. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + * @see Artifatory Gradle Plugin + * @see Maven Central Sonatype Gradle Support + */ public class PublishArtifactsPlugin implements Plugin { + @Override public void apply(Project project) { - project.getTasks().register("publishArtifacts", new Action() { - @Override - public void execute(Task publishArtifacts) { - publishArtifacts.setGroup("Publishing"); - publishArtifacts.setDescription("Publish the artifacts to either Artifactory or Maven Central based on the version"); - if (Utils.isRelease(project)) { - publishArtifacts.dependsOn("publishToOssrh"); - } - else { - publishArtifacts.dependsOn("artifactoryPublish"); - } + + project.getTasks().register("publishArtifacts", publishArtifacts -> { + + publishArtifacts.setGroup("Publishing"); + publishArtifacts.setDescription("Publish project artifacts to either Artifactory (Spring Repositories) " + + "or Maven Central based on the project version"); + + if (Utils.isRelease(project)) { + publishArtifacts.dependsOn("publishToOssrh"); + } + else { + publishArtifacts.dependsOn("artifactoryPublish"); } }); } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishLocalPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishLocalPlugin.java index 54f9e497..d2a61790 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/PublishLocalPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/PublishLocalPlugin.java @@ -1,29 +1,50 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ package org.springframework.gradle.maven; -import org.gradle.api.Action; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.artifacts.repositories.MavenArtifactRepository; -import org.gradle.api.publish.PublishingExtension; -import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; - import java.io.File; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.publish.PublishingExtension; +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; + +/** + * Adds configuration to publish Gradle {@link Project} artifacts to a {@literal local} Maven Repository, + * rooted at {@literal projectDir/buildDir/publications/repos}. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + */ +// TODO: Is this action even necessary?? public class PublishLocalPlugin implements Plugin { + @Override public void apply(Project project) { - project.getPlugins().withType(MavenPublishPlugin.class).all(new Action() { - @Override - public void execute(MavenPublishPlugin mavenPublish) { - PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - publishing.getRepositories().maven(new Action() { - @Override - public void execute(MavenArtifactRepository maven) { - maven.setName("local"); - maven.setUrl(new File(project.getRootProject().getBuildDir(), "publications/repos")); - } - }); - } + + project.getPlugins().withType(MavenPublishPlugin.class).all(mavenPublish -> { + + PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); + + publishing.getRepositories().maven(maven -> { + maven.setName("local"); + maven.setUrl(new File(project.getRootProject().getBuildDir(), "publications/repos")); + }); }); } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPlugin.java index 7a042ce1..f9a043cd 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -22,8 +22,12 @@ import org.gradle.api.plugins.PluginManager; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; /** + * Declares and enables Maven functionality for a Spring Gradle {@link Project Projects}. + * * @author Rob Winch * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project */ public class SpringMavenPlugin implements Plugin { @@ -33,11 +37,11 @@ public class SpringMavenPlugin implements Plugin { PluginManager pluginManager = project.getPluginManager(); pluginManager.apply(MavenPublishPlugin.class); - pluginManager.apply(SpringSigningPlugin.class); pluginManager.apply(MavenPublishingConventionsPlugin.class); pluginManager.apply(PublishAllJavaComponentsPlugin.class); - pluginManager.apply(PublishLocalPlugin.class); pluginManager.apply(PublishArtifactsPlugin.class); + pluginManager.apply(PublishLocalPlugin.class); + pluginManager.apply(SpringSigningPlugin.class); pluginManager.apply(ArtifactoryPlugin.class); } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPublishPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPublishPlugin.java index 4376e5fb..db846f91 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPublishPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPublishPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -24,6 +24,13 @@ import org.gradle.api.Project; import io.github.gradlenexus.publishplugin.NexusPublishExtension; import io.github.gradlenexus.publishplugin.NexusPublishPlugin; +/** + * Enables a Gradle {@link Project} to publish to Maven Central through OSSRH using Sonatype's Nexus Repository Manager. + * + * @author Rob Winch + * @author John Blum + * @see Nexus Publish Gradle Plugin + */ public class SpringNexusPublishPlugin implements Plugin { @Override @@ -33,13 +40,20 @@ public class SpringNexusPublishPlugin implements Plugin { NexusPublishExtension nexusPublishing = project.getExtensions().findByType(NexusPublishExtension.class); + // TODO: Why did we not simply use/configure the 'sonatype' repository and instead add a repo ('ossrh')? + // See here: https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh + // NOTE: Careful, the keyword 'ossrh' is refered to in names in the Spring Build Conventions Gradle Plugins, + // such as, but not limited to: + // * 'ossrhUsername' + // * 'publishToOssrh' + // * 'closeAndReleaseOssrhStagingRepository' nexusPublishing.getRepositories().create("ossrh", nexusRepository -> { nexusRepository.getNexusUrl().set(URI.create("https://s01.oss.sonatype.org/service/local/")); nexusRepository.getSnapshotRepositoryUrl() .set(URI.create("https://s01.oss.sonatype.org/content/repositories/snapshots/")); }); - nexusPublishing.getConnectTimeout().set(Duration.ofMinutes(3)); nexusPublishing.getClientTimeout().set(Duration.ofMinutes(3)); + nexusPublishing.getConnectTimeout().set(Duration.ofMinutes(3)); } } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java index 53acf0a5..25d4c233 100644 --- a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2022-present the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -24,34 +24,76 @@ import org.gradle.api.publish.PublishingExtension; import org.gradle.plugins.signing.SigningExtension; import org.gradle.plugins.signing.SigningPlugin; +import io.spring.gradle.convention.Utils; + +/** + * Signs all Gradle {@link Project} artifacts. + * + * @author Rob Winch + * @author John Blum + * @see org.gradle.api.Plugin + * @see org.gradle.api.Project + * @see org.gradle.plugins.signing.SigningPlugin + */ public class SpringSigningPlugin implements Plugin { @Override public void apply(Project project) { - project.getPluginManager().apply(SigningPlugin.class); + if (isSigningRequired(project)) { + project.getPluginManager().apply(SigningPlugin.class); + sign(project); + } + } - project.getPlugins().withType(SigningPlugin.class).all(signingPlugin -> { + private boolean isSigningRequired(Project project) { + return isSigningKeyPresent(project) && isRelease(project); + } - boolean hasSigningKey = project.hasProperty("signing.keyId") - || project.hasProperty("signingKey"); + private boolean isSigningKeyPresent(Project project) { - if (hasSigningKey) { - sign(project); - } - }); + return project.hasProperty("signing.keyId") + || project.hasProperty("signingKeyId") + || project.hasProperty("signingKey"); + } + + private boolean isRelease(Project project) { + return Utils.isRelease(project); } private void sign(Project project) { + SigningExtension signing = resolveAndConfigureSigningExtension(project); + + project.getPlugins().withType(PublishAllJavaComponentsPlugin.class).all(publishingPlugin -> { + PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class); + Publication maven = publishing.getPublications().getByName("mavenJava"); + signing.sign(maven); + }); + } + + private SigningExtension resolveAndConfigureSigningExtension(Project project) { + SigningExtension signing = project.getExtensions().findByType(SigningExtension.class); - signing.setRequired((Callable) () -> - project.getGradle().getTaskGraph().hasTask("publishArtifacts")); + return configurePgpKeys(project, configureSigningRequired(project, signing)); + } - String signingKey = (String) project.findProperty("signingKey"); - String signingKeyId = (String) project.findProperty("signingKeyId"); - String signingPassword = (String) project.findProperty("signingPassword"); + private SigningExtension configureSigningRequired(Project project, SigningExtension signing) { + + Callable signingRequired = + () -> project.getGradle().getTaskGraph().hasTask("publishArtifacts"); + + signing.setRequired(signingRequired); + + return signing; + } + + private SigningExtension configurePgpKeys(Project project, SigningExtension signing) { + + String signingKey = Utils.findPropertyAsString(project, "signingKey"); + String signingKeyId = resolveSigningKeyId(project); + String signingPassword = Utils.findPropertyAsString(project, "signingPassword"); if (signingKeyId != null) { signing.useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword); @@ -60,10 +102,14 @@ public class SpringSigningPlugin implements Plugin { signing.useInMemoryPgpKeys(signingKey, signingPassword); } - project.getPlugins().withType(PublishAllJavaComponentsPlugin.class).all(publishingPlugin -> { - PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class); - Publication maven = publishing.getPublications().getByName("mavenJava"); - signing.sign(maven); - }); + return signing; + } + + private String resolveSigningKeyId(Project project) { + + String signingKeyId = Utils.findPropertyAsString(project, "signingKeyId"); + + return signingKeyId != null ? signingKeyId + : Utils.findPropertyAsString(project, "signing.keyId"); } } diff --git a/gradle/maven-pom-editor.gradle b/gradle/maven-pom-editor.gradle deleted file mode 100644 index 2cae4230..00000000 --- a/gradle/maven-pom-editor.gradle +++ /dev/null @@ -1,33 +0,0 @@ - -def customizePom(gradleProject, pom) { - - pom.whenConfigured { generatedPom -> - generatedPom.project { - developers { - developer { - id = 'jxblum' - name = "John Blum" - email = "jblum@pivotal.io" - } - } - scm { - connection = 'scm:git:git@github.com:spring-projects/spring-boot-data-geode.git' - developerConnection = 'scm:git:git@github.com:spring-projects/spring-boot-data-geode.git' - url = 'https://github.com/spring-projects/spring-boot-data-geode' - } - url = 'https://github.com/spring-projects/spring-boot-data-geode#spring-boot-for-apache-geode' - } - } -} - -project.install { - repositories.mavenInstaller { - customizePom(project, pom) - } -} - -project.uploadArchives { - repositories.mavenDeployer { - customizePom(project, pom) - } -} diff --git a/spring-geode-bom/spring-geode-bom.gradle b/spring-geode-bom/spring-geode-bom.gradle index 474d192f..05f97adb 100644 --- a/spring-geode-bom/spring-geode-bom.gradle +++ b/spring-geode-bom/spring-geode-bom.gradle @@ -1,4 +1,4 @@ -import io.spring.gradle.convention.SpringMavenPlugin +import io.spring.gradle.convention.SpringModulePlugin apply plugin: 'io.spring.convention.bom' apply from: MAVEN_POM_EDITOR_GRADLE @@ -6,7 +6,7 @@ apply from: MAVEN_POM_EDITOR_GRADLE sonarqube.skipProject = true project.rootProject.allprojects.each { p -> - p.plugins.withType(SpringMavenPlugin) { + p.plugins.withType(SpringModulePlugin) { if (!project.name.equals(p.name)) { project.mavenBom.projects.add(p) }