diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b82bfa..cb4d8f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,68 +8,41 @@ on: jobs: build: - runs-on: ubuntu-latest - if: ${{ github.repository == 'spring-projects/spring-security-kerberos' }} + name: Build + uses: spring-io/spring-security-release-tools/.github/workflows/build.yml@v1 strategy: - fail-fast: false matrix: include: - - nickname: linux adopt 17 - version: 17 - distribution: adopt - - nickname: linux liberica 17 - version: 17 - distribution: liberica - name: CI Build ${{ matrix.nickname }} - steps: - - uses: actions/checkout@v3 - - uses: spring-io/spring-gradle-build-action@v1 - with: - distribution: ${{ matrix.distribution }} - java-version: ${{ matrix.version }} - - name: Build - env: - GRADLE_ENTERPRISE_CACHE_USERNAME: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }} - GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }} - GRADLE_ENTERPRISE_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} - run: ./gradlew build - - uses: actions/upload-artifact@v3 - if: ${{ failure() }} - with: - name: buildreports - retention-days: 1 - path: | - */build/reports - spring-security-kerberos-samples/*/build/reports - publish: + - nickname: linux adopt 17 + jdk: 17 + jdk-distribution: adopt + - nickname: linux liberica 17 + version: 17 + distribution: liberica + with: + runs-on: ubuntu-latest + java-version: ${{ matrix.jdk }} + distribution: ${{ matrix.jdk-distribution }} + secrets: inherit + deploy-artifacts: + name: Deploy Artifacts + needs: [ build ] + uses: spring-io/spring-security-release-tools/.github/workflows/deploy-artifacts.yml@v1 + with: + should-deploy-artifacts: ${{ needs.build.outputs.should-deploy-artifacts }} + secrets: inherit + deploy-docs: + name: Deploy Javadocs + needs: [ build ] + uses: spring-io/spring-security-release-tools/.github/workflows/deploy-docs.yml@v1 + with: + should-deploy-docs: ${{ needs.build.outputs.should-deploy-artifacts }} + secrets: inherit + docs: runs-on: ubuntu-latest needs: [build] steps: - - uses: actions/checkout@v3 - - uses: spring-io/spring-gradle-build-action@v1 - with: - distribution: adopt - java-version: 17 - - name: Build - env: - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.GPG_PRIVATE_KEY }} - ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_PASSPHRASE }} - OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }} - OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }} - ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }} - ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }} - DEVELOCITY_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} - run: | - ./gradlew build publishArtifacts \ - -PossrhUsername="$OSSRH_TOKEN_USERNAME" \ - -PossrhPassword="$OSSRH_TOKEN_PASSWORD" \ - -PartifactoryUsername="$ARTIFACTORY_USERNAME" \ - -PartifactoryPassword="$ARTIFACTORY_PASSWORD" - docs: - runs-on: ubuntu-latest - needs: [publish] - steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Dispatch (partial build) if: github.ref_type == 'branch' env: diff --git a/build.gradle b/build.gradle index c2ec9b9..80a09ab 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id "base" - id 'org.springframework.security.kerberos.root' + id 'io.spring.convention.root' + alias(libs.plugins.security.release) } description = 'Spring Security Kerberos' @@ -37,3 +37,14 @@ develocity { termsOfUseAgree = 'yes' } } + +springRelease { + repositoryOwner = "spring-projects" + repositoryName = "spring-security-kerberos" + weekOfMonth = 4 + dayOfWeek = 1 + referenceDocUrl = "https://docs.spring.io/spring-security-kerberos/reference/{version}/" + apiDocUrl = "https://docs.spring.io/spring-security-kerberos/docs/{version}/api/" + replaceVersionInReferenceDocUrl = true + releaseVersionPrefix = "v" +} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 93f322f..2502dda 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,57 +1,39 @@ plugins { id "java-gradle-plugin" id "java" + id "groovy" } -sourceCompatibility = JavaVersion.VERSION_17 +java { + sourceCompatibility = JavaVersion.VERSION_17 +} repositories { gradlePluginPortal() mavenCentral() - maven { url 'https://repo.spring.io/plugins-release/' } - maven { url "https://repo.spring.io/snapshot" } -} - -ext { - def propertiesFile = new File(new File("$projectDir").parentFile, "gradle.properties") - propertiesFile.withInputStream { - def properties = new Properties() - properties.load(it) - set("springFrameworkVersion", properties["springFrameworkVersion"]) - } + maven { url "https://repo.spring.io/plugins-release/" } } dependencies { - implementation(platform(libs.spring.framework.bom)) - implementation("org.springframework:spring-core") - implementation 'org.asciidoctor:asciidoctor-gradle-jvm:3.3.2' - implementation 'org.jfrog.buildinfo:build-info-extractor-gradle:4.33.16' - implementation 'org.antora:gradle-antora-plugin:1.0.0' - implementation 'io.spring.gradle.antora:spring-antora-plugin:0.0.1' - implementation 'io.github.gradle-nexus:publish-plugin:1.1.0' + implementation "com.github.ben-manes:gradle-versions-plugin:0.38.0" + implementation "io.github.gradle-nexus:publish-plugin:1.1.0" + implementation "io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.41" + implementation "io.spring.nohttp:nohttp-gradle:0.0.11" + implementation "org.asciidoctor:asciidoctor-gradle-jvm:3.3.2" + implementation "org.asciidoctor:asciidoctor-gradle-jvm-pdf:3.3.2" + implementation "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" + implementation "org.hidetake:gradle-ssh-plugin:2.10.1" + implementation "org.jfrog.buildinfo:build-info-extractor-gradle:5.2.0" + implementation "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1" + implementation "org.springframework:spring-core:6.1.7" } + gradlePlugin { plugins { - modulePlugin { - id = "org.springframework.security.kerberos.module" - implementationClass = "org.springframework.security.kerberos.gradle.ModulePlugin" - } - bomPlugin { - id = "org.springframework.security.kerberos.bom" - implementationClass = "org.springframework.security.kerberos.gradle.BomPlugin" - } - docsPlugin { - id = "org.springframework.security.kerberos.docs" - implementationClass = "org.springframework.security.kerberos.gradle.DocsPlugin" - } - distPlugin { - id = "org.springframework.security.kerberos.root" - implementationClass = "org.springframework.security.kerberos.gradle.RootPlugin" - } samplePlugin { id = "org.springframework.security.kerberos.sample" implementationClass = "org.springframework.security.kerberos.gradle.SamplePlugin" } } -} +} \ No newline at end of file diff --git a/buildSrc/gradle/libs.versions.toml b/buildSrc/gradle/libs.versions.toml deleted file mode 120000 index d9b1d4e..0000000 --- a/buildSrc/gradle/libs.versions.toml +++ /dev/null @@ -1 +0,0 @@ -../../gradle/libs.versions.toml \ No newline at end of file diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenBomPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenBomPlugin.groovy new file mode 100644 index 0000000..488864c --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenBomPlugin.groovy @@ -0,0 +1,17 @@ +package io.spring.gradle.convention + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlatformPlugin +import org.springframework.gradle.properties.SpringCopyPropertiesPlugin +import org.springframework.gradle.SpringMavenPlugin + +public class SpringMavenBomPlugin implements Plugin { + static String MAVEN_BOM_TASK_NAME = "mavenBom" + + public void apply(Project project) { + project.plugins.apply(JavaPlatformPlugin) + project.plugins.apply(SpringMavenPlugin) + project.plugins.apply(SpringCopyPropertiesPlugin) + } +} diff --git a/buildSrc/src/main/groovy/org/springframework/gradle/docs/SpringDeployDocsPlugin.groovy b/buildSrc/src/main/groovy/org/springframework/gradle/docs/SpringDeployDocsPlugin.groovy new file mode 100644 index 0000000..8ad17d9 --- /dev/null +++ b/buildSrc/src/main/groovy/org/springframework/gradle/docs/SpringDeployDocsPlugin.groovy @@ -0,0 +1,78 @@ +/* + * Copyright 2002-2022 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.docs + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class SpringDeployDocsPlugin implements Plugin { + + @Override + void apply(Project project) { + project.getPluginManager().apply('org.hidetake.ssh') + + project.ssh.settings { + knownHosts = allowAnyHosts + } + project.remotes { + docs { + role 'docs' + if (project.hasProperty('deployDocsHost')) { + host = project.findProperty('deployDocsHost') + } + retryCount = 5 // retry 5 times (default is 0) + retryWaitSec = 10 // wait 10 seconds between retries (default is 0) + user = project.findProperty('deployDocsSshUsername') + if (project.hasProperty('deployDocsSshKeyPath')) { + identity = project.file(project.findProperty('deployDocsSshKeyPath')) + } else if (project.hasProperty('deployDocsSshKey')) { + identity = project.findProperty('deployDocsSshKey') + } + if (project.hasProperty('deployDocsSshPassphrase')) { + passphrase = project.findProperty('deployDocsSshPassphrase') + } + } + } + + project.task('deployDocs') { + dependsOn 'docsZip' + doFirst { + project.ssh.run { + session(project.remotes.docs) { + def now = System.currentTimeMillis() + def name = project.rootProject.name + def version = project.rootProject.version + def tempPath = "/tmp/${name}-${now}-docs/".replaceAll(' ', '_') + execute "mkdir -p $tempPath" + + project.tasks.docsZip.outputs.each { o -> + put from: o.files, into: tempPath + } + + execute "unzip $tempPath*.zip -d $tempPath" + + def extractPath = "/var/www/domains/spring.io/docs/htdocs/autorepo/docs/${name}/${version}/" + + execute "rm -rf $extractPath" + execute "mkdir -p $extractPath" + execute "mv $tempPath/docs/* $extractPath" + execute "chmod -R g+w $extractPath" + } + } + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java b/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java new file mode 100644 index 0000000..e567d60 --- /dev/null +++ b/buildSrc/src/main/java/io/spring/gradle/convention/SpringDocsPlugin.java @@ -0,0 +1,90 @@ +/* + * Copyright 2002-2022 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 io.spring.gradle.convention; + +import java.io.File; + +import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.file.DuplicatesStrategy; +import org.gradle.api.plugins.BasePlugin; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.PluginManager; +import org.gradle.api.tasks.TaskContainer; +import org.gradle.api.tasks.bundling.Zip; + +import org.springframework.gradle.docs.SpringAsciidoctorPlugin; +import org.springframework.gradle.docs.SpringJavadocApiPlugin; +import org.springframework.gradle.docs.SpringJavadocOptionsPlugin; +import org.springframework.gradle.management.SpringManagementConfigurationPlugin; +import org.springframework.gradle.maven.SpringRepositoryPlugin; + +/** + * Aggregates asciidoc, javadoc, and deploying of the docs into a single plugin. + * + * @author Steve Riesenberg + */ +public class SpringDocsPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply default plugins + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(BasePlugin.class); + pluginManager.apply(JavaPlugin.class); + pluginManager.apply(SpringManagementConfigurationPlugin.class); + pluginManager.apply(SpringRepositoryPlugin.class); + pluginManager.apply(SpringAsciidoctorPlugin.class); + // Note: Applying plugin via id since it requires groovy compilation + pluginManager.apply("org.springframework.gradle.deploy-docs"); + pluginManager.apply(SpringJavadocApiPlugin.class); + pluginManager.apply(SpringJavadocOptionsPlugin.class); + + TaskContainer tasks = project.getTasks(); + project.configure(tasks.withType(AbstractAsciidoctorTask.class), (task) -> { + File destination = new File(project.getBuildDir(), "docs"); + task.setOutputDir(destination); + task.sources((patternSet) -> { + patternSet.include("**/*.adoc"); + patternSet.exclude("_*/**"); + }); + }); + + // Add task to create documentation archive + Zip docsZip = tasks.create("docsZip", Zip.class, (zip) -> { + zip.dependsOn(tasks.getByName("api"), tasks.getByName("asciidoctor")/*, tasks.getByName("asciidoctorPdf")*/); + zip.setGroup("Distribution"); + zip.getArchiveBaseName().set(project.getRootProject().getName()); + zip.getArchiveClassifier().set("docs"); + zip.setDescription("Builds -docs archive containing all " + + "Docs for deployment at docs.spring.io"); + zip.into("docs"); + zip.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); + }); + + // Add task to aggregate documentation + Task docs = tasks.create("docs", (task) -> { + task.dependsOn(docsZip); + task.setGroup("Documentation"); + task.setDescription("An aggregator task to generate all the documentation"); + }); + + // Wire docs task into the build + tasks.getByName("assemble").dependsOn(docs); + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ModulePlugin.java b/buildSrc/src/main/java/io/spring/gradle/convention/SpringModulePlugin.java similarity index 61% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ModulePlugin.java rename to buildSrc/src/main/java/io/spring/gradle/convention/SpringModulePlugin.java index 0680702..821c392 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ModulePlugin.java +++ b/buildSrc/src/main/java/io/spring/gradle/convention/SpringModulePlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2002-2022 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. @@ -13,28 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; + +package io.spring.gradle.convention; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.JavaLibraryPlugin; -import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.PluginManager; -/** - * @author Janne Valkealahti - */ -class ModulePlugin implements Plugin { +import org.springframework.gradle.SpringJavaPlugin; +import org.springframework.gradle.SpringMavenPlugin; +import org.springframework.gradle.classpath.SpringCheckClasspathForProhibitedDependenciesPlugin; +/** + * @author Steve Riesenberg + */ +public class SpringModulePlugin implements Plugin { @Override - public final void apply(Project project) { + public void apply(Project project) { + // Apply default plugins PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(JavaPlugin.class); - pluginManager.apply(OptionalDependenciesPlugin.class); - pluginManager.apply(ManagementConfigurationPlugin.class); pluginManager.apply(JavaLibraryPlugin.class); + pluginManager.apply(SpringJavaPlugin.class); pluginManager.apply(SpringMavenPlugin.class); - new ArtifactoryConventions().apply(project); - new JavaConventions().apply(project); + pluginManager.apply(SpringCheckClasspathForProhibitedDependenciesPlugin.class); } } diff --git a/buildSrc/src/main/java/io/spring/gradle/convention/SpringRootProjectPlugin.java b/buildSrc/src/main/java/io/spring/gradle/convention/SpringRootProjectPlugin.java new file mode 100644 index 0000000..169b433 --- /dev/null +++ b/buildSrc/src/main/java/io/spring/gradle/convention/SpringRootProjectPlugin.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2023 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 io.spring.gradle.convention; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.BasePlugin; +import org.gradle.api.plugins.PluginManager; + +import org.springframework.gradle.classpath.SpringCheckProhibitedDependenciesLifecyclePlugin; +import org.springframework.gradle.maven.SpringArtifactoryPlugin; +import org.springframework.gradle.maven.SpringNexusPlugin; +import org.springframework.gradle.nohttp.SpringNoHttpPlugin; +import org.springframework.gradle.sonarqube.SpringSonarQubePlugin; + +/** + * @author Steve Riesenberg + */ +public class SpringRootProjectPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply default plugins + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(BasePlugin.class); + pluginManager.apply(SpringNoHttpPlugin.class); + pluginManager.apply(SpringNexusPlugin.class); + pluginManager.apply(SpringCheckProhibitedDependenciesLifecyclePlugin.class); + pluginManager.apply(SpringArtifactoryPlugin.class); + pluginManager.apply(SpringSonarQubePlugin.class); + + // Apply default repositories + project.getRepositories().mavenCentral(); + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/Utils.java b/buildSrc/src/main/java/org/springframework/gradle/ProjectUtils.java similarity index 63% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/Utils.java rename to buildSrc/src/main/java/org/springframework/gradle/ProjectUtils.java index e829cdc..5f62b29 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/Utils.java +++ b/buildSrc/src/main/java/org/springframework/gradle/ProjectUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 the original author or authors. + * Copyright 2002-2022 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. @@ -13,26 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; + +package org.springframework.gradle; import org.gradle.api.Project; /** - * @author Janne Valkealahti + * @author Steve Riesenberg */ -class Utils { +public class ProjectUtils { + private ProjectUtils() { + } - static boolean isSnapshot(Project project) { + public static String getProjectName(Project project) { + String projectName = project.getRootProject().getName(); + if (projectName.endsWith("-build")) { + projectName = projectName.substring(0, projectName.length() - "-build".length()); + } + return projectName; + } + + public static boolean isSnapshot(Project project) { String projectVersion = projectVersion(project); return projectVersion.matches("^.*([.-]BUILD)?-SNAPSHOT$"); } - static boolean isMilestone(Project project) { + public static boolean isMilestone(Project project) { String projectVersion = projectVersion(project); return projectVersion.matches("^.*[.-]M\\d+$") || projectVersion.matches("^.*[.-]RC\\d+$"); } - static boolean isRelease(Project project) { + public static boolean isRelease(Project project) { return !(isSnapshot(project) || isMilestone(project)); } diff --git a/buildSrc/src/main/java/org/springframework/gradle/SpringJavaPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/SpringJavaPlugin.java new file mode 100644 index 0000000..4727c00 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/SpringJavaPlugin.java @@ -0,0 +1,100 @@ +/* + * Copyright 2002-2022 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; + +import java.util.HashMap; +import java.util.Map; + +import io.spring.javaformat.gradle.SpringJavaFormatPlugin; +import org.gradle.api.JavaVersion; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.GroovyPlugin; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.plugins.PluginManager; +import org.gradle.api.tasks.compile.CompileOptions; +import org.gradle.api.tasks.compile.JavaCompile; +import org.gradle.api.tasks.testing.Test; +import org.gradle.jvm.tasks.Jar; +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper; + +import org.springframework.gradle.checkstyle.SpringJavaCheckstylePlugin; +import org.springframework.gradle.docs.SpringJavadocOptionsPlugin; +import org.springframework.gradle.jacoco.SpringJacocoPlugin; +import org.springframework.gradle.management.SpringManagementConfigurationPlugin; +import org.springframework.gradle.maven.SpringRepositoryPlugin; +import org.springframework.gradle.propdeps.SpringPropDepsEclipsePlugin; +import org.springframework.gradle.propdeps.SpringPropDepsIdeaPlugin; +import org.springframework.gradle.properties.SpringCopyPropertiesPlugin; + +/** + * @author Steve Riesenberg + */ +public class SpringJavaPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply default plugins + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(JavaPlugin.class); + pluginManager.apply(SpringManagementConfigurationPlugin.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); + } + if (project.file("src/main/kotlin").exists() + || project.file("src/test/kotlin").exists() + || project.file("src/integration-test/kotlin").exists() + || project.getBuildFile().getName().endsWith(".kts")) { + pluginManager.apply(KotlinPluginWrapper.class); + } + pluginManager.apply(SpringRepositoryPlugin.class); + pluginManager.apply(SpringPropDepsEclipsePlugin.class); + pluginManager.apply(SpringPropDepsIdeaPlugin.class); + pluginManager.apply(SpringJavadocOptionsPlugin.class); + pluginManager.apply(SpringJavaFormatPlugin.class); + pluginManager.apply(SpringJavaCheckstylePlugin.class); + pluginManager.apply(SpringCopyPropertiesPlugin.class); + pluginManager.apply(SpringJacocoPlugin.class); + + // Apply Java source compatibility version + JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); + java.setTargetCompatibility(JavaVersion.VERSION_17); + + // Configure Java tasks + project.getTasks().withType(JavaCompile.class, (javaCompile) -> { + CompileOptions options = javaCompile.getOptions(); + options.setEncoding("UTF-8"); + options.getCompilerArgs().add("-parameters"); + if (JavaVersion.current().isJava11Compatible()) { + options.getRelease().set(17); + } + }); + project.getTasks().withType(Jar.class, (jar) -> jar.manifest((manifest) -> { + Map attributes = new HashMap<>(); + attributes.put("Created-By", String.format("%s (%s)", System.getProperty("java.version"), System.getProperty("java.specification.vendor"))); + attributes.put("Implementation-Title", project.getName()); + attributes.put("Implementation-Version", project.getVersion().toString()); + attributes.put("Automatic-Module-Name", project.getName().replace("-", ".")); + manifest.attributes(attributes); + })); + project.getTasks().withType(Test.class, (test) -> { + test.useJUnitPlatform(); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/SpringMavenPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/SpringMavenPlugin.java new file mode 100644 index 0000000..c7c8c96 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/SpringMavenPlugin.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2022 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; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.PluginManager; +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; + +import org.springframework.gradle.maven.SpringArtifactoryPlugin; +import org.springframework.gradle.maven.SpringMavenPublishingConventionsPlugin; +import org.springframework.gradle.maven.SpringPublishAllJavaComponentsPlugin; +import org.springframework.gradle.maven.SpringPublishArtifactsPlugin; +import org.springframework.gradle.maven.SpringPublishLocalPlugin; +import org.springframework.gradle.maven.SpringSigningPlugin; + +/** + * @author Steve Riesenberg + */ +public class SpringMavenPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply default plugins + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(MavenPublishPlugin.class); + + pluginManager.apply(SpringSigningPlugin.class); + pluginManager.apply(SpringMavenPublishingConventionsPlugin.class); + pluginManager.apply(SpringPublishAllJavaComponentsPlugin.class); + pluginManager.apply(SpringPublishLocalPlugin.class); + pluginManager.apply(SpringPublishArtifactsPlugin.class); + pluginManager.apply(SpringArtifactoryPlugin.class); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/checkstyle/SpringJavaCheckstylePlugin.java b/buildSrc/src/main/java/org/springframework/gradle/checkstyle/SpringJavaCheckstylePlugin.java new file mode 100644 index 0000000..1478222 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/checkstyle/SpringJavaCheckstylePlugin.java @@ -0,0 +1,105 @@ +/* + * Copyright 2002-2024 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.checkstyle; + +import java.io.File; +import java.util.Objects; + +import javax.annotation.Nullable; + +import io.spring.javaformat.gradle.tasks.CheckFormat; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.quality.CheckstyleExtension; +import org.gradle.api.plugins.quality.CheckstylePlugin; + +/** + * Adds and configures Checkstyle plugin. + * + * @author Vedran Pavic + * @author Steve Riesenberg + */ +public class SpringJavaCheckstylePlugin implements Plugin { + private static final String CHECKSTYLE_DIR = "etc/checkstyle"; + private static final String SPRING_JAVAFORMAT_VERSION_PROPERTY = "springJavaformatVersion"; + private static final String DEFAULT_SPRING_JAVAFORMAT_VERSION = "0.0.41"; + private static final String NOHTTP_CHECKSTYLE_VERSION_PROPERTY = "nohttpCheckstyleVersion"; + private static final String DEFAULT_NOHTTP_CHECKSTYLE_VERSION = "0.0.11"; + private static final String CHECKSTYLE_TOOL_VERSION_PROPERTY = "checkstyleToolVersion"; + private static final String DEFAULT_CHECKSTYLE_TOOL_VERSION = "8.34"; + private static final String SPRING_JAVAFORMAT_EXCLUDE_PACKAGES_PROPERTY = "springJavaformatExcludePackages"; + + @Override + public void apply(Project project) { + project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { + File checkstyleDir = project.getRootProject().file(CHECKSTYLE_DIR); + if (checkstyleDir.exists() && checkstyleDir.isDirectory()) { + project.getPluginManager().apply(CheckstylePlugin.class); + + // NOTE: See gradle.properties#springJavaformatVersion for actual version number + project.getDependencies().add("checkstyle", "io.spring.javaformat:spring-javaformat-checkstyle:" + getSpringJavaformatVersion(project)); + // NOTE: See gradle.properties#nohttpCheckstyleVersion for actual version number + project.getDependencies().add("checkstyle", "io.spring.nohttp:nohttp-checkstyle:" + getNohttpCheckstyleVersion(project)); + + CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class); + checkstyle.getConfigDirectory().set(checkstyleDir); + // NOTE: See gradle.properties#checkstyleToolVersion for actual version number + checkstyle.setToolVersion(getCheckstyleToolVersion(project)); + } + + // Configure checkFormat task + project.getTasks().withType(CheckFormat.class, (checkFormat) -> { + // NOTE: See gradle.properties#springJavaformatExcludePackages for excluded packages + String[] springJavaformatExcludePackages = getSpringJavaformatExcludePackages(project); + if (springJavaformatExcludePackages != null) { + checkFormat.exclude(springJavaformatExcludePackages); + } + }); + }); + } + + private static String getSpringJavaformatVersion(Project project) { + String springJavaformatVersion = DEFAULT_SPRING_JAVAFORMAT_VERSION; + if (project.hasProperty(SPRING_JAVAFORMAT_VERSION_PROPERTY)) { + springJavaformatVersion = Objects.requireNonNull(project.findProperty(SPRING_JAVAFORMAT_VERSION_PROPERTY)).toString(); + } + return springJavaformatVersion; + } + + private static String getNohttpCheckstyleVersion(Project project) { + String nohttpCheckstyleVersion = DEFAULT_NOHTTP_CHECKSTYLE_VERSION; + if (project.hasProperty(NOHTTP_CHECKSTYLE_VERSION_PROPERTY)) { + nohttpCheckstyleVersion = Objects.requireNonNull(project.findProperty(NOHTTP_CHECKSTYLE_VERSION_PROPERTY)).toString(); + } + return nohttpCheckstyleVersion; + } + + private static String getCheckstyleToolVersion(Project project) { + String checkstyleToolVersion = DEFAULT_CHECKSTYLE_TOOL_VERSION; + if (project.hasProperty(CHECKSTYLE_TOOL_VERSION_PROPERTY)) { + checkstyleToolVersion = Objects.requireNonNull(project.findProperty(CHECKSTYLE_TOOL_VERSION_PROPERTY)).toString(); + } + return checkstyleToolVersion; + } + + @Nullable + private String[] getSpringJavaformatExcludePackages(Project project) { + String springJavaformatExcludePackages = (String) project.findProperty(SPRING_JAVAFORMAT_EXCLUDE_PACKAGES_PROPERTY); + return (springJavaformatExcludePackages != null) ? springJavaformatExcludePackages.split(" ") : null; + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/classpath/CheckClasspathForProhibitedDependencies.java b/buildSrc/src/main/java/org/springframework/gradle/classpath/CheckClasspathForProhibitedDependencies.java new file mode 100644 index 0000000..8ec48b5 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/classpath/CheckClasspathForProhibitedDependencies.java @@ -0,0 +1,99 @@ +/* + * Copyright 2012-2022 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.classpath; + +import java.io.IOException; +import java.util.TreeSet; +import java.util.stream.Collectors; + +import org.gradle.api.DefaultTask; +import org.gradle.api.GradleException; +import org.gradle.api.Task; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.ModuleVersionIdentifier; +import org.gradle.api.artifacts.ResolvedConfiguration; +import org.gradle.api.file.FileCollection; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.TaskAction; + +/** + * A {@link Task} for checking the classpath for prohibited dependencies. + * + * @author Andy Wilkinson + */ +public class CheckClasspathForProhibitedDependencies extends DefaultTask { + + private Configuration classpath; + + public CheckClasspathForProhibitedDependencies() { + getOutputs().upToDateWhen((task) -> true); + } + + public void setClasspath(Configuration classpath) { + this.classpath = classpath; + } + + @Classpath + public FileCollection getClasspath() { + return this.classpath; + } + + @TaskAction + public void checkForProhibitedDependencies() throws IOException { + ResolvedConfiguration resolvedConfiguration = this.classpath.getResolvedConfiguration(); + TreeSet prohibited = resolvedConfiguration.getResolvedArtifacts().stream() + .map((artifact) -> artifact.getModuleVersion().getId()).filter(this::prohibited) + .map((id) -> id.getGroup() + ":" + id.getName()).collect(Collectors.toCollection(TreeSet::new)); + if (!prohibited.isEmpty()) { + StringBuilder message = new StringBuilder(String.format("Found prohibited dependencies in '%s':%n", this.classpath.getName())); + for (String dependency : prohibited) { + message.append(String.format(" %s%n", dependency)); + } + throw new GradleException(message.toString()); + } + } + + private boolean prohibited(ModuleVersionIdentifier id) { + String group = id.getGroup(); + if (group.equals("javax.batch")) { + return false; + } + if (group.equals("javax.cache")) { + return false; + } + if (group.equals("javax.money")) { + return false; + } + if (group.startsWith("javax")) { + return true; + } + if (group.equals("commons-logging")) { + return true; + } + if (group.equals("org.slf4j") && id.getName().equals("jcl-over-slf4j")) { + return true; + } + if (group.startsWith("org.jboss.spec")) { + return true; + } + if (group.equals("org.apache.geronimo.specs")) { + return true; + } + return false; + } + +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckClasspathForProhibitedDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckClasspathForProhibitedDependenciesPlugin.java new file mode 100644 index 0000000..4b92b2e --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckClasspathForProhibitedDependenciesPlugin.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2022 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.classpath; + +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.JavaBasePlugin; +import org.gradle.api.tasks.SourceSetContainer; +import org.gradle.api.tasks.TaskProvider; +import org.gradle.language.base.plugins.LifecycleBasePlugin; + +import org.springframework.util.StringUtils; + +/** + * @author Andy Wilkinson + * @author Rob Winch + */ +public class SpringCheckClasspathForProhibitedDependenciesPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.getPlugins().apply(SpringCheckProhibitedDependenciesLifecyclePlugin.class); + project.getPlugins().withType(JavaBasePlugin.class, (javaBasePlugin) -> + configureProhibitedDependencyChecks(project)); + } + + private void configureProhibitedDependencyChecks(Project project) { + SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class); + sourceSets.all((sourceSet) -> createProhibitedDependenciesChecks(project, + sourceSet.getCompileClasspathConfigurationName(), sourceSet.getRuntimeClasspathConfigurationName())); + } + + private void createProhibitedDependenciesChecks(Project project, String... configurationNames) { + ConfigurationContainer configurations = project.getConfigurations(); + for (String configurationName : configurationNames) { + Configuration configuration = configurations.getByName(configurationName); + createProhibitedDependenciesCheck(configuration, project); + } + } + + private void createProhibitedDependenciesCheck(Configuration classpath, Project project) { + String taskName = "check" + StringUtils.capitalize(classpath.getName() + "ForProhibitedDependencies"); + TaskProvider checkClasspathTask = project.getTasks().register(taskName, + CheckClasspathForProhibitedDependencies.class, (checkClasspath) -> { + checkClasspath.setGroup(LifecycleBasePlugin.CHECK_TASK_NAME); + checkClasspath.setDescription("Checks " + classpath.getName() + " for prohibited dependencies"); + checkClasspath.setClasspath(classpath); + }); + project.getTasks().named(SpringCheckProhibitedDependenciesLifecyclePlugin.CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, (checkProhibitedTask) -> checkProhibitedTask.dependsOn(checkClasspathTask)); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckProhibitedDependenciesLifecyclePlugin.java b/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckProhibitedDependenciesLifecyclePlugin.java new file mode 100644 index 0000000..a8d649b --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/classpath/SpringCheckProhibitedDependenciesLifecyclePlugin.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2022 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.classpath; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.plugins.JavaBasePlugin; +import org.gradle.api.tasks.TaskProvider; + +/** + * @author Rob Winch + */ +public class SpringCheckProhibitedDependenciesLifecyclePlugin implements Plugin { + public static final String CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME = "checkForProhibitedDependencies"; + + @Override + public void apply(Project project) { + TaskProvider checkProhibitedDependencies = project.getTasks().register(SpringCheckProhibitedDependenciesLifecyclePlugin.CHECK_PROHIBITED_DEPENDENCIES_TASK_NAME, (task) -> { + task.setGroup(JavaBasePlugin.VERIFICATION_GROUP); + task.setDescription("Checks both the compile/runtime classpath of every SourceSet for prohibited dependencies"); + }); + project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME, (checkTask) -> { + checkTask.dependsOn(checkProhibitedDependencies); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java new file mode 100644 index 0000000..5946b8f --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringAsciidoctorPlugin.java @@ -0,0 +1,146 @@ +/* + * Copyright 2019-2020 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.docs; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask; +import org.asciidoctor.gradle.jvm.AsciidoctorJExtension; +import org.asciidoctor.gradle.jvm.AsciidoctorJPlugin; +import org.asciidoctor.gradle.jvm.AsciidoctorTask; +import org.asciidoctor.gradle.jvm.pdf.AsciidoctorJPdfPlugin; +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +/** + * Conventions that are applied in the presence of the {@link AsciidoctorJPlugin}. When + * the plugin is applied: + * + *
    + *
  • All warnings are made fatal. + *
  • A task is created to resolve and unzip our documentation resources (CSS and + * Javascript). + *
  • For each {@link AsciidoctorTask} (HTML only): + *
      + *
    • A configuration named asciidoctorExtensions is used to add the + * block + * switch extension + *
    • {@code doctype} {@link AsciidoctorTask#options(Map) option} is configured. + *
    • {@link AsciidoctorTask#attributes(Map) Attributes} are configured for syntax + * highlighting, CSS styling, docinfo, etc. + *
    + *
  • For each {@link AbstractAsciidoctorTask} (HTML and PDF): + *
      + *
    • {@link AsciidoctorTask#attributes(Map) Attributes} are configured to enable + * warnings for references to missing attributes, the year is added as @{code today-year}, + * etc + *
    • {@link AbstractAsciidoctorTask#baseDirFollowsSourceDir() baseDirFollowsSourceDir()} + * is enabled. + *
    + *
+ * + * @author Andy Wilkinson + * @author Rob Winch + * @author Steve Riesenberg + */ +public class SpringAsciidoctorPlugin implements Plugin { + private static final String ASCIIDOCTORJ_VERSION = "2.4.3"; + private static final String EXTENSIONS_CONFIGURATION_NAME = "asciidoctorExtensions"; + + @Override + public void apply(Project project) { + // Apply asciidoctor plugin + project.getPluginManager().apply(AsciidoctorJPlugin.class); + project.getPluginManager().apply(AsciidoctorJPdfPlugin.class); + + // Configure asciidoctor + project.getPlugins().withType(AsciidoctorJPlugin.class, (asciidoctorPlugin) -> { + configureDocumentationDependenciesRepository(project); + makeAllWarningsFatal(project); + upgradeAsciidoctorJVersion(project); + createAsciidoctorExtensionsConfiguration(project); + project.getTasks().withType(AbstractAsciidoctorTask.class, this::configureAsciidoctorExtension); + }); + } + + private void configureDocumentationDependenciesRepository(Project project) { + project.getRepositories().maven((mavenRepo) -> { + mavenRepo.setUrl(URI.create("https://repo.spring.io/release")); + mavenRepo.mavenContent((mavenContent) -> { + mavenContent.includeGroup("io.spring.asciidoctor"); + mavenContent.includeGroup("io.spring.asciidoctor.backends"); + mavenContent.includeGroup("io.spring.docresources"); + }); + }); + } + + private void makeAllWarningsFatal(Project project) { + project.getExtensions().getByType(AsciidoctorJExtension.class).fatalWarnings(".*"); + } + + private void upgradeAsciidoctorJVersion(Project project) { + project.getExtensions().getByType(AsciidoctorJExtension.class).setVersion(ASCIIDOCTORJ_VERSION); + } + + private void createAsciidoctorExtensionsConfiguration(Project project) { + project.getConfigurations().create(EXTENSIONS_CONFIGURATION_NAME, (configuration) -> { + project.getConfigurations().matching((candidate) -> "management".equals(candidate.getName())) + .all(configuration::extendsFrom); + configuration.getDependencies().add(project.getDependencies() + .create("io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.5")); + configuration.getDependencies() + .add(project.getDependencies().create("org.asciidoctor:asciidoctorj-pdf:1.5.3")); + }); + } + + private void configureAsciidoctorExtension(AbstractAsciidoctorTask asciidoctorTask) { + asciidoctorTask.configurations(EXTENSIONS_CONFIGURATION_NAME); + configureCommonAttributes(asciidoctorTask); + configureOptions(asciidoctorTask); + asciidoctorTask.baseDirFollowsSourceDir(); + asciidoctorTask.resources((resourcesSpec) -> { + resourcesSpec.from(asciidoctorTask.getSourceDir(), (resourcesSrcDirSpec) -> { + // Not using intermediateWorkDir. + // See https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/523 + resourcesSrcDirSpec.include("images/*.png", "css/**", "js/**", "**/*.java"); + // This exclusion is required to allow cacheability of :spring-authorization-server-docs:asciidoctor + // The whole docs/src/docs/asciidoc folder is being passed as a task input + resourcesSrcDirSpec.exclude("**/examples/build/**"); + }); + }); + if (asciidoctorTask instanceof AsciidoctorTask) { + boolean pdf = asciidoctorTask.getName().toLowerCase().contains("pdf"); + String backend = (!pdf) ? "spring-html" : "spring-pdf"; + ((AsciidoctorTask) asciidoctorTask).outputOptions((outputOptions) -> + outputOptions.backends(backend)); + } + } + + private void configureCommonAttributes(AbstractAsciidoctorTask asciidoctorTask) { + Map attributes = new HashMap<>(); + attributes.put("attribute-missing", "warn"); + attributes.put("revnumber", null); + asciidoctorTask.attributes(attributes); + } + + private void configureOptions(AbstractAsciidoctorTask asciidoctorTask) { + asciidoctorTask.options(Collections.singletonMap("doctype", "book")); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocApiPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocApiPlugin.java new file mode 100644 index 0000000..dac79b1 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocApiPlugin.java @@ -0,0 +1,108 @@ +/* + * Copyright 2002-2022 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.docs; + +import java.io.File; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +import io.spring.gradle.convention.SpringModulePlugin; +import org.gradle.api.Action; +import org.gradle.api.JavaVersion; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.javadoc.Javadoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Rob Winch + * @author Steve Riesenberg + */ +public class SpringJavadocApiPlugin implements Plugin { + private final Logger logger = LoggerFactory.getLogger(getClass()); + private Set excludes = Collections.singleton(Pattern.compile("test")); + + @Override + public void apply(Project project) { + // Create task to generate aggregated docs + Javadoc api = project.getTasks().create("api", Javadoc.class, (javadoc) -> { + javadoc.setGroup("Documentation"); + javadoc.setDescription("Generates aggregated Javadoc API documentation."); + }); + + // Note: The following action cannot be a lambda, for groovy compatibility + api.doLast(new Action() { + @Override + public void execute(Task task) { + if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) { + project.copy((copy) -> copy.from(api.getDestinationDir()) + .into(api.getDestinationDir()) + .include("element-list") + .rename("element-list", "package-list")); + } + } + }); + + Set subprojects = project.getRootProject().getSubprojects(); + for (Project subproject : subprojects) { + addProject(api, subproject); + } + + if (subprojects.isEmpty()) { + addProject(api, project); + } + + api.setMaxMemory("1024m"); + api.setDestinationDir(new File(project.getBuildDir(), "api")); + } + + public void setExcludes(String... excludes) { + if (excludes == null) { + this.excludes = Collections.emptySet(); + } + this.excludes = new HashSet<>(excludes.length); + for (String exclude : excludes) { + this.excludes.add(Pattern.compile(exclude)); + } + } + + private void addProject(Javadoc api, Project project) { + for (Pattern exclude : excludes) { + if (exclude.matcher(project.getName()).matches()) { + logger.info("Skipping {} because it is excluded by {}", project, exclude); + return; + } + } + logger.info("Try add sources for {}", project); + project.getPlugins().withType(SpringModulePlugin.class, (plugin) -> { + logger.info("Added sources for {}", project); + + JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); + SourceSet mainSourceSet = java.getSourceSets().getByName("main"); + + api.setSource(api.getSource().plus(mainSourceSet.getAllJava())); + project.getTasks().withType(Javadoc.class).all((projectJavadoc) -> + api.setClasspath(api.getClasspath().plus(projectJavadoc.getClasspath()))); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocOptionsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocOptionsPlugin.java new file mode 100644 index 0000000..04d9073 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/docs/SpringJavadocOptionsPlugin.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2022 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.docs; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.tasks.javadoc.Javadoc; +import org.gradle.external.javadoc.StandardJavadocDocletOptions; + +/** + * @author Steve Riesenberg + */ +public class SpringJavadocOptionsPlugin implements Plugin { + @Override + public void apply(Project project) { + project.getTasks().withType(Javadoc.class, (javadoc) -> { + StandardJavadocDocletOptions options = (StandardJavadocDocletOptions) javadoc.getOptions(); + options.addStringOption("Xdoclint:none", "-quiet"); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/jacoco/SpringJacocoPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/jacoco/SpringJacocoPlugin.java new file mode 100644 index 0000000..010e42b --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/jacoco/SpringJacocoPlugin.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2022 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.jacoco; + +import java.util.Objects; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.testing.jacoco.plugins.JacocoPlugin; +import org.gradle.testing.jacoco.plugins.JacocoPluginExtension; + +/** + * Adds a version of jacoco to use and makes check depend on jacocoTestReport. + * + * @author Rob Winch + * @author Steve Riesenberg + */ +public class SpringJacocoPlugin implements Plugin { + private static final String JACOCO_TOOL_VERSION_PROPERTY = "jacocoToolVersion"; + private static final String DEFAULT_JACOCO_TOOL_VERSION = "0.8.7"; + + @Override + public void apply(Project project) { + project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { + project.getPluginManager().apply(JacocoPlugin.class); + project.getTasks().getByName("check").dependsOn(project.getTasks().getByName("jacocoTestReport")); + + JacocoPluginExtension jacoco = project.getExtensions().getByType(JacocoPluginExtension.class); + // NOTE: See gradle.properties#jacocoToolVersion for actual version number + jacoco.setToolVersion(getJacocoToolVersion(project)); + }); + } + + private static String getJacocoToolVersion(Project project) { + String jacocoToolVersion = DEFAULT_JACOCO_TOOL_VERSION; + if (project.hasProperty(JACOCO_TOOL_VERSION_PROPERTY)) { + jacocoToolVersion = Objects.requireNonNull(project.findProperty(JACOCO_TOOL_VERSION_PROPERTY)).toString(); + } + return jacocoToolVersion; + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ManagementConfigurationPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/management/SpringManagementConfigurationPlugin.java similarity index 65% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ManagementConfigurationPlugin.java rename to buildSrc/src/main/java/org/springframework/gradle/management/SpringManagementConfigurationPlugin.java index d359d2b..802a247 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ManagementConfigurationPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/management/SpringManagementConfigurationPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2002-2021 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; + +package org.springframework.gradle.management; import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -22,19 +23,18 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaTestFixturesPlugin; import org.gradle.api.plugins.PluginContainer; import org.gradle.api.publish.PublishingExtension; +import org.gradle.api.publish.VariantVersionMappingStrategy; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; /** - * Creates a Management configuration that is appropriate for adding a platform - * to that is not exposed externally. If the JavaPlugin is applied, the - * compileClasspath, runtimeClasspath, testCompileClasspath, and - * testRuntimeClasspath will extend from it. - * - * @author Janne Valkealahti + * Creates a Management configuration that is appropriate for adding a platform to that is not exposed externally. If + * the JavaPlugin is applied, the compileClasspath, runtimeClasspath, testCompileClasspath, and testRuntimeClasspath + * will extend from it. + * @author Rob Winch + * @author Steve Riesenberg */ -public class ManagementConfigurationPlugin implements Plugin { - +public class SpringManagementConfigurationPlugin implements Plugin { public static final String MANAGEMENT_CONFIGURATION_NAME = "management"; @Override @@ -44,24 +44,24 @@ public class ManagementConfigurationPlugin implements Plugin { management.setVisible(false); management.setCanBeConsumed(false); management.setCanBeResolved(false); + PluginContainer plugins = project.getPlugins(); plugins.withType(JavaPlugin.class, (javaPlugin) -> { - configurations.getByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME).extendsFrom(management); + configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); + configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); + configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); + configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(management); }); plugins.withType(JavaTestFixturesPlugin.class, (javaTestFixturesPlugin) -> { configurations.getByName("testFixturesCompileClasspath").extendsFrom(management); configurations.getByName("testFixturesRuntimeClasspath").extendsFrom(management); }); - plugins.withType(OptionalDependenciesPlugin.class, (optionalDependencies) -> configurations - .getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME).extendsFrom(management)); plugins.withType(MavenPublishPlugin.class, (mavenPublish) -> { PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - publishing.getPublications().withType(MavenPublication.class, (mavenPublication -> { - mavenPublication.versionMapping((versions) -> - versions.allVariants(versionMapping -> versionMapping.fromResolutionResult()) - ); - })); + publishing.getPublications().withType(MavenPublication.class, (mavenPublication) -> + mavenPublication.versionMapping((versions) -> + versions.allVariants(VariantVersionMappingStrategy::fromResolutionResult))); }); }); } -} +} \ No newline at end of file diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringArtifactoryPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringArtifactoryPlugin.java new file mode 100644 index 0000000..85226e4 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringArtifactoryPlugin.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2024 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.Plugin; +import org.gradle.api.Project; +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; +import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin; +import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention; + +import org.springframework.gradle.ProjectUtils; + +/** + * @author Steve Riesenberg + */ +public class SpringArtifactoryPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply base plugin + project.getPlugins().apply(ArtifactoryPlugin.class); + + // Apply artifactory repository configuration + boolean isSnapshot = ProjectUtils.isSnapshot(project); + boolean isMilestone = ProjectUtils.isMilestone(project); + + ArtifactoryPluginConvention artifactoryExtension = project.getExtensions().getByType(ArtifactoryPluginConvention.class); + artifactoryExtension.publish((publish) -> { + publish.setContextUrl("https://repo.spring.io"); + publish.repository((repository) -> { + String repoKey = isSnapshot ? "libs-snapshot-local" : isMilestone ? "libs-milestone-local" : "libs-release-local"; + repository.setRepoKey(repoKey); + if (project.hasProperty("artifactoryUsername")) { + repository.setUsername((String) project.findProperty("artifactoryUsername")); + repository.setPassword((String) project.findProperty("artifactoryPassword")); + } + }); + // Would fail if maven publish is not applied, i.e. in root project (SpringRootProjectPlugin) + project.getPlugins().withType(MavenPublishPlugin.class, mavenPublish -> { + publish.defaults((defaults) -> defaults.publications("mavenJava")); + }); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPublishingConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPublishingConventionsPlugin.java new file mode 100644 index 0000000..ef7152b --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringMavenPublishingConventionsPlugin.java @@ -0,0 +1,106 @@ +/* + * Copyright 2002-2022 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 java.util.Collections; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.publish.PublishingExtension; +import org.gradle.api.publish.maven.MavenPom; +import org.gradle.api.publish.maven.MavenPomDeveloperSpec; +import org.gradle.api.publish.maven.MavenPomIssueManagement; +import org.gradle.api.publish.maven.MavenPomLicenseSpec; +import org.gradle.api.publish.maven.MavenPomOrganization; +import org.gradle.api.publish.maven.MavenPomScm; +import org.gradle.api.publish.maven.MavenPublication; +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; + +/** + * @author Steve Riesenberg + */ +public class SpringMavenPublishingConventionsPlugin implements Plugin { + @Override + public void apply(Project project) { + project.getPlugins().withType(MavenPublishPlugin.class, (mavenPublish) -> { + PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); + publishing.getPublications().withType(MavenPublication.class, (mavenPublication) -> + customizePom(mavenPublication.getPom(), project)); + SpringMavenPublishingConventionsPlugin.this.customizeJavaPlugin(project); + }); + } + + private void customizePom(MavenPom pom, Project project) { + pom.getUrl().set("https://spring.io/projects/spring-authorization-server"); + pom.getName().set(project.provider(project::getName)); + pom.getDescription().set(project.provider(project::getDescription)); + pom.organization(this::customizeOrganization); + pom.licenses(this::customizeLicences); + pom.developers(this::customizeDevelopers); + pom.scm(this::customizeScm); + pom.issueManagement(this::customizeIssueManagement); + } + + private void customizeOrganization(MavenPomOrganization organization) { + organization.getName().set("VMware, Inc."); + organization.getUrl().set("https://spring.io"); + } + + private void customizeLicences(MavenPomLicenseSpec licences) { + 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("Joe Grandja"); + developer.getEmail().set("jgrandja@vmware.com"); + developer.getOrganization().set("VMware, Inc."); + developer.getOrganizationUrl().set("https://spring.io"); + developer.getRoles().set(Collections.singletonList("Project lead")); + }); + developers.developer((developer) -> { + developer.getName().set("Steve Riesenberg"); + developer.getEmail().set("sriesenberg@vmware.com"); + developer.getOrganization().set("VMware, Inc."); + developer.getOrganizationUrl().set("https://spring.io"); + }); + } + + private void customizeScm(MavenPomScm scm) { + scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-authorization-server.git"); + scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-authorization-server.git"); + scm.getUrl().set("https://github.com/spring-projects/spring-authorization-server"); + } + + private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { + issueManagement.getSystem().set("GitHub"); + issueManagement.getUrl().set("https://github.com/spring-projects/spring-authorization-server/issues"); + } + + private void customizeJavaPlugin(Project project) { + project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { + JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); + extension.withJavadocJar(); + extension.withSourcesJar(); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringNexusPublishPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPlugin.java similarity index 66% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringNexusPublishPlugin.java rename to buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPlugin.java index 3a3eb03..6a486e4 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringNexusPublishPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringNexusPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 the original author or authors. + * Copyright 2002-2022 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. @@ -13,40 +13,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; + +package org.springframework.gradle.maven; import java.net.URI; import java.time.Duration; -import org.gradle.api.Action; +import io.github.gradlenexus.publishplugin.NexusPublishExtension; +import io.github.gradlenexus.publishplugin.NexusPublishPlugin; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; -import io.github.gradlenexus.publishplugin.NexusPublishExtension; -import io.github.gradlenexus.publishplugin.NexusPublishPlugin; -import io.github.gradlenexus.publishplugin.NexusRepository; - -public class SpringNexusPublishPlugin implements Plugin { +import org.springframework.gradle.ProjectUtils; +/** + * @author Steve Riesenberg + */ +public class SpringNexusPlugin implements Plugin { @Override public void apply(Project project) { + // Apply nexus publish plugin project.getPlugins().apply(NexusPublishPlugin.class); - NexusPublishExtension nexusPublishing = project.getExtensions().findByType(NexusPublishExtension.class); - nexusPublishing.getRepositories().create("ossrh", new Action() { - @Override - public void execute(NexusRepository 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/")); - } + + // Create ossrh repository + NexusPublishExtension nexusPublishing = project.getExtensions().getByType(NexusPublishExtension.class); + 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/")); }); + + // Configure timeouts nexusPublishing.getConnectTimeout().set(Duration.ofMinutes(3)); nexusPublishing.getClientTimeout().set(Duration.ofMinutes(3)); // Ensure release build automatically closes and releases staging repository Task finalizeDeployArtifacts = project.task("finalizeDeployArtifacts"); - if (Utils.isRelease(project) && project.hasProperty("ossrhUsername")) { + if (ProjectUtils.isRelease(project) && project.hasProperty("ossrhUsername")) { Task closeAndReleaseOssrhStagingRepository = project.getTasks().findByName("closeAndReleaseOssrhStagingRepository"); finalizeDeployArtifacts.dependsOn(closeAndReleaseOssrhStagingRepository); } diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishAllJavaComponentsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishAllJavaComponentsPlugin.java similarity index 61% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishAllJavaComponentsPlugin.java rename to buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishAllJavaComponentsPlugin.java index e8defb1..58999b6 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishAllJavaComponentsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishAllJavaComponentsPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2002-2022 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. @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; -import org.gradle.api.Action; +package org.springframework.gradle.maven; + import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlatformPlugin; @@ -24,22 +24,19 @@ import org.gradle.api.publish.PublishingExtension; import org.gradle.api.publish.maven.MavenPublication; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; -public class PublishAllJavaComponentsPlugin implements Plugin { - +/** + * @author Steve Riesenberg + */ +public class SpringPublishAllJavaComponentsPlugin implements Plugin { @Override public void apply(Project project) { - project.getPlugins().withType(MavenPublishPlugin.class).all((mavenPublish) -> { + project.getPlugins().withType(MavenPublishPlugin.class, (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/SpringPublishArtifactsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishArtifactsPlugin.java new file mode 100644 index 0000000..8868bc5 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishArtifactsPlugin.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2022 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.Plugin; +import org.gradle.api.Project; + +import org.springframework.gradle.ProjectUtils; + +/** + * @author Steve Riesenberg + */ +public class SpringPublishArtifactsPlugin implements Plugin { + @Override + public void apply(Project project) { + project.getTasks().register("publishArtifacts", (publishArtifacts) -> { + publishArtifacts.setGroup("Publishing"); + publishArtifacts.setDescription("Publish the artifacts to either Artifactory or Maven Central based on the version"); + if (ProjectUtils.isRelease(project)) { + publishArtifacts.dependsOn("publishToOssrh"); + } else { + publishArtifacts.dependsOn("artifactoryPublish"); + } + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishLocalPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishLocalPlugin.java similarity index 60% rename from buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishLocalPlugin.java rename to buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishLocalPlugin.java index b7afc70..aeac1be 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishLocalPlugin.java +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringPublishLocalPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2002-2024 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. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.security.kerberos.gradle; + +package org.springframework.gradle.maven; import java.io.File; @@ -22,15 +23,17 @@ import org.gradle.api.Project; import org.gradle.api.publish.PublishingExtension; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; -public class PublishLocalPlugin implements Plugin { - +/** + * @author Steve Riesenberg + */ +public class SpringPublishLocalPlugin implements Plugin { @Override public void apply(Project project) { - - project.getPlugins().withType(MavenPublishPlugin.class).all(mavenPublish -> { - project.getExtensions().getByType(PublishingExtension.class).getRepositories().maven(maven -> { + project.getPlugins().withType(MavenPublishPlugin.class, (mavenPublish) -> { + PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); + publishing.getRepositories().maven((maven) -> { maven.setName("local"); - maven.setUrl(new File(project.getRootProject().getBuildDir(), "publications/repos")); + maven.setUrl(new File(project.getRootProject().getLayout().getBuildDirectory().getAsFile().get(), "publications/repos")); }); }); } diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringRepositoryPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringRepositoryPlugin.java new file mode 100644 index 0000000..63895b6 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringRepositoryPlugin.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2022 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 java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +import org.springframework.gradle.ProjectUtils; + +/** + * @author Steve Riesenberg + */ +public class SpringRepositoryPlugin implements Plugin { + @Override + public void apply(Project project) { + List forceMavenRepositories = Collections.emptyList(); + if (project.hasProperty("forceMavenRepositories")) { + forceMavenRepositories = Arrays.asList(((String) project.findProperty("forceMavenRepositories")).split(",")); + } + + boolean isImplicitSnapshotRepository = forceMavenRepositories.isEmpty() && ProjectUtils.isSnapshot(project); + boolean isImplicitMilestoneRepository = forceMavenRepositories.isEmpty() && ProjectUtils.isMilestone(project); + + boolean isSnapshot = isImplicitSnapshotRepository || forceMavenRepositories.contains("snapshot"); + boolean isMilestone = isImplicitMilestoneRepository || forceMavenRepositories.contains("milestone"); + + if (forceMavenRepositories.contains("local")) { + project.getRepositories().mavenLocal(); + } + project.getRepositories().mavenCentral(); + if (isSnapshot) { + repository(project, "artifactory-snapshot", "https://repo.spring.io/snapshot/"); + } + if (isSnapshot || isMilestone) { + repository(project, "artifactory-milestone", "https://repo.spring.io/milestone/"); + } + repository(project, "artifactory-release", "https://repo.spring.io/release/"); + } + + private void repository(Project project, String name, String url) { + project.getRepositories().maven((repo) -> { + repo.setName(name); + if (project.hasProperty("artifactoryUsername")) { + repo.credentials((credentials) -> { + credentials.setUsername(Objects.requireNonNull(project.findProperty("artifactoryUsername")).toString()); + credentials.setPassword(Objects.requireNonNull(project.findProperty("artifactoryPassword")).toString()); + }); + } + repo.setUrl(url); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java new file mode 100644 index 0000000..5d5e870 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/maven/SpringSigningPlugin.java @@ -0,0 +1,61 @@ +/* + * Copyright 2002-2022 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 java.util.concurrent.Callable; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.publish.Publication; +import org.gradle.api.publish.PublishingExtension; +import org.gradle.plugins.signing.SigningExtension; +import org.gradle.plugins.signing.SigningPlugin; + +/** + * @author Steve Riesenberg + */ +public class SpringSigningPlugin implements Plugin { + @Override + public void apply(Project project) { + project.getPluginManager().apply(SigningPlugin.class); + project.getPlugins().withType(SigningPlugin.class, (signingPlugin) -> { + boolean hasSigningKey = project.hasProperty("signing.keyId") || project.hasProperty("signingKey"); + if (hasSigningKey) { + sign(project); + } + }); + } + + private void sign(Project project) { + SigningExtension signing = project.getExtensions().getByType(SigningExtension.class); + signing.setRequired((Callable) () -> project.getGradle().getTaskGraph().hasTask("publishArtifacts")); + + String signingKeyId = (String) project.findProperty("signingKeyId"); + String signingKey = (String) project.findProperty("signingKey"); + String signingPassword = (String) project.findProperty("signingPassword"); + if (signingKeyId != null) { + signing.useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword); + } else { + signing.useInMemoryPgpKeys(signingKey, signingPassword); + } + project.getPlugins().withType(SpringPublishAllJavaComponentsPlugin.class, (publishingPlugin) -> { + PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); + Publication maven = publishing.getPublications().getByName("mavenJava"); + signing.sign(maven); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/nohttp/SpringNoHttpPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/nohttp/SpringNoHttpPlugin.java new file mode 100644 index 0000000..f48b3a7 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/nohttp/SpringNoHttpPlugin.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2022 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.nohttp; + +import java.io.File; + +import io.spring.nohttp.gradle.NoHttpExtension; +import io.spring.nohttp.gradle.NoHttpPlugin; +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +/** + * @author Steve Riesenberg + */ +public class SpringNoHttpPlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply nohttp plugin + project.getPluginManager().apply(NoHttpPlugin.class); + + // Configure nohttp + NoHttpExtension nohttp = project.getExtensions().getByType(NoHttpExtension.class); + File allowlistFile = project.getRootProject().file("etc/nohttp/allowlist.lines"); + nohttp.setAllowlistFile(allowlistFile); + nohttp.getSource().exclude("**/build/**"); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsEclipsePlugin.java b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsEclipsePlugin.java new file mode 100644 index 0000000..75a745b --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsEclipsePlugin.java @@ -0,0 +1,47 @@ +/* + * Copyright 2002-2022 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.propdeps; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.PluginManager; +import org.gradle.plugins.ide.eclipse.EclipsePlugin; +import org.gradle.plugins.ide.eclipse.EclipseWtpPlugin; +import org.gradle.plugins.ide.eclipse.model.EclipseModel; + +/** + * Plugin to allow optional and provided dependency configurations to work with the + * standard gradle 'eclipse' plugin + * + * @author Phillip Webb + * @author Steve Riesenberg + */ +public class SpringPropDepsEclipsePlugin implements Plugin { + @Override + public void apply(Project project) { + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(SpringPropDepsPlugin.class); + pluginManager.apply(EclipsePlugin.class); + pluginManager.apply(EclipseWtpPlugin.class); + + EclipseModel eclipseModel = project.getExtensions().getByType(EclipseModel.class); + eclipseModel.classpath((classpath) -> { + classpath.getPlusConfigurations().add(project.getConfigurations().getByName("provided")); + classpath.getPlusConfigurations().add(project.getConfigurations().getByName("optional")); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsIdeaPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsIdeaPlugin.java new file mode 100644 index 0000000..47e0a3a --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsIdeaPlugin.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2022 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.propdeps; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.PluginManager; +import org.gradle.plugins.ide.idea.IdeaPlugin; +import org.gradle.plugins.ide.idea.model.IdeaModel; + +/** + * Plugin to allow optional and provided dependency configurations to work with the + * standard gradle 'idea' plugin + * + * @author Phillip Webb + * @author Brian Clozel + * @author Steve Riesenberg + * @link https://youtrack.jetbrains.com/issue/IDEA-107046 + * @link https://youtrack.jetbrains.com/issue/IDEA-117668 + */ +public class SpringPropDepsIdeaPlugin implements Plugin { + @Override + public void apply(Project project) { + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(SpringPropDepsPlugin.class); + pluginManager.apply(IdeaPlugin.class); + + IdeaModel ideaModel = project.getExtensions().getByType(IdeaModel.class); + ideaModel.module((idea) -> { + // IDEA internally deals with 4 scopes : COMPILE, TEST, PROVIDED, RUNTIME + // but only PROVIDED seems to be picked up + idea.getScopes().get("PROVIDED").get("plus").add(project.getConfigurations().getByName("provided")); + idea.getScopes().get("PROVIDED").get("plus").add(project.getConfigurations().getByName("optional")); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsPlugin.java new file mode 100644 index 0000000..2a0a591 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/propdeps/SpringPropDepsPlugin.java @@ -0,0 +1,80 @@ +/* + * Copyright 2002-2022 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.propdeps; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.plugins.JavaLibraryPlugin; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.tasks.javadoc.Javadoc; + +import org.springframework.gradle.management.SpringManagementConfigurationPlugin; + +/** + * Plugin to allow 'optional' and 'provided' dependency configurations + * + * As stated in the maven documentation, provided scope "is only available on the compilation and test classpath, + * and is not transitive". + * + * This plugin creates two new configurations, and each one: + *
    + *
  • is a parent of the compile configuration
  • + *
  • is not visible, not transitive
  • + *
  • all dependencies are excluded from the default configuration
  • + *
+ * + * @author Phillip Webb + * @author Brian Clozel + * @author Rob Winch + * @author Steve Riesenberg + * + * @see Maven documentation + * @see Gradle configurations + * @see SpringPropDepsEclipsePlugin + * @see SpringPropDepsIdeaPlugin + */ +public class SpringPropDepsPlugin implements Plugin { + @Override + public void apply(Project project) { + project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { + Configuration provided = addConfiguration(project, "provided"); + Configuration optional = addConfiguration(project, "optional"); + + Javadoc javadoc = (Javadoc) project.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME); + javadoc.setClasspath(javadoc.getClasspath().plus(provided).plus(optional)); + }); + } + + private Configuration addConfiguration(Project project, String name) { + Configuration configuration = project.getConfigurations().create(name); + configuration.extendsFrom(project.getConfigurations().getByName("implementation")); + project.getPlugins().withType(JavaLibraryPlugin.class, (javaLibraryPlugin) -> + configuration.extendsFrom(project.getConfigurations().getByName("api"))); + project.getPlugins().withType(SpringManagementConfigurationPlugin.class, (springManagementConfigurationPlugin) -> + configuration.extendsFrom(project.getConfigurations().getByName("management"))); + + JavaPluginExtension java = project.getExtensions().getByType(JavaPluginExtension.class); + java.getSourceSets().all((sourceSet) -> { + sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(configuration)); + sourceSet.setRuntimeClasspath(sourceSet.getRuntimeClasspath().plus(configuration)); + }); + + return configuration; + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/properties/SpringCopyPropertiesPlugin.java b/buildSrc/src/main/java/org/springframework/gradle/properties/SpringCopyPropertiesPlugin.java new file mode 100644 index 0000000..bb7bf39 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/properties/SpringCopyPropertiesPlugin.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2022 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.properties; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +/** + * @author Steve Riesenberg + */ +public class SpringCopyPropertiesPlugin 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); + } + } +} diff --git a/buildSrc/src/main/java/org/springframework/gradle/sonarqube/SpringSonarQubePlugin.java b/buildSrc/src/main/java/org/springframework/gradle/sonarqube/SpringSonarQubePlugin.java new file mode 100644 index 0000000..f05a5a3 --- /dev/null +++ b/buildSrc/src/main/java/org/springframework/gradle/sonarqube/SpringSonarQubePlugin.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002-2022 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.sonarqube; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.sonarqube.gradle.SonarQubeExtension; +import org.sonarqube.gradle.SonarQubePlugin; + +import org.springframework.gradle.ProjectUtils; + +/** + * @author Steve Riesenberg + */ +public class SpringSonarQubePlugin implements Plugin { + @Override + public void apply(Project project) { + // Apply sonarqube plugin + project.getPluginManager().apply(SonarQubePlugin.class); + + // Configure sonarqube + SonarQubeExtension sonarqube = project.getExtensions().getByType(SonarQubeExtension.class); + sonarqube.properties((properties) -> { + String projectName = ProjectUtils.getProjectName(project); + properties.property("sonar.java.coveragePlugin", "jacoco"); + properties.property("sonar.projectName", projectName); + properties.property("sonar.jacoco.reportPath", project.getBuildDir().getName() + "/jacoco.exec"); + properties.property("sonar.links.homepage", "https://spring.io/" + projectName); + properties.property("sonar.links.ci", "https://jenkins.spring.io/job/" + projectName + "/"); + properties.property("sonar.links.issue", "https://github.com/spring-projects/" + projectName + "/issues"); + properties.property("sonar.links.scm", "https://github.com/spring-projects/" + projectName); + properties.property("sonar.links.scm_dev", "https://github.com/spring-projects/" + projectName + ".git"); + }); + } +} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ArtifactoryConventions.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ArtifactoryConventions.java deleted file mode 100644 index dba1b11..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ArtifactoryConventions.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2022 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.security.kerberos.gradle; - -import java.util.HashMap; -import java.util.Map; - -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.plugins.PluginManager; -import org.gradle.api.publish.tasks.GenerateModuleMetadata; -import org.jfrog.build.extractor.clientConfiguration.ArtifactSpec; -import org.jfrog.build.extractor.clientConfiguration.ArtifactSpecs; -import org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin; -import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention; -import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask; - -/** - * @author Janne Valkealahti - */ -public class ArtifactoryConventions { - - void apply(Project project) { - PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(ArtifactoryPlugin.class); - - project.getTasks().withType(GenerateModuleMetadata.class, metadata -> { - metadata.setEnabled(false); - }); - - project.getPlugins().withType(ArtifactoryPlugin.class, artifactory -> { - if (isRootProject(project)) { - ArtifactoryPluginConvention apConvention = (ArtifactoryPluginConvention) project.getConvention() - .getPlugins().get("artifactory"); - if (project.hasProperty("artifactoryContextUrl")) { - apConvention.setContextUrl(project.property("artifactoryContextUrl")); - } - else { - apConvention.setContextUrl("https://repo.spring.io"); - } - apConvention.publish(publisherConfig -> { - publisherConfig.invokeMethod("setPublishBuildInfo", new Object[] { false }); - publisherConfig.repository(repository -> { - String repoKey = Utils.isSnapshot(project) ? "libs-snapshot-local" - : Utils.isMilestone(project) ? "libs-milestone-local" : "libs-release-local"; - repository.setRepoKey(repoKey); - if (project.hasProperty("artifactoryUsername") && project.hasProperty("artifactoryPassword") ) { - repository.setUsername(project.property("artifactoryUsername")); - repository.setPassword(project.property("artifactoryPassword")); - } - }); - }); - } - Task task = project.getTasks().findByName(ArtifactoryTask.ARTIFACTORY_PUBLISH_TASK_NAME); - if (task != null) { - ArtifactoryTask aTask = (ArtifactoryTask) task; - aTask.setCiServerBuild(); - // bom is not a java project so plugin doesn't - // add defaults for publications. - aTask.publications("mavenJava", "docs"); - - // plugin is difficult to work with, use this hack - // to set props before task does its real work - task.doFirst(t -> { - // this needs mods if we ever have zips other than - // docs zip having asciidoc/javadoc. - ArtifactoryTask at = (ArtifactoryTask) t; - ArtifactSpecs artifactSpecs = at.getArtifactSpecs(); - Map propsMap = new HashMap<>(); - propsMap.put("zip.deployed", "false"); - propsMap.put("zip.type", "docs"); - ArtifactSpec spec = ArtifactSpec.builder() - .artifactNotation("*:*:*:*@zip") - // docs is manually set for zip in root plugin - .configuration("docs") - .properties(propsMap) - .build(); - artifactSpecs.add(spec); - }); - } - }); - } - - private static boolean isRootProject(Project project) { - return project.equals(project.getRootProject()); - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/BomPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/BomPlugin.java deleted file mode 100644 index 708c290..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/BomPlugin.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022 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.security.kerberos.gradle; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.artifacts.dsl.DependencyConstraintHandler; -import org.gradle.api.plugins.JavaPlatformPlugin; -import org.gradle.api.plugins.PluginManager; - -/** - * @author Janne Valkealahti - */ -class BomPlugin implements Plugin { - - @Override - public void apply(Project project) { - PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(SpringMavenPlugin.class); - pluginManager.apply(JavaPlatformPlugin.class); - new ArtifactoryConventions().apply(project); - - // bom should have modules - DependencyConstraintHandler constraints = project.getDependencies().getConstraints(); - project.getRootProject().getAllprojects().forEach(p -> { - p.getPlugins().withType(ModulePlugin.class, m -> { - constraints.add("api", p); - }); - }); - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/DocsPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/DocsPlugin.java deleted file mode 100644 index 151ac22..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/DocsPlugin.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2023 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.security.kerberos.gradle; - -import java.util.HashMap; -import java.util.Map; - -import org.antora.gradle.AntoraPlugin; -import org.gradle.api.Action; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.Task; -import org.gradle.api.plugins.JavaLibraryPlugin; -import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.PluginManager; -import org.gradle.api.publish.tasks.GenerateModuleMetadata; - -import io.spring.gradle.antora.GenerateAntoraYmlPlugin; -import io.spring.gradle.antora.GenerateAntoraYmlTask; - -/** - * @author Janne Valkealahti - */ -class DocsPlugin implements Plugin { - - @Override - public void apply(Project project) { - PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(JavaPlugin.class); - pluginManager.apply(JavaLibraryPlugin.class); - pluginManager.apply(ManagementConfigurationPlugin.class); - pluginManager.apply(AntoraPlugin.class); - pluginManager.apply(GenerateAntoraYmlPlugin.class); - - ExtractVersionConstraints dependencyVersions = project.getTasks().create("dependencyVersions", - ExtractVersionConstraints.class, task -> { - task.enforcedPlatform(":spring-security-kerberos-management"); - }); - - configureYmlPlugins(project, dependencyVersions); - - project.getTasks().withType(GenerateModuleMetadata.class, metadata -> { - metadata.setEnabled(false); - }); - } - - private void configureYmlPlugins(Project project, ExtractVersionConstraints dependencyVersions) { - project.getPlugins().withType(GenerateAntoraYmlPlugin.class, (ymlPlugin) -> { - project.getTasks().withType(GenerateAntoraYmlTask.class, (ymlTask) -> { - ymlTask.dependsOn(dependencyVersions); - configureHtmlOnlyAttributes(project, ymlTask, dependencyVersions); - }); - }); - } - - private void configureHtmlOnlyAttributes(Project project, GenerateAntoraYmlTask ymlTask, - ExtractVersionConstraints dependencyVersions) { - - ymlTask.doFirst(new Action() { - - @Override - public void execute(Task arg0) { - Map versionConstraints = dependencyVersions.getVersionConstraints(); - Map attrs = new HashMap<>(); - attrs.put("version", project.getVersion()); - attrs.put("spring-version", versionConstraints.get("org.springframework:spring-core")); - attrs.put("spring-security-version", versionConstraints.get("org.springframework.security:spring-security-core")); - ymlTask.getAsciidocAttributes().putAll(attrs); - } - }); - } -} \ No newline at end of file diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ExtractVersionConstraints.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ExtractVersionConstraints.java deleted file mode 100644 index 1947d91..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/ExtractVersionConstraints.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.springframework.security.kerberos.gradle; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; - -import org.gradle.api.DefaultTask; -import org.gradle.api.artifacts.ComponentMetadataDetails; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.artifacts.DependencyConstraint; -import org.gradle.api.artifacts.DependencyConstraintMetadata; -import org.gradle.api.artifacts.dsl.DependencyHandler; -import org.gradle.api.tasks.Internal; -import org.gradle.api.tasks.TaskAction; - -/** - * @author Janne Valkealahti - */ -class ExtractVersionConstraints extends DefaultTask { - - private final Configuration configuration; - - private final Map versionConstraints = new TreeMap<>(); - - private final Set constrainedVersions = new TreeSet<>(); - - private final Set versionProperties = new TreeSet<>(); - - private final List projectPaths = new ArrayList<>(); - - public ExtractVersionConstraints() { - DependencyHandler dependencies = getProject().getDependencies(); - this.configuration = getProject().getConfigurations().create(getName()); - dependencies.getComponents().all(this::processMetadataDetails); - } - - public void enforcedPlatform(String projectPath) { - this.configuration.getDependencies().add(getProject().getDependencies().enforcedPlatform( - getProject().getDependencies().project(Collections.singletonMap("path", projectPath)))); - this.projectPaths.add(projectPath); - } - - @Internal - public Map getVersionConstraints() { - return Collections.unmodifiableMap(this.versionConstraints); - } - - @Internal - public Set getConstrainedVersions() { - return this.constrainedVersions; - } - - @Internal - public Set getVersionProperties() { - return this.versionProperties; - } - - @TaskAction - void extractVersionConstraints() { - this.configuration.resolve(); - for (String projectPath : this.projectPaths) { - for (DependencyConstraint constraint : getProject().project(projectPath).getConfigurations() - .getByName("apiElements").getAllDependencyConstraints()) { - this.versionConstraints.put(constraint.getGroup() + ":" + constraint.getName(), - constraint.getVersionConstraint().toString()); - this.constrainedVersions.add(new ConstrainedVersion(constraint.getGroup(), constraint.getName(), - constraint.getVersionConstraint().toString())); - } - } - } - - private void processMetadataDetails(ComponentMetadataDetails details) { - details.allVariants((variantMetadata) -> variantMetadata.withDependencyConstraints((dependencyConstraints) -> { - for (DependencyConstraintMetadata constraint : dependencyConstraints) { - this.versionConstraints.put(constraint.getGroup() + ":" + constraint.getName(), - constraint.getVersionConstraint().toString()); - this.constrainedVersions.add(new ConstrainedVersion(constraint.getGroup(), constraint.getName(), - constraint.getVersionConstraint().toString())); - } - })); - } - - public static final class ConstrainedVersion implements Comparable, Serializable { - - private final String group; - - private final String artifact; - - private final String version; - - private ConstrainedVersion(String group, String artifact, String version) { - this.group = group; - this.artifact = artifact; - this.version = version; - } - - public String getGroup() { - return this.group; - } - - public String getArtifact() { - return this.artifact; - } - - public String getVersion() { - return this.version; - } - - @Override - public int compareTo(ConstrainedVersion other) { - int groupComparison = this.group.compareTo(other.group); - if (groupComparison != 0) { - return groupComparison; - } - return this.artifact.compareTo(other.artifact); - } - - } - - public static final class VersionProperty implements Comparable, Serializable { - - private final String libraryName; - - private final String versionProperty; - - public VersionProperty(String libraryName, String versionProperty) { - this.libraryName = libraryName; - this.versionProperty = versionProperty; - } - - public String getLibraryName() { - return this.libraryName; - } - - public String getVersionProperty() { - return this.versionProperty; - } - - @Override - public int compareTo(VersionProperty other) { - int groupComparison = this.libraryName.compareToIgnoreCase(other.libraryName); - if (groupComparison != 0) { - return groupComparison; - } - return this.versionProperty.compareTo(other.versionProperty); - } - - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/OptionalDependenciesPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/OptionalDependenciesPlugin.java deleted file mode 100644 index 0799d43..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/OptionalDependenciesPlugin.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2022 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.security.kerberos.gradle; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.artifacts.Configuration; -import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginExtension; -import org.gradle.api.tasks.SourceSetContainer; - -public class OptionalDependenciesPlugin implements Plugin { - - public static final String OPTIONAL_CONFIGURATION_NAME = "optional"; - - @Override - public void apply(Project project) { - Configuration optional = project.getConfigurations().create(OPTIONAL_CONFIGURATION_NAME); - optional.setCanBeConsumed(false); - optional.setCanBeResolved(false); - project.getPlugins().withType(JavaPlugin.class, (javaPlugin) -> { - SourceSetContainer sourceSets = project.getExtensions().getByType(JavaPluginExtension.class) - .getSourceSets(); - sourceSets.all((sourceSet) -> { - project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName()) - .extendsFrom(optional); - project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()) - .extendsFrom(optional); - }); - }); - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishArtifactsPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishArtifactsPlugin.java deleted file mode 100644 index 834d044..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/PublishArtifactsPlugin.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2023 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.security.kerberos.gradle; - -import org.gradle.api.Action; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.Task; - -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)) { - // Don't depend on publishDocsPublicationToOssrhRepository as we don't - // want dist zip for api docs on central - Task publishOssrh = project.getTasks().findByName("publishMavenJavaPublicationToOssrhRepository"); - if (publishOssrh != null) { - publishArtifacts.dependsOn(publishOssrh); - } - } - // publishArtifacts.dependsOn("publishMavenJavaPublicationToOssrhRepository"); - // always publish to artifactory as we need apidocs via autorepo - publishArtifacts.dependsOn("artifactoryPublish"); - } - }); - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/RootPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/RootPlugin.java deleted file mode 100644 index 0ea2bd3..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/RootPlugin.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2022-2023 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.security.kerberos.gradle; - -import java.io.File; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.plugins.JavaPluginConvention; -import org.gradle.api.plugins.PluginManager; -import org.gradle.api.publish.PublishingExtension; -import org.gradle.api.publish.maven.MavenPublication; -import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.bundling.Zip; -import org.gradle.api.tasks.javadoc.Javadoc; -import org.gradle.external.javadoc.CoreJavadocOptions; - -/** - * Manages tasks creating zip file for docs and publishing it. - * - * @author Janne Valkealahti - */ -class RootPlugin implements Plugin { - - @Override - public void apply(Project project) { - PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(MavenPublishPlugin.class); - pluginManager.apply(SpringNexusPublishPlugin.class); - pluginManager.apply(PublishLocalPlugin.class); - pluginManager.apply(PublishArtifactsPlugin.class); - Javadoc apiTask = createApiTask(project); - Zip zipTask = createZipTask(project); - zipTask.dependsOn(apiTask); - new ArtifactoryConventions().apply(project); - } - - private Zip createZipTask(Project project) { - Zip zipTask = project.getTasks().create("distZip", Zip.class, zip -> { - zip.setGroup("Distribution"); - zip.from("build/api", copy -> { - copy.into("api"); - }); - }); - - PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - MavenPublication mavenPublication = publishing.getPublications().create("docs", MavenPublication.class); - mavenPublication.artifact(zipTask); - return zipTask; - } - - private Javadoc createApiTask(Project project) { - Javadoc api = project.getTasks().create("api", Javadoc.class, a -> { - a.setGroup("Documentation"); - a.setDescription("Generates aggregated Javadoc API documentation."); - a.setDestinationDir(new File(project.getBuildDir(), "api")); - CoreJavadocOptions options = (CoreJavadocOptions) a.getOptions(); - options.source("17"); - options.encoding("UTF-8"); - options.addStringOption("Xdoclint:none", "-quiet"); - }); - - project.getRootProject().getSubprojects().forEach(p -> { - p.getPlugins().withType(ModulePlugin.class, m -> { - JavaPluginConvention java = p.getConvention().getPlugin(JavaPluginConvention.class); - SourceSet mainSourceSet = java.getSourceSets().getByName("main"); - - api.setSource(api.getSource().plus(mainSourceSet.getAllJava())); - - p.getTasks().withType(Javadoc.class, j -> { - api.setClasspath(api.getClasspath().plus(j.getClasspath())); - }); - }); - }); - return api; - } - -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SamplePlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SamplePlugin.java index a8802ca..02026af 100644 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SamplePlugin.java +++ b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SamplePlugin.java @@ -19,6 +19,7 @@ import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.PluginManager; +import org.springframework.gradle.management.SpringManagementConfigurationPlugin; /** * @author Janne Valkealahti @@ -29,7 +30,7 @@ class SamplePlugin implements Plugin { public void apply(Project project) { PluginManager pluginManager = project.getPluginManager(); pluginManager.apply(JavaPlugin.class); - pluginManager.apply(ManagementConfigurationPlugin.class); + pluginManager.apply(SpringManagementConfigurationPlugin.class); new JavaConventions().apply(project); } } diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringMavenPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringMavenPlugin.java deleted file mode 100644 index 637cd60..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringMavenPlugin.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2022 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.security.kerberos.gradle; - -import java.util.List; -import java.util.ListIterator; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.attributes.Usage; -import org.gradle.api.component.AdhocComponentWithVariants; -import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginExtension; -import org.gradle.api.plugins.PluginManager; -import org.gradle.api.publish.PublishingExtension; -import org.gradle.api.publish.VariantVersionMappingStrategy; -import org.gradle.api.publish.maven.MavenPom; -import org.gradle.api.publish.maven.MavenPomDeveloperSpec; -import org.gradle.api.publish.maven.MavenPomIssueManagement; -import org.gradle.api.publish.maven.MavenPomLicenseSpec; -import org.gradle.api.publish.maven.MavenPomOrganization; -import org.gradle.api.publish.maven.MavenPomScm; -import org.gradle.api.publish.maven.MavenPublication; -import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; - -import groovy.util.Node; - -public class SpringMavenPlugin implements Plugin { - - @Override - public void apply(Project project) { - PluginManager pluginManager = project.getPluginManager(); - pluginManager.apply(MavenPublishPlugin.class); - pluginManager.apply(SpringSigningPlugin.class); - pluginManager.apply(PublishLocalPlugin.class); - pluginManager.apply(PublishAllJavaComponentsPlugin.class); - pluginManager.apply(PublishArtifactsPlugin.class); - - project.getPlugins().withType(MavenPublishPlugin.class).all(mavenPublish -> { - PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); - publishing.getPublications().withType(MavenPublication.class) - .all(mavenPublication -> customizeMavenPublication(mavenPublication, project)); - project.getPlugins().withType(JavaPlugin.class).all(javaPlugin -> { - JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); - extension.withJavadocJar(); - extension.withSourcesJar(); - }); - }); - } - - private void customizeMavenPublication(MavenPublication publication, Project project) { - customizePom(publication.getPom(), project); - project.getPlugins().withType(JavaPlugin.class) - .all((javaPlugin) -> customizeJavaMavenPublication(publication, project)); - } - - private void customizeJavaMavenPublication(MavenPublication publication, Project project) { - publication.versionMapping((strategy) -> strategy.usage(Usage.JAVA_API, (mappingStrategy) -> mappingStrategy - .fromResolutionOf(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME))); - publication.versionMapping( - (strategy) -> strategy.usage(Usage.JAVA_RUNTIME, VariantVersionMappingStrategy::fromResolutionResult)); - } - - private void customizePom(MavenPom pom, Project project) { - pom.getUrl().set("https://github.com/spring-projects/spring-security-kerberos"); - pom.getName().set(project.provider(project::getName)); - pom.getDescription().set(project.provider(project::getDescription)); - pom.organization(this::customizeOrganization); - pom.licenses(this::customizeLicences); - pom.developers(this::customizeDevelopers); - pom.scm(scm -> customizeScm(scm, project)); - pom.issueManagement(this::customizeIssueManagement); - - // TODO: find something better not to add dependencyManagement in pom - // which result spring-security-kerberos-management in it. spring-security-kerberos-bom - // has its own dependencyManagement which we need to keep - if (!project.getName().equals("spring-security-kerberos-bom")) { - pom.withXml(xxx -> { - Node pomNode = xxx.asNode(); - List childs = pomNode.children(); - ListIterator iter = childs.listIterator(); - while (iter.hasNext()) { - Object next = iter.next(); - if (next instanceof Node) { - if (((Node)next).name().toString().equals("{http://maven.apache.org/POM/4.0.0}dependencyManagement")) { - iter.remove(); - } - } - } - }); - } - } - - private void customizeOrganization(MavenPomOrganization organization) { - organization.getName().set("Pivotal Software, Inc."); - organization.getUrl().set("https://spring.io"); - } - - private void customizeLicences(MavenPomLicenseSpec licences) { - 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 customizeScm(MavenPomScm scm, Project project) { - scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-security-kerberos.git"); - scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-security-kerberos.git"); - scm.getUrl().set("https://github.com/spring-projects/spring-security-kerberos"); - } - - private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { - issueManagement.getSystem().set("GitHub"); - issueManagement.getUrl().set("https://github.com/spring-projects/spring-security-kerberos/issues"); - } -} diff --git a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringSigningPlugin.java b/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringSigningPlugin.java deleted file mode 100644 index a60f127..0000000 --- a/buildSrc/src/main/java/org/springframework/security/kerberos/gradle/SpringSigningPlugin.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2023 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.security.kerberos.gradle; - -import java.util.concurrent.Callable; - -import org.gradle.api.Action; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.publish.Publication; -import org.gradle.api.publish.PublishingExtension; -import org.gradle.plugins.signing.SigningExtension; -import org.gradle.plugins.signing.SigningPlugin; - -public class SpringSigningPlugin implements Plugin { - - @Override - public void apply(Project project) { - project.getPluginManager().apply(SigningPlugin.class); - project.getPlugins().withType(SigningPlugin.class).all(new Action() { - @Override - public void execute(SigningPlugin signingPlugin) { - boolean hasSigningKey = project.hasProperty("signing.keyId") || project.hasProperty("signingKey"); - if (hasSigningKey) { - sign(project); - } - } - }); - } - - private void sign(Project project) { - SigningExtension signing = project.getExtensions().findByType(SigningExtension.class); - signing.setRequired(new Callable() { - @Override - public Boolean call() throws Exception { - return project.getGradle().getTaskGraph().hasTask("publishArtifacts"); - } - }); - String signingKeyId = (String) project.findProperty("signingKeyId"); - String signingKey = (String) project.findProperty("signingKey"); - String signingPassword = (String) project.findProperty("signingPassword"); - if (signingKeyId != null) { - signing.useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword); - } else { - signing.useInMemoryPgpKeys(signingKey, signingPassword); - } - project.getPlugins().withType(PublishAllJavaComponentsPlugin.class).all(new Action() { - @Override - public void execute(PublishAllJavaComponentsPlugin publishingPlugin) { - PublishingExtension publishing = project.getExtensions().findByType(PublishingExtension.class); - Publication maven = publishing.getPublications().getByName("mavenJava"); - signing.sign(maven); - } - }); - } -} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.bom.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.bom.properties new file mode 100644 index 0000000..c9aef1a --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.bom.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringMavenBomPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.docs.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.docs.properties new file mode 100644 index 0000000..a2643dd --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.docs.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringDocsPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.root.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.root.properties new file mode 100644 index 0000000..4db8b53 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.root.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringRootProjectPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-module.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-module.properties new file mode 100644 index 0000000..124dd85 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-module.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringModulePlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/org.springframework.gradle.deploy-docs.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/org.springframework.gradle.deploy-docs.properties new file mode 100644 index 0000000..e135a0a --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/org.springframework.gradle.deploy-docs.properties @@ -0,0 +1,2 @@ +# Referencing this plugin by ID allows java code to depend on groovy compilation +implementation-class=org.springframework.gradle.docs.SpringDeployDocsPlugin \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 51995e2..1e6bb86 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,3 +13,4 @@ spring-security-bom='org.springframework.security:spring-security-bom:6.3.0' [plugins] spring-boot='org.springframework.boot:3.3.0' dependency-management='io.spring.dependency-management:1.1.5' +security-release='io.spring.security.release:1.0.3' \ No newline at end of file diff --git a/spring-security-kerberos-bom/spring-security-kerberos-bom.gradle b/spring-security-kerberos-bom/spring-security-kerberos-bom.gradle index ade72de..086fd3c 100644 --- a/spring-security-kerberos-bom/spring-security-kerberos-bom.gradle +++ b/spring-security-kerberos-bom/spring-security-kerberos-bom.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.security.kerberos.bom' + id 'io.spring.convention.bom' } description = 'Spring Security Kerberos BOM' diff --git a/spring-security-kerberos-client/spring-security-kerberos-client.gradle b/spring-security-kerberos-client/spring-security-kerberos-client.gradle index 3707eb6..b1bc519 100644 --- a/spring-security-kerberos-client/spring-security-kerberos-client.gradle +++ b/spring-security-kerberos-client/spring-security-kerberos-client.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.security.kerberos.module' + id 'io.spring.convention.spring-module' } description = 'Spring Security Kerberos Client' diff --git a/spring-security-kerberos-core/spring-security-kerberos-core.gradle b/spring-security-kerberos-core/spring-security-kerberos-core.gradle index 9c9c7ad..416459b 100644 --- a/spring-security-kerberos-core/spring-security-kerberos-core.gradle +++ b/spring-security-kerberos-core/spring-security-kerberos-core.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.security.kerberos.module' + id 'io.spring.convention.spring-module' } description = 'Spring Security Kerberos Core' diff --git a/spring-security-kerberos-docs/spring-security-kerberos-docs.gradle b/spring-security-kerberos-docs/spring-security-kerberos-docs.gradle index ef7e067..68edee8 100644 --- a/spring-security-kerberos-docs/spring-security-kerberos-docs.gradle +++ b/spring-security-kerberos-docs/spring-security-kerberos-docs.gradle @@ -1,5 +1,7 @@ plugins { - id 'org.springframework.security.kerberos.docs' + id 'io.spring.convention.docs' + id 'org.antora' version '1.0.0' + id 'io.spring.antora.generate-antora-yml' version '0.0.1' } description = 'Spring Security Kerberos Documentation' diff --git a/spring-security-kerberos-test/spring-security-kerberos-test.gradle b/spring-security-kerberos-test/spring-security-kerberos-test.gradle index d314eaa..c6e0a9f 100644 --- a/spring-security-kerberos-test/spring-security-kerberos-test.gradle +++ b/spring-security-kerberos-test/spring-security-kerberos-test.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.security.kerberos.module' + id 'io.spring.convention.spring-module' } description = 'Spring Security Kerberos Test' diff --git a/spring-security-kerberos-web/spring-security-kerberos-web.gradle b/spring-security-kerberos-web/spring-security-kerberos-web.gradle index 2e18440..2c2e61c 100644 --- a/spring-security-kerberos-web/spring-security-kerberos-web.gradle +++ b/spring-security-kerberos-web/spring-security-kerberos-web.gradle @@ -1,5 +1,5 @@ plugins { - id 'org.springframework.security.kerberos.module' + id 'io.spring.convention.spring-module' } description = 'Spring Security Kerberos Web'