diff --git a/build.gradle b/build.gradle index 818f6408bb..ca65936d4e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,5 @@ buildscript { dependencies { - classpath 'io.spring.gradle:spring-build-conventions:0.0.37' classpath "io.spring.javaformat:spring-javaformat-gradle-plugin:$springJavaformatVersion" classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion" classpath 'io.spring.nohttp:nohttp-gradle:0.0.5.RELEASE' @@ -75,4 +74,6 @@ if (hasProperty('buildScan')) { nohttp { allowlistFile = project.file("etc/nohttp/allowlist.lines") + source.exclude "buildSrc/build/**" + } diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index d3eeb801df..38061e9378 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,7 +1,14 @@ apply plugin: "java-gradle-plugin" +apply plugin: 'java' +apply plugin: 'groovy' + +sourceCompatibility = 1.8 repositories { + jcenter() + gradlePluginPortal() mavenCentral() + maven { url 'https://repo.spring.io/plugins-release/' } } gradlePlugin { @@ -17,12 +24,34 @@ gradlePlugin { } } -dependencies { - compile 'com.thaiopensource:trang:20091111' - compile 'net.sourceforge.saxon:saxon:9.1.0.8' +configurations { + implementation { + exclude module: 'groovy-all' + } } -task ide(type: Copy) { - from configurations.runtime - into 'ide' +dependencies { + implementation 'com.thaiopensource:trang:20091111' + implementation 'net.sourceforge.saxon:saxon:9.1.0.8' + implementation localGroovy() + + implementation 'com.github.ben-manes:gradle-versions-plugin:0.25.0' + implementation 'gradle.plugin.org.gretty:gretty:3.0.1' + implementation 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.1' + implementation 'io.spring.gradle:dependency-management-plugin:1.0.9.RELEASE' + implementation 'io.spring.gradle:docbook-reference-plugin:0.3.1' + implementation 'io.spring.gradle:propdeps-plugin:0.0.10.RELEASE' + implementation 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.15' + implementation 'io.spring.nohttp:nohttp-gradle:0.0.5.RELEASE' + implementation 'org.asciidoctor:asciidoctor-gradle-jvm:3.1.0' + implementation 'org.asciidoctor:asciidoctor-gradle-jvm-pdf:3.1.0' + implementation 'org.hidetake:gradle-ssh-plugin:2.10.1' + implementation 'org.jfrog.buildinfo:build-info-extractor-gradle:4.9.10' + implementation 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1' + + testImplementation 'junit:junit:4.12' + testImplementation 'org.apache.commons:commons-io:1.3.2' + testImplementation 'org.assertj:assertj-core:3.13.2' + testImplementation 'org.mockito:mockito-core:3.0.0' + testImplementation 'org.spockframework:spock-core:1.3-groovy-2.5' } diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy new file mode 100644 index 0000000000..3c991dbade --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/AbstractSpringJavaPlugin.groovy @@ -0,0 +1,88 @@ +/* + * Copyright 2002-2016 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 io.spring.gradle.propdeps.PropDepsMavenPlugin; +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.MavenPlugin; +import org.gradle.api.plugins.PluginManager; +import org.gradle.internal.impldep.org.apache.maven.Maven; +import org.gradle.plugins.ide.eclipse.EclipseWtpPlugin; +import org.gradle.plugins.ide.idea.IdeaPlugin; +import io.spring.gradle.propdeps.PropDepsEclipsePlugin; +import io.spring.gradle.propdeps.PropDepsIdeaPlugin; +import io.spring.gradle.propdeps.PropDepsPlugin; + +/** + * @author Rob Winch + */ +public abstract class AbstractSpringJavaPlugin implements Plugin { + + @Override + public final void apply(Project project) { + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(JavaPlugin.class); + pluginManager.apply(ManagementConfigurationPlugin.class); + if (project.file("src/main/groovy").exists() + || project.file("src/test/groovy").exists() + || project.file("src/integration-test/groovy").exists()) { + pluginManager.apply(GroovyPlugin.class); + } + pluginManager.apply("io.spring.convention.repository"); + pluginManager.apply(EclipseWtpPlugin); + pluginManager.apply(IdeaPlugin); + pluginManager.apply(PropDepsPlugin); + pluginManager.apply(PropDepsEclipsePlugin); + pluginManager.apply(PropDepsIdeaPlugin); + project.getPlugins().withType(MavenPlugin) { + pluginManager.apply(PropDepsMavenPlugin); + } + pluginManager.apply("io.spring.convention.tests-configuration"); + pluginManager.apply("io.spring.convention.integration-test"); + pluginManager.apply("io.spring.convention.springdependencymangement"); + pluginManager.apply("io.spring.convention.dependency-set"); + pluginManager.apply("io.spring.convention.javadoc-options"); + pluginManager.apply("io.spring.convention.checkstyle"); + pluginManager.apply('com.github.ben-manes.versions'); + + copyPropertyFromRootProjectTo("group", project); + copyPropertyFromRootProjectTo("version", project); + copyPropertyFromRootProjectTo("description", project); + + project.jar { + manifest.attributes["Created-By"] = + "${System.getProperty("java.version")} (${System.getProperty("java.specification.vendor")})" + manifest.attributes["Implementation-Title"] = project.name + manifest.attributes["Implementation-Version"] = project.version + manifest.attributes["Automatic-Module-Name"] = project.name.replace('-', '.') + } + additionalPlugins(project); + } + + private void copyPropertyFromRootProjectTo(String propertyName, Project project) { + Project rootProject = project.getRootProject(); + Object property = rootProject.findProperty(propertyName); + if(property != null) { + project.setProperty(propertyName, property); + } + } + + protected abstract void additionalPlugins(Project project); +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy new file mode 100644 index 0000000000..d21e08bc5f --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/ArtifactoryPlugin.groovy @@ -0,0 +1,58 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import org.gradle.api.Plugin +import org.gradle.api.Project + +class ArtifactoryPlugin implements Plugin { + + @Override + void apply(Project project) { + project.plugins.apply('com.jfrog.artifactory') + String name = Utils.getProjectName(project); + boolean isSnapshot = Utils.isSnapshot(project); + boolean isMilestone = Utils.isMilestone(project); + project.artifactory { + contextUrl = 'https://repo.spring.io' + publish { + repository { + repoKey = isSnapshot ? 'libs-snapshot-local' : isMilestone ? 'libs-milestone-local' : 'libs-release-local' + if(project.hasProperty('artifactoryUsername')) { + username = artifactoryUsername + password = artifactoryPassword + } + } + } + } + + project.artifactoryPublish { + publishIvy false + properties = [ + 'bintray.package': "${project.group}:${name}", + 'bintray.version': "${project.version}" + ] + } + + project.artifactory { + publish { + defaults { + publishConfigs('archives') + } + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy new file mode 100644 index 0000000000..1bfbbecbdf --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/CheckstylePlugin.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2016-2019 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.JavaPlugin + +/** + * Adds and configures Checkstyle plugin. + * + * @author Vedran Pavic + */ +class CheckstylePlugin implements Plugin { + + final CHECKSTYLE_DIR = 'etc/checkstyle' + + @Override + void apply(Project project) { + project.plugins.withType(JavaPlugin) { + def checkstyleDir = project.rootProject.file(CHECKSTYLE_DIR) + if (checkstyleDir.exists() && checkstyleDir.directory) { + project.getPluginManager().apply('checkstyle') + project.dependencies.add('checkstyle', 'io.spring.javaformat:spring-javaformat-checkstyle:0.0.15') + project.dependencies.add('checkstyle', 'io.spring.nohttp:nohttp-checkstyle:0.0.3.RELEASE') + + project.checkstyle { + configDir = checkstyleDir + toolVersion = '8.21' + } + } + } + } + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencyManagementExportTask.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencyManagementExportTask.groovy new file mode 100644 index 0000000000..f70afc1b6b --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencyManagementExportTask.groovy @@ -0,0 +1,61 @@ +package io.spring.gradle.convention + +import org.gradle.api.Project +import org.gradle.api.artifacts.component.ModuleComponentSelector +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; +import java.util.Properties; + +import org.gradle.api.DefaultTask; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.tasks.TaskAction; + +import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension; + +public class DependencyManagementExportTask extends DefaultTask { + @Internal + def projects; + + @Input + String getProjectNames() { + return projects*.name + } + + @TaskAction + public void dependencyManagementExport() throws IOException { + def projects = this.projects ?: project.subprojects + project + def configurations = projects*.configurations*.findAll { ['testRuntime','integrationTestRuntime','grettyRunnerTomcat8','ajtools'].contains(it.name) } + def dependencyResults = configurations*.incoming*.resolutionResult*.allDependencies.flatten() + def moduleVersionVersions = dependencyResults.findAll { r -> r.requested instanceof ModuleComponentSelector }.collect { r-> r.selected.moduleVersion } + + def projectDependencies = projects.collect { p-> "${p.group}:${p.name}:${p.version}".toString() } as Set + def dependencies = moduleVersionVersions.collect { d -> + "${d.group}:${d.name}:${d.version}".toString() + }.sort() as Set + + println '' + println '' + println 'dependencyManagement {' + println '\tdependencies {' + dependencies.findAll { d-> !projectDependencies.contains(d)}.each { + println "\t\tdependency '$it'" + } + println '\t}' + println '}' + println '' + println '' + println 'TIP Use this to find duplicates:\n$ sort gradle/dependency-management.gradle| uniq -c | grep -v \'^\\s*1\'' + println '' + println '' + } + + void setOutputFile(File file) throws IOException { + this.output = new FileOutputStream(file); + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy new file mode 100644 index 0000000000..02b0037e28 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy @@ -0,0 +1,126 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention; + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin + +/** + * Adds sets of dependencies to make it easy to add a grouping of dependencies. The + * dependencies added are: + * + *
    + *
  • sockDependencies
  • + *
  • seleniumDependencies
  • + *
  • gebDependencies
  • + *
  • powerMockDependencies
  • + *
  • slf4jDependencies
  • + *
  • jstlDependencies
  • + *
  • apachedsDependencies
  • + *
+ * + * @author Rob Winch + */ +public class DependencySetPlugin implements Plugin { + @Override + public void apply(Project project) { + + project.ext.spockDependencies = [ + project.dependencies.create("org.spockframework:spock-spring") { + exclude group: 'junit', module: 'junit-dep' + }, + project.dependencies.create("org.spockframework:spock-core") { + exclude group: 'junit', module: 'junit-dep' + } + ] + + project.ext.seleniumDependencies = [ + "org.seleniumhq.selenium:htmlunit-driver", + "org.seleniumhq.selenium:selenium-support" + ] + + project.ext.gebDependencies = project.spockDependencies + + project.seleniumDependencies + [ + "org.gebish:geb-spock", + 'commons-httpclient:commons-httpclient', + "org.codehaus.groovy:groovy", + "org.codehaus.groovy:groovy-all" + ] + + project.ext.powerMockDependencies = [ + "org.powermock:powermock-core", + "org.powermock:powermock-api-support", + "org.powermock:powermock-module-junit4-common", + "org.powermock:powermock-module-junit4", + project.dependencies.create("org.powermock:powermock-api-mockito") { + exclude group: 'org.mockito', module: 'mockito-all' + }, + "org.powermock:powermock-reflect" + ] + + project.ext.powerMock2Dependencies = [ + "org.powermock:powermock-core", + "org.powermock:powermock-api-support", + "org.powermock:powermock-module-junit4-common", + "org.powermock:powermock-module-junit4", + project.dependencies.create("org.powermock:powermock-api-mockito2") { + exclude group: 'org.mockito', module: 'mockito-all' + }, + "org.powermock:powermock-reflect" + ] + + project.ext.slf4jDependencies = [ + "org.slf4j:slf4j-api", + "org.slf4j:jcl-over-slf4j", + "org.slf4j:log4j-over-slf4j", + "ch.qos.logback:logback-classic" + ] + + project.ext.springCoreDependency = [ + project.dependencies.create("org.springframework:spring-core") { + exclude(group: 'commons-logging', module: 'commons-logging') + } + ] + + project.ext.testDependencies = [ + "junit:junit", + "org.mockito:mockito-core", + "org.springframework:spring-test", + "org.assertj:assertj-core" + ] + + project.ext.jstlDependencies = [ + "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api", + "org.apache.taglibs:taglibs-standard-jstlel" + ] + + project.ext.apachedsDependencies = [ + "org.apache.directory.server:apacheds-core", + "org.apache.directory.server:apacheds-core-entry", + "org.apache.directory.server:apacheds-protocol-shared", + "org.apache.directory.server:apacheds-protocol-ldap", + "org.apache.directory.server:apacheds-server-jndi", + 'org.apache.directory.shared:shared-ldap' + ] + + project.plugins.withType(JavaPlugin) { + project.dependencies { + testCompile project.testDependencies + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/DeployDocsPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/DeployDocsPlugin.groovy new file mode 100644 index 0000000000..bf1add5065 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/DeployDocsPlugin.groovy @@ -0,0 +1,82 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.Plugin +import org.gradle.api.Project + +public class DeployDocsPlugin implements Plugin { + + @Override + public 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') + } else { + host = 'docs.af.pivotal.io' + } + 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/groovy/io/spring/gradle/convention/DocsPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/DocsPlugin.groovy new file mode 100644 index 0000000000..0eb1ad42a1 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/DocsPlugin.groovy @@ -0,0 +1,73 @@ +package io.spring.gradle.convention + +import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask +import org.gradle.api.Action +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.DependencySet +import org.gradle.api.plugins.PluginManager +import org.gradle.api.tasks.Sync +import org.gradle.api.tasks.bundling.Zip + +/** + * Aggregates asciidoc, javadoc, and deploying of the docs into a single plugin + */ +public class DocsPlugin implements Plugin { + + @Override + public void apply(Project project) { + + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply("org.asciidoctor.jvm.convert"); + pluginManager.apply("org.asciidoctor.jvm.pdf"); + pluginManager.apply(AsciidoctorConventionPlugin); + pluginManager.apply(DeployDocsPlugin); + pluginManager.apply(JavadocApiPlugin); + + String projectName = Utils.getProjectName(project); + String pdfFilename = projectName + "-reference.pdf"; + + project.tasks.withType(AbstractAsciidoctorTask) { t -> + project.configure(t) { + sources { + include "**/*.adoc" + exclude '_*/**' + } + } + } + + + Task docsZip = project.tasks.create('docsZip', Zip) { + dependsOn 'api', 'asciidoctor' + group = 'Distribution' + baseName = project.rootProject.name + classifier = 'docs' + description = "Builds -${classifier} archive containing all " + + "Docs for deployment at docs.spring.io" + + from(project.tasks.asciidoctor.outputs) { + into 'reference/html5' + include '**' + } + from(project.tasks.asciidoctorPdf.outputs) { + into 'reference/pdf' + include '**' + rename "index.pdf", pdfFilename + } + from(project.tasks.api.outputs) { + into 'api' + } + into 'docs' + duplicatesStrategy 'exclude' + } + + Task docs = project.tasks.create("docs") { + group = 'Documentation' + description 'An aggregator task to generate all the documentation' + dependsOn docsZip + } + project.tasks.assemble.dependsOn docs + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy new file mode 100644 index 0000000000..5fda90d74f --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/IntegrationTestPlugin.groovy @@ -0,0 +1,121 @@ +/* + * Copyright 2016-2018 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 io.spring.gradle.propdeps.PropDepsPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.plugins.GroovyPlugin +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.testing.Test +import org.gradle.plugins.ide.eclipse.EclipsePlugin +import org.gradle.plugins.ide.idea.IdeaPlugin + +/** + * + * Adds support for integration tests to java projects. + * + *
    + *
  • Adds integrationTestCompile and integrationTestRuntime configurations
  • + *
  • A new source test folder of src/integration-test/java has been added
  • + *
  • A task to run integration tests named integrationTest is added
  • + *
  • If Groovy plugin is added a new source test folder src/integration-test/groovy is added
  • + *
+ * + * @author Rob Winch + */ +public class IntegrationTestPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.plugins.withType(JavaPlugin.class) { + applyJava(project) + } + } + + private applyJava(Project project) { + if(!project.file('src/integration-test/').exists()) { + // ensure we don't add if no tests to avoid adding Gretty + return + } + project.configurations { + integrationTestCompile { + extendsFrom testCompile + } + integrationTestRuntime { + extendsFrom integrationTestCompile, testRuntime + } + } + + project.sourceSets { + integrationTest { + java.srcDir project.file('src/integration-test/java') + resources.srcDir project.file('src/integration-test/resources') + compileClasspath = project.sourceSets.main.output + project.sourceSets.test.output + project.configurations.integrationTestCompile + runtimeClasspath = output + compileClasspath + project.configurations.integrationTestRuntime + } + } + + Task integrationTestTask = project.tasks.create("integrationTest", Test) { + group = 'Verification' + description = 'Runs the integration tests.' + dependsOn 'jar' + testClassesDirs = project.sourceSets.integrationTest.output.classesDirs + classpath = project.sourceSets.integrationTest.runtimeClasspath + shouldRunAfter project.tasks.test + } + project.tasks.check.dependsOn integrationTestTask + + project.plugins.withType(IdeaPlugin) { + project.idea { + module { + testSourceDirs += project.file('src/integration-test/java') + scopes.TEST.plus += [ project.configurations.integrationTestCompile ] + } + } + } + + project.plugins.withType(GroovyPlugin) { + project.sourceSets { + integrationTest { + groovy.srcDirs project.file('src/integration-test/groovy') + } + } + project.plugins.withType(IdeaPlugin) { + project.idea { + module { + testSourceDirs += project.file('src/integration-test/groovy') + } + } + } + } + + project.plugins.withType(PropDepsPlugin) { + project.configurations { + integrationTestCompile { + extendsFrom optional, provided + } + } + } + + project.plugins.withType(EclipsePlugin) { + project.eclipse.classpath { + plusConfigurations += [ project.configurations.integrationTestCompile ] + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy new file mode 100644 index 0000000000..900cf9f144 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/JacocoPlugin.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2016-2018 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.JavaPlugin + +/** + * Adds a version of jacoco to use and makes check depend on jacocoTestReport. + * + * @author Rob Winch + */ +class JacocoPlugin implements Plugin { + + @Override + void apply(Project project) { + project.plugins.withType(JavaPlugin) { + project.getPluginManager().apply("jacoco") + project.tasks.check.dependsOn project.tasks.jacocoTestReport + + project.jacoco { + toolVersion = '0.8.2' + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocApiPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocApiPlugin.groovy new file mode 100644 index 0000000000..fc18e4e7af --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocApiPlugin.groovy @@ -0,0 +1,105 @@ +/* + * Copyright 2002-2016 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 java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +import org.gradle.api.Action; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.tasks.SourceSet; +import org.gradle.api.tasks.javadoc.Javadoc; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Rob Winch + */ +public class JavadocApiPlugin implements Plugin { + Logger logger = LoggerFactory.getLogger(getClass()); + Set excludes = Collections.singleton(Pattern.compile("test")); + + @Override + public void apply(Project project) { + logger.info("Applied"); + Project rootProject = project.getRootProject(); + + + //Task docs = project.getTasks().findByPath("docs") ?: project.getTasks().create("docs"); + Javadoc api = project.getTasks().create("api", Javadoc); + + api.setGroup("Documentation"); + api.setDescription("Generates aggregated Javadoc API documentation."); + + Set subprojects = rootProject.getSubprojects(); + for (Project subproject : subprojects) { + addProject(api, subproject); + } + + if (subprojects.isEmpty()) { + addProject(api, project); + } + + api.setMaxMemory("1024m"); + api.setDestinationDir(new File(project.getBuildDir(), "api")); + + project.getPluginManager().apply("io.spring.convention.javadoc-options"); + } + + 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(final Javadoc api, final 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).all(new Action() { + @Override + public void execute(SpringModulePlugin plugin) { + logger.info("Added sources for {}", project); + + JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class); + SourceSet mainSourceSet = java.getSourceSets().getByName("main"); + + api.setSource(api.getSource().plus(mainSourceSet.getAllJava())); + project.getTasks().withType(Javadoc.class).all(new Action() { + @Override + public void execute(Javadoc projectJavadoc) { + api.setClasspath(api.getClasspath().plus(projectJavadoc.getClasspath())); + } + }); + } + }); + } +} + diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy new file mode 100644 index 0000000000..e0fef7ecbe --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/JavadocOptionsPlugin.groovy @@ -0,0 +1,15 @@ +package io.spring.gradle.convention + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.javadoc.Javadoc + +public class JavadocOptionsPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.getTasks().withType(Javadoc).all { t-> + t.options.addStringOption('Xdoclint:none', '-quiet') + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java b/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java new file mode 100644 index 0000000000..8631723e3e --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/ManagementConfigurationPlugin.java @@ -0,0 +1,33 @@ +package io.spring.gradle.convention; + +import org.gradle.api.Action; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; + +/** + * https://github.com/gradle/gradle/issues/7576#issuecomment-434637595 + * @author Rob Winch + */ +public class ManagementConfigurationPlugin implements Plugin { + @Override + public void apply(Project project) { + Configuration management = project.getConfigurations() + .create("management", new Action() { + @Override + public void execute(Configuration configuration) { + configuration.setCanBeResolved(false); + configuration.setCanBeConsumed(false); + configuration.setDescription("Used for setting Gradle constraints that impact all configurations that can be resolved"); + } + }); + project.getConfigurations().all(new Action() { + @Override + public void execute(Configuration configuration) { + if (configuration.isCanBeResolved()) { + configuration.extendsFrom(management); + } + } + }); + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy new file mode 100644 index 0000000000..92ce552feb --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomPlugin.groovy @@ -0,0 +1,54 @@ +package io.spring.gradle.convention + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.plugins.MavenPlugin +import org.gradle.plugins.signing.SigningPlugin +import org.sonarqube.gradle.SonarQubePlugin + +public class MavenBomPlugin implements Plugin { + static String MAVEN_BOM_TASK_NAME = "mavenBom" + + public void apply(Project project) { + project.configurations { + archives + } + project.plugins.apply('io.spring.convention.artifactory') + project.plugins.apply('io.spring.convention.maven') + project.plugins.apply(MavenPlugin) + project.plugins.apply(SigningPlugin) + project.plugins.apply("io.spring.convention.ossrh") + + project.group = project.rootProject.group + project.task(MAVEN_BOM_TASK_NAME, type: MavenBomTask, group: 'Generate', description: 'Configures the pom as a Maven Build of Materials (BOM)') + project.install.dependsOn project.mavenBom + project.tasks.uploadArchives.dependsOn project.mavenBom + project.tasks.artifactoryPublish.dependsOn project.mavenBom + + project.plugins.withType(SonarQubePlugin) { + project.sonarqube.skipProject = true + } + + project.rootProject.allprojects.each { p -> + p.plugins.withType(io.spring.gradle.convention.SpringMavenPlugin) { + if (!project.name.equals(p.name)) { + project.mavenBom.projects.add(p) + } + } + } + + def deployArtifacts = project.task("deployArtifacts") + deployArtifacts.group = 'Deploy tasks' + deployArtifacts.description = "Deploys the artifacts to either Artifactor or Maven Central" + if(Utils.isRelease(project)) { + deployArtifacts.dependsOn project.tasks.uploadArchives + } else { + deployArtifacts.dependsOn project.tasks.artifactoryPublish + } + + project.artifacts { + archives project.mavenBom.bomFile + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomTask.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomTask.groovy new file mode 100644 index 0000000000..beaf4acfbc --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/MavenBomTask.groovy @@ -0,0 +1,87 @@ +package io.spring.gradle.convention + +import org.gradle.api.DefaultTask +import org.gradle.api.Project +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +public class MavenBomTask extends DefaultTask { + + @Internal + Set projects = [] + + @OutputFile + File bomFile + + @Input + Set getProjectNames() { + return projects*.name as Set + } + + public MavenBomTask() { + this.group = "Generate" + this.description = "Generates a Maven Build of Materials (BOM). See https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies" + this.projects = project.subprojects + this.bomFile = project.file("${->project.buildDir}/maven-bom/${->project.name}-${->project.version}.txt") + this.outputs.upToDateWhen { false } + } + + @TaskAction + public void configureBom() { +// project.configurations.archives.artifacts.clear() + bomFile.parentFile.mkdirs() + bomFile.write("Maven Build of Materials (BOM). See https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies") + project.artifacts { + // work around GRADLE-2406 by attaching text artifact + archives(bomFile) + } + project.install { + repositories.mavenInstaller { + pom.whenConfigured { + packaging = "pom" + withXml { + asNode().children().last() + { + delegate.dependencyManagement { + delegate.dependencies { + projects.sort { dep -> "$dep.group:$dep.name" }.each { p -> + + delegate.dependency { + delegate.groupId(p.group) + delegate.artifactId(p.name) + delegate.version(p.version) + } + } + } + } + } + } + } + } + } + project.uploadArchives { + repositories.mavenDeployer { + pom.whenConfigured { + packaging = "pom" + withXml { + asNode().children().last() + { + delegate.dependencyManagement { + delegate.dependencies { + projects.sort { dep -> "$dep.group:$dep.name" }.each { p -> + + delegate.dependency { + delegate.groupId(p.group) + delegate.artifactId(p.name) + delegate.version(p.version) + } + } + } + } + } + } + } + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/MergePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/MergePlugin.groovy new file mode 100644 index 0000000000..cd7e61c573 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/MergePlugin.groovy @@ -0,0 +1,182 @@ +/* + * Copyright 2002-2015 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.* +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.ProjectDependency; +import org.gradle.api.artifacts.maven.Conf2ScopeMapping +import org.gradle.api.plugins.MavenPlugin +import org.gradle.plugins.ide.eclipse.EclipsePlugin +import org.gradle.plugins.ide.idea.IdeaPlugin +import org.gradle.api.invocation.* + +/** + * Gradle plugin that allows projects to merged together. Primarily developed to + * allow Spring to support multiple incompatible versions of third-party + * dependencies (for example Hibernate v3 and v4). + *

+ * The 'merge' extension should be used to define how projects are merged, for example: + *

+ * configure(subprojects) {
+ *     apply plugin: MergePlugin
+ * }
+ *
+ * project("myproject") {
+ * }
+ *
+ * project("myproject-extra") {
+ *     merge.into = project("myproject")
+ * }
+ * 
+ *

+ * This plugin adds two new configurations: + *

    + *
  • merging - Contains the projects being merged into this project
  • + *
  • runtimeMerge - Contains all dependencies that are merge projects. These are used + * to allow an IDE to reference merge projects.
  • + *
      + * + * @author Rob Winch + * @author Phillip Webb + */ +class MergePlugin implements Plugin { + + private static boolean attachedProjectsEvaluated; + + public void apply(Project project) { + project.plugins.apply(MavenPlugin) + project.plugins.apply(EclipsePlugin) + project.plugins.apply(IdeaPlugin) + + MergeModel model = project.extensions.create("merge", MergeModel) + model.project = project + project.configurations.create("merging") + Configuration runtimeMerge = project.configurations.create("runtimeMerge") + + // Ensure the IDE can reference merged projects + project.eclipse.classpath.plusConfigurations += [ runtimeMerge ] + project.idea.module.scopes.PROVIDED.plus += [ runtimeMerge ] + + // Hook to perform the actual merge logic + project.afterEvaluate{ + if (it.merge.into != null) { + setup(it) + } + setupIdeDependencies(it) + } + + // Hook to build runtimeMerge dependencies + if (!attachedProjectsEvaluated) { + project.gradle.projectsEvaluated{ + postProcessProjects(it) + } + attachedProjectsEvaluated = true; + } + } + + private void setup(Project project) { + project.merge.into.dependencies.add("merging", project) + project.dependencies.add("provided", project.merge.into.sourceSets.main.output) + project.dependencies.add("runtimeMerge", project.merge.into) + setupTaskDependencies(project) + setupMaven(project) + } + + private void setupTaskDependencies(Project project) { + // invoking a task will invoke the task with the same name on 'into' project + ["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish", "signArchives", "uploadArchives"].each { + def task = project.tasks.findByPath(it) + if (task) { + task.enabled = false + task.dependsOn(project.merge.into.tasks.findByPath(it)) + } + } + + // update 'into' project artifacts to contain the source artifact contents + project.merge.into.sourcesJar.from(project.sourcesJar.source) + project.merge.into.jar.from(project.sourceSets.main.output) + project.merge.into.javadoc { + source += project.javadoc.source + classpath += project.javadoc.classpath + } + } + + private void setupIdeDependencies(Project project) { + project.configurations.each { c -> + c.dependencies.findAll( { it instanceof org.gradle.api.artifacts.ProjectDependency } ).each { d -> + if(d.dependencyProject.hasProperty("merge")) { + d.dependencyProject.merge.from.each { from -> + project.dependencies.add("runtimeMerge", from) + } + } + } + } + } + + private void setupMaven(Project project) { + project.configurations.each { configuration -> + Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration]) + if (mapping.scope) { + Configuration intoConfiguration = project.merge.into.configurations.create( + project.name + "-" + configuration.name) + configuration.excludeRules.each { + configuration.exclude([ + (ExcludeRule.GROUP_KEY) : it.group, + (ExcludeRule.MODULE_KEY) : it.module]) + } + configuration.dependencies.each { + def intoCompile = project.merge.into.configurations.getByName("compile") + // Protect against changing a compile scope dependency (SPR-10218) + if (!intoCompile.dependencies.contains(it)) { + intoConfiguration.dependencies.add(it) + } + } + def index = project.parent.childProjects.findIndexOf {p -> p.getValue() == project} + project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping( + mapping.priority + 100 + index, intoConfiguration, mapping.scope) + } + } + } + + private postProcessProjects(Gradle gradle) { + gradle.allprojects(new Action() { + public void execute(Project project) { + if(!project.hasProperty("merge")) { + return + } + project.configurations.getByName("runtime")?.allDependencies?.withType(ProjectDependency)?.each{ + Configuration dependsOnMergedFrom = it.dependencyProject.configurations.getByName("merging"); + dependsOnMergedFrom.dependencies.each{ dep -> + project.dependencies.add("runtimeMerge", dep.dependencyProject) + } + } + } + }); + } +} + +class MergeModel { + Project project; + Project into; + List from = []; + + public void setInto(Project into) { + this.into = into; + into.merge.from.add(project); + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/OssrhPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/OssrhPlugin.groovy new file mode 100644 index 0000000000..c414e39ce2 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/OssrhPlugin.groovy @@ -0,0 +1,26 @@ +package io.spring.gradle.convention + +import org.gradle.api.Plugin +import org.gradle.api.Project + +public class OssrhPlugin implements Plugin { + + @Override + public void apply(Project project) { + if(project.hasProperty('ossrhUsername')) { + project.uploadArchives { + repositories { + mavenDeployer { + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: project.ossrhUsername, password: project.ossrhPassword) + } + + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: project.ossrhUsername, password: project.ossrhPassword) + } + } + } + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy new file mode 100644 index 0000000000..4fb23b34af --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/RepositoryConventionPlugin.groovy @@ -0,0 +1,80 @@ +/* + * Copyright 2016-2018 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 + +class RepositoryConventionPlugin implements Plugin { + + @Override + void apply(Project project) { + String[] forceMavenRepositories = ((String) project.findProperty("forceMavenRepositories"))?.split(',') + boolean isImplicitSnapshotRepository = forceMavenRepositories == null && Utils.isSnapshot(project) + boolean isImplicitMilestoneRepository = forceMavenRepositories == null && Utils.isMilestone(project) + + boolean isSnapshot = isImplicitSnapshotRepository || forceMavenRepositories?.contains('snapshot') + boolean isMilestone = isImplicitMilestoneRepository || forceMavenRepositories?.contains('milestone') + + project.repositories { + if (forceMavenRepositories?.contains('local')) { + mavenLocal() + } + mavenCentral() + jcenter() { + content { + includeGroup "org.gretty" + } + } + if (isSnapshot) { + maven { + name = 'artifactory-snapshot' + if (project.hasProperty('artifactoryUsername')) { + credentials { + username project.artifactoryUsername + password project.artifactoryPassword + } + } + url = 'https://repo.spring.io/snapshot/' + } + } + if (isSnapshot || isMilestone) { + maven { + name = 'artifactory-milestone' + if (project.hasProperty('artifactoryUsername')) { + credentials { + username project.artifactoryUsername + password project.artifactoryPassword + } + } + url = 'https://repo.spring.io/milestone/' + } + } + maven { + name = 'artifactory-release' + if (project.hasProperty('artifactoryUsername')) { + credentials { + username project.artifactoryUsername + password project.artifactoryPassword + } + } + url = 'https://repo.spring.io/release/' + } + } + } + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy new file mode 100644 index 0000000000..843d5b57cb --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/RootProjectPlugin.groovy @@ -0,0 +1,78 @@ +/* + * Copyright 2016-2019 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 io.spring.nohttp.gradle.NoHttpPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.BasePlugin +import org.gradle.api.plugins.PluginManager + +class RootProjectPlugin implements Plugin { + + @Override + void apply(Project project) { + PluginManager pluginManager = project.getPluginManager() + pluginManager.apply(BasePlugin) + pluginManager.apply(SchemaPlugin) + pluginManager.apply(NoHttpPlugin) + pluginManager.apply("org.sonarqube") + + project.repositories.mavenCentral() + + project.allprojects { + configurations.all { + resolutionStrategy { + cacheChangingModulesFor 0, "seconds" + cacheDynamicVersionsFor 0, "seconds" + } + } + } + + String projectName = Utils.getProjectName(project) + project.sonarqube { + properties { + property "sonar.java.coveragePlugin", "jacoco" + property "sonar.projectName", projectName + property "sonar.jacoco.reportPath", "${project.buildDir.name}/jacoco.exec" + property "sonar.links.homepage", "https://spring.io/${projectName}" + property "sonar.links.ci", "https://jenkins.spring.io/job/${projectName}/" + property "sonar.links.issue", "https://github.com/spring-projects/${projectName}/issues" + property "sonar.links.scm", "https://github.com/spring-projects/${projectName}" + property "sonar.links.scm_dev", "https://github.com/spring-projects/${projectName}.git" + } + } + + project.tasks.create("dependencyManagementExport", DependencyManagementExportTask) + + def finalizeDeployArtifacts = project.task("finalizeDeployArtifacts") + if (Utils.isRelease(project) && project.hasProperty("ossrhUsername")) { + project.ext.nexusUsername = project.ossrhUsername + project.ext.nexusPassword = project.ossrhPassword + project.getPluginManager().apply("io.codearte.nexus-staging") + finalizeDeployArtifacts.dependsOn project.tasks.closeAndReleaseRepository + project.nexusStaging { + packageGroup = 'org.springframework' + + // try for 5 minutes total + numberOfRetries = 60 // default is 20 + delayBetweenRetriesInMillis = 5000 // default is 2000 + } + } + } + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaDeployPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaDeployPlugin.groovy new file mode 100644 index 0000000000..4b9c038dbb --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaDeployPlugin.groovy @@ -0,0 +1,71 @@ +package io.spring.gradle.convention + +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.Plugin +import org.gradle.api.Project + +public class SchemaDeployPlugin implements Plugin { + + @Override + public 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') + } else { + host = 'docs.af.pivotal.io' + } + 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('deploySchema') { + dependsOn 'schemaZip' + 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}-schema/".replaceAll(' ', '_') + + execute "mkdir -p $tempPath" + + project.tasks.schemaZip.outputs.each { o -> + println "Putting $o.files" + put from: o.files, into: tempPath + } + + execute "unzip $tempPath*.zip -d $tempPath" + + def extractPath = "/var/www/domains/spring.io/docs/htdocs/autorepo/schema/${name}/${version}/" + + execute "rm -rf $extractPath" + execute "mkdir -p $extractPath" + execute "rm -f $tempPath*.zip" + execute "rm -rf $extractPath*" + execute "mv $tempPath/* $extractPath" + execute "chmod -R g+w $extractPath" + } + } + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaPlugin.groovy new file mode 100644 index 0000000000..769ae80d11 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaPlugin.groovy @@ -0,0 +1,15 @@ +package io.spring.gradle.convention + +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.Plugin +import org.gradle.api.Project + +public class SchemaPlugin implements Plugin { + + @Override + public void apply(Project project) { + project.getPluginManager().apply(SchemaZipPlugin) + project.getPluginManager().apply(SchemaDeployPlugin) + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaZipPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaZipPlugin.groovy new file mode 100644 index 0000000000..167545be9f --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SchemaZipPlugin.groovy @@ -0,0 +1,43 @@ +package io.spring.gradle.convention + +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.Plugin +import org.gradle.api.Project + +public class SchemaZipPlugin implements Plugin { + + @Override + public void apply(Project project) { + Zip schemaZip = project.tasks.create('schemaZip', Zip) + schemaZip.group = 'Distribution' + schemaZip.baseName = project.rootProject.name + schemaZip.classifier = 'schema' + schemaZip.description = "Builds -${schemaZip.classifier} archive containing all " + + "XSDs for deployment at static.springframework.org/schema." + + project.rootProject.subprojects.each { module -> + + module.getPlugins().withType(JavaPlugin.class).all { + def Properties schemas = new Properties(); + + module.sourceSets.main.resources.find { + it.path.endsWith('META-INF/spring.schemas') + }?.withInputStream { schemas.load(it) } + + for (def key : schemas.keySet()) { + def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1') + assert shortName != key + File xsdFile = module.sourceSets.main.resources.find { + it.path.endsWith(schemas.get(key)) + } + assert xsdFile != null + schemaZip.into (shortName) { + duplicatesStrategy 'exclude' + from xsdFile.path + } + } + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SortedProperties.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SortedProperties.groovy new file mode 100644 index 0000000000..5b950d83da --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SortedProperties.groovy @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.spring.gradle.convention; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; + +/** + * A Properties which sorts they keys so that they can be written to a File with + * the keys sorted. + * + * @author Rob Winch + * + */ +class SortedProperties extends Properties { + private static final long serialVersionUID = -6199017589626540836L; + + public Enumeration keys() { + Enumeration keysEnum = super.keys(); + List keyList = new ArrayList(); + + while (keysEnum.hasMoreElements()) { + keyList.add(keysEnum.nextElement()); + } + + Collections.sort(keyList, new Comparator() { + @Override + public int compare(Object o1, Object o2) { + return o1.toString().compareTo(o2.toString()); + } + }); + + return Collections.enumeration(keyList); + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy new file mode 100644 index 0000000000..19df0e7d8f --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringDependencyManagementConventionPlugin.groovy @@ -0,0 +1,54 @@ +/* + * Copyright 2016-2019 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 io.spring.gradle.dependencymanagement.DependencyManagementPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project + +/** + * Adds and configures {@link DependencyManagementPlugin}. + *

      + * Additionally, if 'gradle/dependency-management.gradle' file is present it will be + * automatically applied file for configuring the dependencies. + */ +class SpringDependencyManagementConventionPlugin implements Plugin { + + static final String DEPENDENCY_MANAGEMENT_RESOURCE = "gradle/dependency-management.gradle" + + @Override + void apply(Project project) { + project.getPluginManager().apply(ManagementConfigurationPlugin) + project.getPluginManager().apply(DependencyManagementPlugin) + project.dependencyManagement { + resolutionStrategy { + cacheChangingModulesFor 0, "seconds" + } + } + File rootDir = project.rootDir + List dependencyManagementFiles = [project.rootProject.file(DEPENDENCY_MANAGEMENT_RESOURCE)] + for (File dir = project.projectDir; dir != rootDir; dir = dir.parentFile) { + dependencyManagementFiles.add(new File(dir, DEPENDENCY_MANAGEMENT_RESOURCE)) + } + dependencyManagementFiles.each { f -> + if (f.exists()) { + project.apply from: f.absolutePath + } + } + } + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenPlugin.groovy new file mode 100644 index 0000000000..a8d9be2705 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringMavenPlugin.groovy @@ -0,0 +1,221 @@ +package io.spring.gradle.convention + +import io.spring.gradle.dependencymanagement.DependencyManagementPlugin +import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension +import io.spring.gradle.dependencymanagement.dsl.GeneratedPomCustomizationHandler +import org.gradle.api.Action +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.XmlProvider +import org.gradle.api.artifacts.component.ModuleComponentSelector +import org.gradle.api.artifacts.maven.MavenDeployment +import org.gradle.api.artifacts.maven.MavenPom +import org.gradle.api.artifacts.result.ResolvedDependencyResult +import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.plugins.MavenPlugin +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.javadoc.Javadoc +import org.gradle.plugins.signing.SigningPlugin +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +public class SpringMavenPlugin implements Plugin { + private static final String ARCHIVES = "archives"; + Logger logger = LoggerFactory.getLogger(getClass()); + + @Override + public void apply(Project project) { + project.getPluginManager().apply(JavaPlugin.class); + project.getPluginManager().apply(MavenPlugin.class); + project.getPluginManager().apply(SigningPlugin.class); + + Javadoc javadoc = (Javadoc) project.getTasks().findByPath("javadoc"); + Jar javadocJar = project.getTasks().create("javadocJar", Jar.class); + javadocJar.setClassifier("javadoc"); + javadocJar.from(javadoc); + + JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class); + SourceSet mainSourceSet = java.getSourceSets().getByName("main"); + Jar sourcesJar = project.getTasks().create("sourcesJar", Jar.class); + sourcesJar.setClassifier("sources"); + sourcesJar.from(mainSourceSet.getAllSource()); + + project.getArtifacts().add(ARCHIVES, javadocJar); + project.getArtifacts().add(ARCHIVES, sourcesJar); + + project.install { + repositories.mavenInstaller { + configurePom(project, pom) + } + } + project.uploadArchives { + repositories.mavenDeployer { + configurePom(project, pom) + } + } + + project.plugins.withType(DependencyManagementPlugin) { + inlineDependencyManagement(project); + } + + def hasSigningKey = project.hasProperty("signing.keyId") || project.findProperty("signingKey") + if(hasSigningKey && Utils.isRelease(project)) { + sign(project) + } + + project.getPluginManager().apply("io.spring.convention.ossrh"); + } + + private void inlineDependencyManagement(Project project) { + final DependencyManagementExtension dependencyManagement = project.getExtensions().findByType(DependencyManagementExtension.class); + dependencyManagement.generatedPomCustomization( { handler -> handler.setEnabled(false) }); + + project.install { + repositories.mavenInstaller { + configurePomForInlineDependencies(project, pom) + } + } + project.uploadArchives { + repositories.mavenDeployer { + configurePomForInlineDependencies(project, pom) + } + } + } + + private void configurePomForInlineDependencies(Project project, MavenPom pom) { + pom.withXml { XmlProvider xml -> + project.plugins.withType(JavaBasePlugin) { + def dependencies = xml.asNode()?.dependencies?.dependency + def configuredDependencies = project.configurations.findAll{ it.canBeResolved }*.incoming*.resolutionResult*.allDependencies.flatten() + dependencies?.each { Node dep -> + def group = dep.groupId.text() + def name = dep.artifactId.text() + + ResolvedDependencyResult resolved = configuredDependencies.find { r -> + (r.requested instanceof ModuleComponentSelector) && + (r.requested.group == group) && + (r.requested.module == name) + } + + if (!resolved) { + return + } + + def versionNode = dep.version + if (!versionNode) { + dep.appendNode('version') + } + def moduleVersion = resolved.selected.moduleVersion + dep.groupId[0].value = moduleVersion.group + dep.artifactId[0].value = moduleVersion.name + dep.version[0].value = moduleVersion.version + } + } + } + } + + private void sign(Project project) { + project.install { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> project.signing.signPom(deployment) } + } + } + } + + project.uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> project.signing.signPom(deployment) } + } + } + } + + project.signing { + required { project.gradle.taskGraph.hasTask("uploadArchives") } + def signingKeyId = project.findProperty("signingKeyId") + def signingKey = project.findProperty("signingKey") + def signingPassword = project.findProperty("signingPassword") + if (signingKeyId) { + useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) + } else if (signingKey) { + useInMemoryPgpKeys(signingKey, signingPassword) + } + sign project.configurations.archives + } + } + + private static void configurePom(Project project, MavenPom pom) { + pom.whenConfigured { p -> + p.dependencies = p.dependencies.sort { dep -> + "$dep.scope:$dep.optional:$dep.groupId:$dep.artifactId" + } + } + + pom.project { + boolean isWar = project.hasProperty("war"); + String projectVersion = String.valueOf(project.getVersion()); + String projectName = Utils.getProjectName(project); + + if(isWar) { + packaging = "war" + } + name = project.name + description = project.name + url = 'https://spring.io/spring-security' + organization { + name = 'spring.io' + url = 'https://spring.io/' + } + licenses { + license { + name 'The Apache Software License, Version 2.0' + url 'https://www.apache.org/licenses/LICENSE-2.0.txt' + distribution 'repo' + } + } + scm { + url = 'https://github.com/spring-projects/spring-security' + connection = 'scm:git:git://github.com/spring-projects/spring-security' + developerConnection = 'scm:git:git://github.com/spring-projects/spring-security' + } + developers { + developer { + id = 'rwinch' + name = 'Rob Winch' + email = 'rwinch@pivotal.io' + } + developer { + id = 'jgrandja' + name = 'Joe Grandja' + email = 'jgrandja@pivotal.io' + } + } + + if(isWar) { + properties { + 'm2eclipse.wtp.contextRoot' '/' + } + } + if (Utils.isSnapshot(project)) { + repositories { + repository { + id 'spring-snapshot' + url 'https://repo.spring.io/snapshot' + } + } + } + else if (Utils.isMilestone(project)) { + repositories { + repository { + id 'spring-milestone' + url 'https://repo.spring.io/milestone' + } + } + } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy new file mode 100644 index 0000000000..5c509e918c --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringModulePlugin.groovy @@ -0,0 +1,50 @@ +/* + * Copyright 2016-2019 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.Project +import org.gradle.api.plugins.JavaLibraryPlugin; +import org.gradle.api.plugins.MavenPlugin; +import org.gradle.api.plugins.PluginManager; + +/** + * @author Rob Winch + */ +class SpringModulePlugin extends AbstractSpringJavaPlugin { + + @Override + void additionalPlugins(Project project) { + PluginManager pluginManager = project.getPluginManager(); + pluginManager.apply(JavaLibraryPlugin.class) + pluginManager.apply(MavenPlugin.class); + pluginManager.apply("io.spring.convention.maven"); + pluginManager.apply("io.spring.convention.artifactory"); + pluginManager.apply("io.spring.convention.jacoco"); + pluginManager.apply("io.spring.convention.merge"); + + def deployArtifacts = project.task("deployArtifacts") + deployArtifacts.group = 'Deploy tasks' + deployArtifacts.description = "Deploys the artifacts to either Artifactory or Maven Central" + if (Utils.isRelease(project)) { + deployArtifacts.dependsOn project.tasks.uploadArchives + } + else { + deployArtifacts.dependsOn project.tasks.artifactoryPublish + } + } + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringPomPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringPomPlugin.groovy new file mode 100644 index 0000000000..955914c54a --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringPomPlugin.groovy @@ -0,0 +1,24 @@ +/* + * Copyright 2002-2016 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; + +/** + * @author Rob Winch + */ +public class SpringPomPlugin extends SpringModulePlugin { + +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy new file mode 100644 index 0000000000..2d7ee845e5 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleBootPlugin.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2002-2016 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.Project; +import org.gradle.api.plugins.PluginManager; +import org.gradle.api.plugins.WarPlugin +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.testing.Test + +/** + * @author Rob Winch + */ +public class SpringSampleBootPlugin extends SpringSamplePlugin { + + @Override + public void additionalPlugins(Project project) { + super.additionalPlugins(project); + + PluginManager pluginManager = project.getPluginManager(); + + pluginManager.apply("org.springframework.boot"); + + project.repositories { + maven { url 'https://repo.spring.io/snapshot' } + maven { url 'https://repo.spring.io/milestone' } + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy new file mode 100644 index 0000000000..37ae6cfb34 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSamplePlugin.groovy @@ -0,0 +1,33 @@ +/* + * Copyright 2002-2016 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.Project +import org.sonarqube.gradle.SonarQubePlugin; + +/** + * @author Rob Winch + */ +public class SpringSamplePlugin extends AbstractSpringJavaPlugin { + + @Override + public void additionalPlugins(Project project) { + project.plugins.withType(SonarQubePlugin) { + project.sonarqube.skipProject = true + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy new file mode 100644 index 0000000000..59bb1545c9 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringSampleWarPlugin.groovy @@ -0,0 +1,97 @@ +/* + * Copyright 2016-2018 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.Project +import org.gradle.api.Task +import org.gradle.api.plugins.PluginManager +import org.gradle.api.tasks.testing.Test + +/** + * @author Rob Winch + */ +public class SpringSampleWarPlugin extends SpringSamplePlugin { + + @Override + public void additionalPlugins(Project project) { + super.additionalPlugins(project); + + PluginManager pluginManager = project.getPluginManager(); + + pluginManager.apply("war"); + pluginManager.apply("org.gretty"); + + project.gretty { + servletContainer = 'tomcat85' + contextPath = '/' + fileLogEnabled = false + } + + Task prepareAppServerForIntegrationTests = project.tasks.create('prepareAppServerForIntegrationTests') { + group = 'Verification' + description = 'Prepares the app server for integration tests' + doFirst { + project.gretty { + httpPort = getRandomFreePort() + httpsPort = getRandomPort() + } + } + } + project.tasks.withType(org.akhikhl.gretty.AppBeforeIntegrationTestTask).all { task -> + task.dependsOn prepareAppServerForIntegrationTests + } + + project.tasks.withType(Test).all { task -> + if("integrationTest".equals(task.name)) { + applyForIntegrationTest(project, task) + } + } + } + + def applyForIntegrationTest(Project project, Task integrationTest) { + project.gretty.integrationTestTask = integrationTest.name + + integrationTest.doFirst { + def gretty = project.gretty + String host = project.gretty.host ?: 'localhost' + boolean isHttps = gretty.httpsEnabled + Integer httpPort = integrationTest.systemProperties['gretty.httpPort'] + Integer httpsPort = integrationTest.systemProperties['gretty.httpsPort'] + int port = isHttps ? httpsPort : httpPort + String contextPath = project.gretty.contextPath + String httpBaseUrl = "http://${host}:${httpPort}${contextPath}" + String httpsBaseUrl = "https://${host}:${httpsPort}${contextPath}" + String baseUrl = isHttps ? httpsBaseUrl : httpBaseUrl + integrationTest.systemProperty 'app.port', port + integrationTest.systemProperty 'app.httpPort', httpPort + integrationTest.systemProperty 'app.httpsPort', httpsPort + integrationTest.systemProperty 'app.baseURI', baseUrl + integrationTest.systemProperty 'app.httpBaseURI', httpBaseUrl + integrationTest.systemProperty 'app.httpsBaseURI', httpsBaseUrl + + integrationTest.systemProperty 'geb.build.baseUrl', baseUrl + integrationTest.systemProperty 'geb.build.reportsDir', 'build/geb-reports' + } + } + + def getRandomPort() { + ServerSocket ss = new ServerSocket(0) + int port = ss.localPort + ss.close() + return port + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy new file mode 100644 index 0000000000..55807dc0f1 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/SpringTestPlugin.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2016 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.Project; + +/** + * @author Rob Winch + */ +public class SpringTestPlugin extends AbstractSpringJavaPlugin { + + @Override + public void additionalPlugins(Project project) { + project.sonarqube.skipProject = true + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy new file mode 100644 index 0000000000..6ad45d0a1e --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/TestsConfigurationPlugin.groovy @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention; + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin +import org.gradle.jvm.tasks.Jar + +/** + * Adds the ability to depends on the test jar within other projects using: + * + * + * testCompile project(path: ':foo', configuration: 'tests') + * + * + * @author Rob Winch + */ +public class TestsConfigurationPlugin implements Plugin { + @Override + public void apply(Project project) { + project.plugins.withType(JavaPlugin) { + applyJavaProject(project) + } + } + + private void applyJavaProject(Project project) { + project.configurations { + tests.extendsFrom testRuntime + } + + project.tasks.create('testJar', Jar) { + classifier = 'test' + from project.sourceSets.test.output + } + + project.artifacts { + tests project.testJar + } + } +} diff --git a/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy b/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy new file mode 100644 index 0000000000..8f5a6a9064 --- /dev/null +++ b/buildSrc/src/main/groovy/io/spring/gradle/convention/Utils.groovy @@ -0,0 +1,34 @@ +package io.spring.gradle.convention; + +import org.gradle.api.Project; + +public class Utils { + + static String getProjectName(Project project) { + String projectName = project.getRootProject().getName(); + if(projectName.endsWith("-build")) { + projectName = projectName.substring(0, projectName.length() - "-build".length()); + } + return projectName; + } + + static boolean isSnapshot(Project project) { + String projectVersion = projectVersion(project) + return projectVersion.matches('^.*([.-]BUILD)?-SNAPSHOT$') + } + + static boolean isMilestone(Project project) { + String projectVersion = projectVersion(project) + return projectVersion.matches('^.*[.-]M\\d+$') || projectVersion.matches('^.*[.-]RC\\d+$') + } + + static boolean isRelease(Project project) { + return !(isSnapshot(project) || isMilestone(project)) + } + + private static String projectVersion(Project project) { + return String.valueOf(project.getVersion()); + } + + private Utils() {} +} diff --git a/buildSrc/src/main/java/io/spring/gradle/convention/AsciidoctorConventionPlugin.java b/buildSrc/src/main/java/io/spring/gradle/convention/AsciidoctorConventionPlugin.java new file mode 100644 index 0000000000..7a71329105 --- /dev/null +++ b/buildSrc/src/main/java/io/spring/gradle/convention/AsciidoctorConventionPlugin.java @@ -0,0 +1,208 @@ +/* + * 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 io.spring.gradle.convention; + +import org.asciidoctor.gradle.base.AsciidoctorAttributeProvider; +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.gradle.api.Action; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; +import org.gradle.api.artifacts.DependencySet; +import org.gradle.api.artifacts.dsl.RepositoryHandler; +import org.gradle.api.file.CopySpec; +import org.gradle.api.file.FileTree; +import org.gradle.api.tasks.Sync; + +import java.io.File; +import java.net.URI; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.function.Consumer; + +/** + * 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 ued 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 + */ +public class AsciidoctorConventionPlugin implements Plugin { + + public void apply(Project project) { + project.getPlugins().withType(AsciidoctorJPlugin.class, (asciidoctorPlugin) -> { + createDefaultAsciidoctorRepository(project); + makeAllWarningsFatal(project); + Sync unzipResources = createUnzipDocumentationResourcesTask(project); + project.getTasks().withType(AbstractAsciidoctorTask.class, (asciidoctorTask) -> { + asciidoctorTask.dependsOn(unzipResources); + configureExtensions(project, asciidoctorTask); + configureCommonAttributes(project, asciidoctorTask); + configureOptions(asciidoctorTask); + asciidoctorTask.baseDirFollowsSourceDir(); + asciidoctorTask.useIntermediateWorkDir(); + asciidoctorTask.resources(new Action() { + @Override + public void execute(CopySpec resourcesSpec) { + resourcesSpec.from(unzipResources); + resourcesSpec.from(asciidoctorTask.getSourceDir(), new Action() { + @Override + public void execute(CopySpec resourcesSrcDirSpec) { + // https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/523 + // For now copy the entire sourceDir over so that include files are + // available in the intermediateWorkDir + // resourcesSrcDirSpec.include("images/**"); + } + }); + } + }); + if (asciidoctorTask instanceof AsciidoctorTask) { + configureHtmlOnlyAttributes(project, asciidoctorTask); + } + }); + }); + } + + private void createDefaultAsciidoctorRepository(Project project) { + project.getGradle().afterProject(new Action() { + @Override + public void execute(Project project) { + RepositoryHandler repositories = project.getRepositories(); + if (repositories.isEmpty()) { + repositories.mavenCentral(); + repositories.maven(repo -> { + repo.setUrl(URI.create("https://repo.spring.io/release")); + }); + } + } + }); + } + + private void makeAllWarningsFatal(Project project) { + project.getExtensions().getByType(AsciidoctorJExtension.class).fatalWarnings(".*"); + } + + private void configureExtensions(Project project, AbstractAsciidoctorTask asciidoctorTask) { + Configuration extensionsConfiguration = project.getConfigurations().maybeCreate("asciidoctorExtensions"); + extensionsConfiguration.defaultDependencies(new Action() { + @Override + public void execute(DependencySet dependencies) { + dependencies.add(project.getDependencies().create("io.spring.asciidoctor:spring-asciidoctor-extensions-block-switch:0.4.2.RELEASE")); + } + }); + asciidoctorTask.configurations(extensionsConfiguration); + } + + private Sync createUnzipDocumentationResourcesTask(Project project) { + Configuration documentationResources = project.getConfigurations().maybeCreate("documentationResources"); + documentationResources.getDependencies() + .add(project.getDependencies().create("io.spring.docresources:spring-doc-resources:0.2.1.RELEASE")); + Sync unzipResources = project.getTasks().create("unzipDocumentationResources", + Sync.class, new Action() { + @Override + public void execute(Sync sync) { + sync.dependsOn(documentationResources); + sync.from(new Callable>() { + @Override + public List call() throws Exception { + List result = new ArrayList<>(); + documentationResources.getAsFileTree().forEach(new Consumer() { + @Override + public void accept(File file) { + result.add(project.zipTree(file)); + } + }); + return result; + } + }); + File destination = new File(project.getBuildDir(), "docs/resources"); + sync.into(project.relativePath(destination)); + } + }); + return unzipResources; + } + + private void configureOptions(AbstractAsciidoctorTask asciidoctorTask) { + asciidoctorTask.options(Collections.singletonMap("doctype", "book")); + } + + private void configureHtmlOnlyAttributes(Project project, AbstractAsciidoctorTask asciidoctorTask) { + Map attributes = new HashMap<>(); + attributes.put("source-highlighter", "highlight.js"); + attributes.put("highlightjsdir", "js/highlight"); + attributes.put("highlightjs-theme", "github"); + attributes.put("linkcss", true); + attributes.put("icons", "font"); + attributes.put("stylesheet", "css/spring.css"); + asciidoctorTask.getAttributeProviders().add(new AsciidoctorAttributeProvider() { + @Override + public Map getAttributes() { + Object version = project.getVersion(); + Map attrs = new HashMap<>(); + if (version != null && version.toString() != Project.DEFAULT_VERSION) { + attrs.put("revnumber", version); + } + return attrs; + } + }); + asciidoctorTask.attributes(attributes); + } + + private void configureCommonAttributes(Project project, AbstractAsciidoctorTask asciidoctorTask) { + Map attributes = new HashMap<>(); + attributes.put("attribute-missing", "warn"); + attributes.put("icons", "font"); + attributes.put("idprefix", ""); + attributes.put("idseparator", "-"); + attributes.put("docinfo", "shared"); + attributes.put("sectanchors", ""); + attributes.put("sectnums", ""); + attributes.put("today-year", LocalDate.now().getYear()); + asciidoctorTask.attributes(attributes); + } +} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.artifactory.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.artifactory.properties new file mode 100644 index 0000000000..573d128134 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.artifactory.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.ArtifactoryPlugin \ No newline at end of file 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 0000000000..dec2e7a807 --- /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.MavenBomPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.checkstyle.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.checkstyle.properties new file mode 100644 index 0000000000..9259a914db --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.checkstyle.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.CheckstylePlugin diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.dependency-set.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.dependency-set.properties new file mode 100644 index 0000000000..497ecd5908 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.dependency-set.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.DependencySetPlugin \ 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 0000000000..fcad41ab0b --- /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.DocsPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.integration-test.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.integration-test.properties new file mode 100644 index 0000000000..0da39b3309 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.integration-test.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.IntegrationTestPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.jacoco.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.jacoco.properties new file mode 100644 index 0000000000..70cfb7d0d8 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.jacoco.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.JacocoPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-api.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-api.properties new file mode 100644 index 0000000000..bfb92306a2 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-api.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.JavadocApiPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-options.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-options.properties new file mode 100644 index 0000000000..77e7832e44 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.javadoc-options.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.JavadocOptionsPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.maven.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.maven.properties new file mode 100644 index 0000000000..a75655edad --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.maven.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringMavenPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.merge.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.merge.properties new file mode 100644 index 0000000000..47f39ec24e --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.merge.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.MergePlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.ossrh.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.ossrh.properties new file mode 100644 index 0000000000..567272412a --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.ossrh.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.OssrhPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.repository.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.repository.properties new file mode 100644 index 0000000000..b427d5521d --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.repository.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.RepositoryConventionPlugin \ 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 0000000000..9844db6244 --- /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.RootProjectPlugin \ 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 0000000000..124dd85f94 --- /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/io.spring.convention.spring-pom.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-pom.properties new file mode 100644 index 0000000000..e59252be87 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-pom.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringPomPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-boot.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-boot.properties new file mode 100644 index 0000000000..6daff6d336 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-boot.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringSampleBootPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-war.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-war.properties new file mode 100644 index 0000000000..54daa2ada2 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample-war.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringSampleWarPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample.properties new file mode 100644 index 0000000000..24714047ca --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-sample.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringSamplePlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-test.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-test.properties new file mode 100644 index 0000000000..4881e2d070 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.spring-test.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringTestPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.springdependencymangement.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.springdependencymangement.properties new file mode 100644 index 0000000000..406e5690c4 --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.springdependencymangement.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.SpringDependencyManagementConventionPlugin \ No newline at end of file diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.tests-configuration.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.tests-configuration.properties new file mode 100644 index 0000000000..afd0a712ad --- /dev/null +++ b/buildSrc/src/main/resources/META-INF/gradle-plugins/io.spring.convention.tests-configuration.properties @@ -0,0 +1 @@ +implementation-class=io.spring.gradle.convention.TestsConfigurationPlugin \ No newline at end of file diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/DependencySetPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/DependencySetPluginITest.groovy new file mode 100644 index 0000000000..43efa0a2d0 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/DependencySetPluginITest.groovy @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class DependencySetPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "dependencies"() { + when: + BuildResult result = testKit.withProjectResource("samples/dependencyset") + .withArguments('dependencies') + .build(); + then: + result.task(":dependencies").outcome == SUCCESS + !result.output.contains("FAILED") + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/DocsPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/DocsPluginITest.groovy new file mode 100644 index 0000000000..99ae2d6473 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/DocsPluginITest.groovy @@ -0,0 +1,95 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import java.util.zip.ZipFile + +import static org.gradle.testkit.runner.TaskOutcome.FAILED +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class DocsPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "build triggers docs"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/simple/") + .withArguments('build') + .build(); + then: + result.task(":build").outcome == SUCCESS + and: + result.task(":docs").outcome == SUCCESS + and: + result.task(":docsZip").outcome == SUCCESS + and: + def zip = new File(testKit.getRootDir(), 'build/distributions/simple-1.0.0.BUILD-SNAPSHOT-docs.zip') + def names = new ZipFile(zip).entries()*.name + names.contains("docs/reference/html5/index.html") + names.contains("docs/reference/pdf/simple-reference.pdf") + } + + def "asciidoc copies images"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/simple/") + .withArguments('asciidoctor') + .build(); + then: + result.task(":asciidoctor").outcome == SUCCESS + new File(testKit.getRootDir(), "build/docs/asciidoc/images").exists() + } + + def "asciidoc docinfo from resources used"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/simple/") + .withArguments('asciidoctor') + .build(); + then: + result.task(":asciidoctor").outcome == SUCCESS + new File(testKit.getRootDir(), "build/docs/asciidoc/index.html").getText().contains("""""") + } + + def "missing attribute fails"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/missing-attribute/") + .withArguments(':asciidoctor') + .buildAndFail(); + then: + result.task(":asciidoctor").outcome == FAILED + } + + def "missing include"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/missing-include/") + .withArguments(':asciidoctor') + .buildAndFail(); + then: + result.task(":asciidoctor").outcome == FAILED + } + + def "missing cross reference"() { + when: + BuildResult result = testKit.withProjectResource("samples/docs/missing-cross-reference/") + .withArguments(':asciidoctor') + .buildAndFail(); + then: + result.task(":asciidoctor").outcome == FAILED + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/IntegrationTestPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/IntegrationTestPluginITest.groovy new file mode 100644 index 0000000000..f31ed287f2 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/IntegrationTestPluginITest.groovy @@ -0,0 +1,63 @@ +/* + * Copyright 2016-2018 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 io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class IntegrationTestPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "check with java plugin"() { + when: + BuildResult result = testKit.withProjectResource("samples/integrationtest/withjava/") + .withArguments('check') + .build(); + then: + result.task(":check").outcome == SUCCESS + and: + new File(testKit.getRootDir(), 'build/test-results/integrationTest/').exists() + new File(testKit.getRootDir(), 'build/reports/tests/integrationTest/').exists() + } + + def "check with propdeps"() { + when: + BuildResult result = testKit.withProjectResource("samples/integrationtest/withpropdeps/") + .withArguments('check') + .build(); + then: + result.task(":check").outcome == SUCCESS + and: + new File(testKit.getRootDir(), 'build/test-results/integrationTest/').exists() + new File(testKit.getRootDir(), 'build/reports/tests/integrationTest/').exists() + } + + def "check with groovy plugin"() { + when: + BuildResult result = testKit.withProjectResource("samples/integrationtest/withgroovy/") + .withArguments('check') + .build(); + then: + result.task(":check").outcome == SUCCESS + and: + new File(testKit.getRootDir(), 'build/test-results/integrationTest/').exists() + new File(testKit.getRootDir(), 'build/reports/tests/integrationTest/').exists() + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/JacocoPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/JacocoPluginITest.groovy new file mode 100644 index 0000000000..cda62362e6 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/JacocoPluginITest.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class JacocoPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "check with java plugin"() { + when: + BuildResult result = testKit.withProjectResource("samples/jacoco/java/") + .withArguments('check') + .build(); + then: + result.task(":check").outcome == SUCCESS + and: + new File(testKit.getRootDir(), 'build/jacoco').exists() + new File(testKit.getRootDir(), 'build/reports/jacoco/test/html/').exists() + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/JavadocApiPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/JavadocApiPluginITest.groovy new file mode 100644 index 0000000000..a728131552 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/JavadocApiPluginITest.groovy @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.*; + +import io.spring.gradle.testkit.junit.rules.TestKit +import org.apache.commons.io.FileUtils + +class JavadocApiPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "multimodule api"() { + when: + BuildResult result = testKit.withProjectResource("samples/javadocapi/multimodule/") + .withArguments('api') + .build(); + then: + result.task(":api").outcome == SUCCESS + and: + File allClasses = new File(testKit.getRootDir(), 'build/api/allclasses-noframe.html'); + File index = new File(testKit.getRootDir(), 'build/api/allclasses.html'); + new File(testKit.getRootDir(), "build/api/").listFiles().each { println it } + File listing = allClasses.exists() ? allClasses : index + listing.text.contains('sample/Api.html') + listing.text.contains('sample/Impl.html') + !listing.text.contains('sample/Sample.html') + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/ShowcaseITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/ShowcaseITest.groovy new file mode 100644 index 0000000000..6bbe925966 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/ShowcaseITest.groovy @@ -0,0 +1,130 @@ +/* + * Copyright 2016-2019 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 io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Rule +import spock.lang.Specification + +class ShowcaseITest extends Specification { + + @Rule final TestKit testKit = new TestKit() + + def "build"() { + when: + BuildResult result = testKit.withProjectResource("samples/showcase/") + .withArguments('build','--stacktrace') + .forwardOutput() + .build(); + then: 'entire build passes' + result.output.contains("BUILD SUCCESSFUL") + + and: 'javadoc api works' + + and: 'integration tests run' + new File(testKit.getRootDir(), 'samples/sgbcs-sample-war/build/test-results/integrationTest/').exists() + new File(testKit.getRootDir(), 'samples/sgbcs-sample-war/build/reports/tests/integrationTest/').exists() + } + + def "install"() { + when: + BuildResult result = testKit.withProjectResource("samples/showcase/") + .withArguments('install','--stacktrace') + .build(); + then: + result.output.contains("SUCCESS") + + and: 'pom exists' + File pom = new File(testKit.getRootDir(), 'sgbcs-core/build/poms/pom-default.xml') + pom.exists() + String pomText = pom.getText() + + and: 'pom does not contain ' + !pomText.contains('') + + and: 'creates optional dependencies correctly' + pomText.replaceAll('\\s','').contains(""" + org.springframework + spring-test + test + 4.3.6.RELEASE + """.replaceAll('\\s','')) + + and: 'adds author' + pomText.replaceAll('\\s','').contains(""" + + rwinch + Rob Winch + rwinch@pivotal.io + + + jgrandja + Joe Grandja + jgrandja@pivotal.io + + """.replaceAll('\\s','')) + + and: 'adds repositories' + pomText.replaceAll('\\s','').contains(""" + scm:git:git://github.com/spring-projects/spring-security + scm:git:git://github.com/spring-projects/spring-security + https://github.com/spring-projects/spring-security + """.replaceAll('\\s','')) + + and: 'adds description & url' + pomText.contains('sgbcs-core') + pomText.contains('https://spring.io/spring-security') + + and: 'adds organization' + pomText.replaceAll('\\s','').contains(''' + spring.io + https://spring.io/ + '''.replaceAll('\\s','')) + + and: 'adds licenses' + pomText.replaceAll('\\s','').contains(''' + + The Apache Software License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + '''.replaceAll('\\s','')) + + and: 'adds scm' + pomText.replaceAll('\\s','').replaceAll('\\s','').contains(""" + scm:git:git://github.com/spring-projects/spring-security + scm:git:git://github.com/spring-projects/spring-security + https://github.com/spring-projects/spring-security + """.replaceAll('\\s','')) + + and: 'bom created' + File bom = new File(testKit.getRootDir(), 'bom/build/poms/pom-default.xml') + bom.exists() + String bomText = bom.getText() + bomText.contains("""sgbcs-core""") + + when: 'mavenBom ran again' + result = testKit.withProjectResource("samples/showcase/") + .withArguments('mavenBom','--stacktrace') + .build(); + then: 'mavenBom is not up to date since install is never up to date' + result.task(':bom:mavenBom').getOutcome() == TaskOutcome.SUCCESS + } + +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/SpringMavenPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/SpringMavenPluginITest.groovy new file mode 100644 index 0000000000..1415d8f5b2 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/SpringMavenPluginITest.groovy @@ -0,0 +1,88 @@ +/* + * Copyright 2016-2019 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 io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class SpringMavenPluginITest extends Specification { + + @Rule final TestKit testKit = new TestKit() + + def "install"() { + when: + BuildResult result = testKit.withProjectResource("samples/maven/install") + .withArguments('install') + .build(); + then: 'pom contains optional' + result.output.contains("SUCCESS") + File pom = new File(testKit.getRootDir(), 'build/poms/pom-default.xml') + pom.exists() + String pomText = pom.getText() + pomText.replaceAll('\\s','').contains(""" + aopalliance + aopalliance + 1.0 + compile + true + """.replaceAll('\\s','')) + } + + def "signArchives when in memory"() { + when: + BuildResult result = testKit.withProjectResource("samples/maven/signing") + .withArguments('signArchives') + .withEnvironment(["ORG_GRADLE_PROJECT_signingKey" : signingKey, + "ORG_GRADLE_PROJECT_signingPassword" : "password"]) + .forwardOutput() + .build(); + then: + result.output.contains("SUCCESS") + File jar = new File(testKit.getRootDir(), 'build/libs/signing-1.0.0.RELEASE.jar') + jar.exists() + File signature = new File("${jar.absolutePath}.asc") + signature.exists() + } + + def "upload"() { + when: + BuildResult result = testKit.withProjectResource("samples/maven/upload") + .withArguments('uploadArchives') + .forwardOutput() + .build(); + then: 'pom contains optional' + result.output.contains("SUCCESS") + File pom = new File(testKit.getRootDir(), 'build/poms/pom-default.xml') + pom.exists() + String pomText = pom.getText() + pomText.replaceAll('\\s','').contains(""" + aopalliance + aopalliance + 1.0 + compile + true + """.replaceAll('\\s','')) + } + + def getSigningKey() { + getClass().getResource("/test-private.pgp").text + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/convention/TestsConfigurationPluginITest.groovy b/buildSrc/src/test/groovy/io/spring/gradle/convention/TestsConfigurationPluginITest.groovy new file mode 100644 index 0000000000..045e595841 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/convention/TestsConfigurationPluginITest.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.convention + +import io.spring.gradle.testkit.junit.rules.TestKit +import org.gradle.testkit.runner.BuildResult +import org.junit.Rule +import spock.lang.Specification + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class TestsConfigurationPluginITest extends Specification { + @Rule final TestKit testKit = new TestKit() + + def "can find dependency"() { + when: + BuildResult result = testKit.withProjectResource("samples/testsconfiguration") + .withArguments('check') + .build(); + then: + result.task(":web:check").outcome == SUCCESS + } +} diff --git a/buildSrc/src/test/groovy/io/spring/gradle/testkit/junit/rules/TestKit.java b/buildSrc/src/test/groovy/io/spring/gradle/testkit/junit/rules/TestKit.java new file mode 100644 index 0000000000..f9b5385540 --- /dev/null +++ b/buildSrc/src/test/groovy/io/spring/gradle/testkit/junit/rules/TestKit.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package io.spring.gradle.testkit.junit.rules; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Paths; +import java.util.Enumeration; + +import org.apache.commons.io.FileUtils; +import org.gradle.testkit.runner.GradleRunner; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +public class TestKit implements TestRule { + final TemporaryFolder testProjectDir = new TemporaryFolder(); + File buildDir; + + @Override + public Statement apply(Statement base, Description description) { + Statement wrapped = new Statement() { + + @Override + public void evaluate() throws Throwable { + try { + buildDir = testProjectDir.newFolder(); + } catch(IOException e) { + throw new RuntimeException(e); + } + base.evaluate(); + } + }; + return testProjectDir.apply(wrapped, description); + } + + public File getRootDir() { + return buildDir; + } + + public GradleRunner withProjectDir(File projectDir) throws IOException { + FileUtils.copyDirectory(projectDir, buildDir); + return GradleRunner.create() + .withProjectDir(buildDir) + .withPluginClasspath(); + } + + public GradleRunner withProjectResource(String projectResourceName) throws IOException, URISyntaxException { + ClassLoader classLoader = getClass().getClassLoader(); + Enumeration resources = classLoader.getResources(projectResourceName); + if(!resources.hasMoreElements()) { + throw new IOException("Cannot find resource " + projectResourceName + " with " + classLoader); + } + URL resourceUrl = resources.nextElement(); + File projectDir = Paths.get(resourceUrl.toURI()).toFile(); + return withProjectDir(projectDir); + } +} diff --git a/buildSrc/src/test/java/io/spring/gradle/convention/IntegrationPluginTest.java b/buildSrc/src/test/java/io/spring/gradle/convention/IntegrationPluginTest.java new file mode 100644 index 0000000000..e8a613c65c --- /dev/null +++ b/buildSrc/src/test/java/io/spring/gradle/convention/IntegrationPluginTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2016 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.apache.commons.io.FileUtils; +import org.gradle.api.Project; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.javadoc.Javadoc; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.After; +import org.junit.Test; + +import java.io.File; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Rob Winch + */ +public class IntegrationPluginTest { + Project rootProject; + + @After + public void cleanup() throws Exception { + if (rootProject != null) { + FileUtils.deleteDirectory(rootProject.getProjectDir()); + } + } + + @Test + public void applyWhenNoSourceThenIntegrationTestTaskNull() { + rootProject = ProjectBuilder.builder().build(); + rootProject.getPlugins().apply(JavaPlugin.class); + rootProject.getPlugins().apply(IntegrationTestPlugin.class); + + assertThat(rootProject.getTasks().findByPath("integrationTest")).isNull(); + } + +} diff --git a/buildSrc/src/test/java/io/spring/gradle/convention/JavadocApiPluginTest.java b/buildSrc/src/test/java/io/spring/gradle/convention/JavadocApiPluginTest.java new file mode 100644 index 0000000000..ddcd3c9191 --- /dev/null +++ b/buildSrc/src/test/java/io/spring/gradle/convention/JavadocApiPluginTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2016 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.apache.commons.io.FileUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.gradle.api.Project; +import org.gradle.api.tasks.javadoc.Javadoc; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.After; +import org.junit.Test; + +/** + * @author Rob Winch + */ +public class JavadocApiPluginTest { + Project rootProject; + + @After + public void cleanup() throws Exception { + if (rootProject != null) { + FileUtils.deleteDirectory(rootProject.getProjectDir()); + } + } + + @Test + public void applyWhenNotOverrideThenPropertiesDefaulted() { + rootProject = ProjectBuilder.builder().build(); + rootProject.getPlugins().apply(JavadocApiPlugin.class); + + Javadoc apiTask = (Javadoc) rootProject.getTasks().getByPath("api"); + + assertThat(apiTask).isNotNull(); + assertThat(apiTask.getGroup()).isEqualTo("Documentation"); + assertThat(apiTask.getDescription()).isEqualTo("Generates aggregated Javadoc API documentation."); + assertThat(apiTask.getMaxMemory()).isEqualTo("1024m"); + assertThat(apiTask.getDestinationDir()).isEqualTo(new File(rootProject.getBuildDir(), "api")); + } + +} diff --git a/buildSrc/src/test/java/io/spring/gradle/convention/RepositoryConventionPluginTests.java b/buildSrc/src/test/java/io/spring/gradle/convention/RepositoryConventionPluginTests.java new file mode 100644 index 0000000000..b0aace1491 --- /dev/null +++ b/buildSrc/src/test/java/io/spring/gradle/convention/RepositoryConventionPluginTests.java @@ -0,0 +1,158 @@ +/* + * Copyright 2016-2018 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.Project; +import org.gradle.api.artifacts.dsl.RepositoryHandler; +import org.gradle.api.artifacts.repositories.ArtifactRepository; +import org.gradle.api.artifacts.repositories.MavenArtifactRepository; +import org.gradle.api.plugins.ExtraPropertiesExtension; +import org.gradle.testfixtures.ProjectBuilder; +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link RepositoryConventionPlugin}. + */ +public class RepositoryConventionPluginTests { + + private Project project = ProjectBuilder.builder().build(); + + @Before + public void setUp() { + this.project.getProperties().clear(); + } + + @Test + public void applyWhenIsReleaseThenShouldIncludeReleaseRepo() { + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertReleaseRepository(repositories); + } + + @Test + public void applyWhenIsMilestoneThenShouldIncludeMilestoneRepo() { + this.project.setVersion("1.0.0.M1"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertMilestoneRepository(repositories); // milestone + } + + @Test + public void applyWhenIsSnapshotThenShouldIncludeSnapshotRepo() { + this.project.setVersion("1.0.0.BUILD-SNAPSHOT"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertSnapshotRepository(repositories); + } + + @Test + public void applyWhenIsSnapshotWithForceReleaseThenShouldOnlyIncludeReleaseRepo() { + this.project.getExtensions().getByType(ExtraPropertiesExtension.class) + .set("forceMavenRepositories", "release"); + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertReleaseRepository(repositories); + } + + @Test + public void applyWhenIsReleaseWithForceMilestoneThenShouldIncludeMilestoneRepo() { + this.project.getExtensions().getByType(ExtraPropertiesExtension.class) + .set("forceMavenRepositories", "milestone"); + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertMilestoneRepository(repositories); + } + + @Test + public void applyWhenIsReleaseWithForceSnapshotThenShouldIncludeSnapshotRepo() { + this.project.getExtensions().getByType(ExtraPropertiesExtension.class) + .set("forceMavenRepositories", "snapshot"); + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertSnapshotRepository(repositories); + } + + @Test + public void applyWhenIsReleaseWithForceLocalThenShouldIncludeReleaseAndLocalRepos() { + this.project.getExtensions().getByType(ExtraPropertiesExtension.class) + .set("forceMavenRepositories", "local"); + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertThat(repositories).hasSize(4); + assertThat((repositories.get(0)).getName()).isEqualTo("MavenLocal"); + } + + @Test + public void applyWhenIsReleaseWithForceMilestoneAndLocalThenShouldIncludeMilestoneAndLocalRepos() { + this.project.getExtensions().getByType(ExtraPropertiesExtension.class) + .set("forceMavenRepositories", "milestone,local"); + this.project.setVersion("1.0.0.RELEASE"); + this.project.getPluginManager().apply(RepositoryConventionPlugin.class); + + RepositoryHandler repositories = this.project.getRepositories(); + assertThat(repositories).hasSize(5); + assertThat((repositories.get(0)).getName()).isEqualTo("MavenLocal"); + } + + private void assertSnapshotRepository(RepositoryHandler repositories) { + assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(5); + assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString()) + .isEqualTo("https://repo.maven.apache.org/maven2/"); + assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString()) + .isEqualTo("https://jcenter.bintray.com/"); + assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString()) + .isEqualTo("https://repo.spring.io/snapshot/"); + assertThat(((MavenArtifactRepository) repositories.get(3)).getUrl().toString()) + .isEqualTo("https://repo.spring.io/milestone/"); + } + + private void assertMilestoneRepository(RepositoryHandler repositories) { + assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(4); + assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString()) + .isEqualTo("https://repo.maven.apache.org/maven2/"); + assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString()) + .isEqualTo("https://jcenter.bintray.com/"); + assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString()) + .isEqualTo("https://repo.spring.io/milestone/"); + } + + private void assertReleaseRepository(RepositoryHandler repositories) { + assertThat(repositories).extracting(ArtifactRepository::getName).hasSize(3); + assertThat(((MavenArtifactRepository) repositories.get(0)).getUrl().toString()) + .isEqualTo("https://repo.maven.apache.org/maven2/"); + assertThat(((MavenArtifactRepository) repositories.get(1)).getUrl().toString()) + .isEqualTo("https://jcenter.bintray.com/"); + assertThat(((MavenArtifactRepository) repositories.get(2)).getUrl().toString()) + .isEqualTo("https://repo.spring.io/release/"); + } + +} diff --git a/buildSrc/src/test/java/io/spring/gradle/convention/UtilsTest.java b/buildSrc/src/test/java/io/spring/gradle/convention/UtilsTest.java new file mode 100644 index 0000000000..76fbea3870 --- /dev/null +++ b/buildSrc/src/test/java/io/spring/gradle/convention/UtilsTest.java @@ -0,0 +1,151 @@ +package io.spring.gradle.convention; + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import org.gradle.api.Project; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class UtilsTest { + @Mock + Project project; + @Mock + Project rootProject; + + @Before + public void setup() { + when(project.getRootProject()).thenReturn(rootProject); + } + + @Test + public void getProjectName() { + when(rootProject.getName()).thenReturn("spring-security"); + + assertThat(Utils.getProjectName(project)).isEqualTo("spring-security"); + } + + @Test + public void getProjectNameWhenEndsWithBuildThenStrippedOut() { + when(rootProject.getName()).thenReturn("spring-security-build"); + + assertThat(Utils.getProjectName(project)).isEqualTo("spring-security"); + } + + @Test + public void isSnapshotValidWithDot() { + when(project.getVersion()).thenReturn("1.0.0.BUILD-SNAPSHOT"); + + assertThat(Utils.isSnapshot(project)).isTrue(); + } + + @Test + public void isSnapshotValidWithNoBuild() { + when(project.getVersion()).thenReturn("1.0.0-SNAPSHOT"); + + assertThat(Utils.isSnapshot(project)).isTrue(); + } + + @Test + public void isSnapshotValidWithDash() { + when(project.getVersion()).thenReturn("Theme-BUILD-SNAPSHOT"); + + assertThat(Utils.isSnapshot(project)).isTrue(); + } + + @Test + public void isSnapshotInvalid() { + when(project.getVersion()).thenReturn("1.0.0.SNAPSHOT"); + + assertThat(Utils.isSnapshot(project)).isFalse(); + } + + @Test + public void isMilestoneValidWithDot() { + when(project.getVersion()).thenReturn("1.0.0.M1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isMilestoneValidWithDash() { + when(project.getVersion()).thenReturn("Theme-M1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isMilestoneValidWithNumberDash() { + when(project.getVersion()).thenReturn("1.0.0-M1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isMilestoneInvalid() { + when(project.getVersion()).thenReturn("1.0.0.M"); + + assertThat(Utils.isMilestone(project)).isFalse(); + } + + @Test + public void isReleaseCandidateValidWithDot() { + when(project.getVersion()).thenReturn("1.0.0.RC1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isReleaseCandidateValidWithNumberDash() { + when(project.getVersion()).thenReturn("1.0.0-RC1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isReleaseCandidateValidWithDash() { + when(project.getVersion()).thenReturn("Theme-RC1"); + + assertThat(Utils.isMilestone(project)).isTrue(); + } + + @Test + public void isReleaseCandidateInvalid() { + when(project.getVersion()).thenReturn("1.0.0.RC"); + + assertThat(Utils.isMilestone(project)).isFalse(); + } + + @Test + public void isReleaseValidWithDot() { + when(project.getVersion()).thenReturn("1.0.0.RELEASE"); + + assertThat(Utils.isRelease(project)).isTrue(); + } + + @Test + public void isReleaseValidWithNoRelease() { + when(project.getVersion()).thenReturn("1.0.0"); + + assertThat(Utils.isRelease(project)).isTrue(); + } + + @Test + public void isReleaseValidWithDash() { + when(project.getVersion()).thenReturn("Theme-RELEASE"); + + assertThat(Utils.isRelease(project)).isTrue(); + } + + @Test + public void isServiceReleaseValid() { + when(project.getVersion()).thenReturn("Theme-SR1"); + + assertThat(Utils.isRelease(project)).isTrue(); + } +} diff --git a/buildSrc/src/test/resources/samples/dependencyset/build.gradle b/buildSrc/src/test/resources/samples/dependencyset/build.gradle new file mode 100644 index 0000000000..c4327c7e8c --- /dev/null +++ b/buildSrc/src/test/resources/samples/dependencyset/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'io.spring.convention.dependency-set' +} + +apply plugin: 'java' +apply from: "$rootDir/gradle/dependency-management.gradle" + +repositories { + mavenCentral() +} + +dependencies { + testCompile spockDependencies + testCompile gebDependencies + testCompile powerMockDependencies + testCompile seleniumDependencies + testCompile slf4jDependencies + testCompile springCoreDependency + testCompile jstlDependencies + testCompile apachedsDependencies +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/dependencyset/gradle/dependency-management.gradle b/buildSrc/src/test/resources/samples/dependencyset/gradle/dependency-management.gradle new file mode 100644 index 0000000000..032446af5f --- /dev/null +++ b/buildSrc/src/test/resources/samples/dependencyset/gradle/dependency-management.gradle @@ -0,0 +1,724 @@ +// we use this to mock dependency management plugin + +def deps = [ + "antlr:antlr" : "2.7.7", + "aopalliance:aopalliance" : "1.0", + "biz.paluch.redis:lettuce" : "5.0.0.Beta1", + "ch.qos.logback:logback-access" : "1.1.9", + "ch.qos.logback:logback-classic" : "1.1.9", + "ch.qos.logback:logback-core" : "1.1.9", + "com.atomikos:transactions-jdbc" : "3.9.3", + "com.atomikos:transactions-jms" : "3.9.3", + "com.atomikos:transactions-jta" : "3.9.3", + "com.caucho:hessian" : "4.0.38", + "com.couchbase.client:couchbase-spring-cache" : "2.1.0", + "com.couchbase.client:java-client" : "2.3.7", + "com.datastax.cassandra:cassandra-driver-core" : "3.1.3", + "com.datastax.cassandra:cassandra-driver-mapping" : "3.1.3", + "com.esotericsoftware:kryo" : "3.0.3", + "com.esotericsoftware:kryo-shaded" : "3.0.3", + "com.fasterxml:classmate" : "1.3.3", + "com.fasterxml.jackson.core:jackson-annotations" : "2.8.0", + "com.fasterxml.jackson.core:jackson-core" : "2.8.6", + "com.fasterxml.jackson.core:jackson-databind" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-avro" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-csv" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-properties" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-protobuf" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-smile" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-xml" : "2.8.6", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-guava" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-hibernate3" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-hibernate4" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-hibernate5" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-hppc" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-jaxrs" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-jdk8" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-joda" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-json-org" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr353" : "2.8.6", + "com.fasterxml.jackson.datatype:jackson-datatype-pcollections" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-cbor-provider" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-smile-provider" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-xml-provider" : "2.8.6", + "com.fasterxml.jackson.jaxrs:jackson-jaxrs-yaml-provider" : "2.8.6", + "com.fasterxml.jackson.jr:jackson-jr-all" : "2.8.6", + "com.fasterxml.jackson.jr:jackson-jr-objects" : "2.8.6", + "com.fasterxml.jackson.jr:jackson-jr-retrofit2" : "2.8.6", + "com.fasterxml.jackson.jr:jackson-jr-stree" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-afterburner" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-guice" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-jaxb-annotations" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-jsonSchema" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-kotlin" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-mrbean" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-osgi" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-parameter-names" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-paranamer" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-scala_2.10" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-scala_2.11" : "2.8.6", + "com.fasterxml.jackson.module:jackson-module-scala_2.12" : "2.8.6", + "com.gemstone.gemfire:gemfire" : "8.2.0", + "com.github.ben-manes.caffeine:caffeine" : "2.3.5", + "com.github.mxab.thymeleaf.extras:thymeleaf-extras-data-attribute" : "1.3", + "com.github.spullara.redis:client" : "0.7", + "com.goldmansachs:gs-collections" : "5.1.0", + "com.google.appengine:appengine-api-1.0-sdk" : "1.9.48", + "com.google.code.findbugs:annotations" : "2.0.3", + "com.google.code.findbugs:jsr305" : "3.0.1", + "com.google.code.gson:gson" : "2.8.0", + "com.google.code.typica:typica" : "1.3", + "com.google.guava:guava" : "20.0", + "com.google.inject:guice" : "3.0", + "com.google.protobuf:protobuf-java" : "2.6.1", + "com.googlecode.json-simple:json-simple" : "1.1.1", + "com.googlecode.protobuf-java-format:protobuf-java-format" : "1.4", + "com.h2database:h2" : "1.4.193", + "com.hazelcast:hazelcast" : "3.7.5", + "com.hazelcast:hazelcast-client" : "3.7.5", + "com.hazelcast:hazelcast-hibernate4" : "3.7.1", + "com.hazelcast:hazelcast-hibernate5" : "1.1.3", + "com.hazelcast:hazelcast-spring" : "3.7.5", + "com.ibm.jbatch:com.ibm.jbatch-tck-spi" : "1.0", + "com.ibm.websphere:uow" : "6.0.2.17", + "com.jamonapi:jamon" : "2.81", + "com.jayway.jsonpath:json-path" : "2.2.0", + "com.jayway.jsonpath:json-path-assert" : "2.2.0", + "com.jayway.restassured:rest-assured" : "2.9.0", + "com.jcraft:jsch" : "0.1.54", + "com.lowagie:itext" : "2.1.7", + "com.maxmind.geoip2:geoip2" : "2.3.1", + "com.mchange:c3p0" : "0.9.5.2", + "com.microsoft.sqlserver:mssql-jdbc" : "6.1.0.jre7", + "com.querydsl:querydsl-apt" : "4.1.4", + "com.querydsl:querydsl-collections" : "4.1.4", + "com.querydsl:querydsl-core" : "4.1.4", + "com.querydsl:querydsl-jpa" : "4.1.4", + "com.querydsl:querydsl-mongodb" : "4.1.4", + "com.rabbitmq:amqp-client" : "4.0.2", + "com.rabbitmq:http-client" : "1.1.0.RELEASE", + "com.rometools:rome" : "1.6.1", + "com.rometools:rome-fetcher" : "1.6.1", + "com.samskivert:jmustache" : "1.13", + "com.sendgrid:sendgrid-java" : "2.2.2", + "com.splunk:splunk" : "1.3.0", + "com.squareup.okhttp:okhttp" : "2.7.5", + "com.squareup.okhttp3:okhttp" : "3.6.0", + "com.sun:ldapbp" : "1.0", + "com.sun.facelets:jsf-facelets" : "1.1.14", + "com.sun.faces:jsf-api" : "2.2.14", + "com.sun.faces:jsf-impl" : "2.2.14", + "com.sun.mail:imap" : "1.5.6", + "com.sun.mail:javax.mail" : "1.5.6", + "com.sun.xml.messaging.saaj:saaj-impl" : "1.3.28", + "com.sun.xml.wss:xws-security" : "3.0", + "com.thoughtworks.xstream:xstream" : "1.4.9", + "com.timgroup:java-statsd-client" : "3.1.0", + "com.unboundid:unboundid-ldapsdk" : "3.2.0", + "com.zaxxer:HikariCP" : "2.5.1", + "com.zaxxer:HikariCP-java6" : "2.3.13", + "commons-beanutils:commons-beanutils" : "1.9.3", + "commons-cli:commons-cli" : "1.3.1", + "commons-codec:commons-codec" : "1.10", + "commons-collections:commons-collections" : "3.2.2", + "commons-dbcp:commons-dbcp" : "1.4", + "commons-digester:commons-digester" : "2.1", + "commons-fileupload:commons-fileupload" : "1.3.2", + "commons-httpclient:commons-httpclient" : "3.1", + "commons-io:commons-io" : "2.5", + "commons-lang:commons-lang" : "2.6", + "commons-logging:commons-logging" : "1.2", + "commons-net:commons-net" : "3.5", + "commons-pool:commons-pool" : "1.6", + "de.flapdoodle.embed:de.flapdoodle.embed.mongo" : "1.50.5", + "dom4j:dom4j" : "1.6.1", + "edu.umd.cs.mtc:multithreadedtc" : "1.01", + "io.dropwizard.metrics:metrics-core" : "3.1.2", + "io.dropwizard.metrics:metrics-ganglia" : "3.1.2", + "io.dropwizard.metrics:metrics-graphite" : "3.1.2", + "io.dropwizard.metrics:metrics-servlets" : "3.1.2", + "io.fastjson:boon" : "0.34", + "io.javaslang:javaslang" : "2.0.5", + "io.javaslang:javaslang-match" : "2.0.5", + "io.netty:netty-all" : "4.0.44.Final", + "io.projectreactor:reactor-bus" : "2.0.8.RELEASE", + "io.projectreactor:reactor-core" : "2.0.8.RELEASE", + "io.projectreactor:reactor-groovy" : "2.0.8.RELEASE", + "io.projectreactor:reactor-groovy-extensions" : "2.0.8.RELEASE", + "io.projectreactor:reactor-logback" : "2.0.8.RELEASE", + "io.projectreactor:reactor-net" : "2.0.8.RELEASE", + "io.projectreactor:reactor-stream" : "2.0.8.RELEASE", + "io.projectreactor.spring:reactor-spring-context" : "2.0.7.RELEASE", + "io.projectreactor.spring:reactor-spring-core" : "2.0.7.RELEASE", + "io.projectreactor.spring:reactor-spring-messaging" : "2.0.7.RELEASE", + "io.projectreactor.spring:reactor-spring-webmvc" : "2.0.7.RELEASE", + "io.searchbox:jest" : "2.0.4", + "io.undertow:undertow-core" : "1.4.8.Final", + "io.undertow:undertow-servlet" : "1.4.8.Final", + "io.undertow:undertow-websockets-jsr" : "1.4.8.Final", + "javax.activation:activation" : "1.1.1", + "javax.annotation:jsr250-api" : "1.0", + "javax.batch:javax.batch-api" : "1.0.1", + "javax.cache:cache-api" : "1.0.0", + "javax.ejb:javax.ejb-api" : "3.2", + "javax.el:javax.el-api" : "2.2.5", + "javax.enterprise:cdi-api" : "1.2", + "javax.enterprise.concurrent:javax.enterprise.concurrent-api" : "1.0", + "javax.faces:javax.faces-api" : "2.2", + "javax.inject:javax.inject" : "1", + "javax.interceptor:javax.interceptor-api" : "1.2", + "javax.jdo:jdo-api" : "3.0.1", + "javax.jms:jms-api" : "1.1-rev-1", + "javax.mail:javax.mail-api" : "1.5.6", + "javax.money:money-api" : "1.0.1", + "javax.portlet:portlet-api" : "2.0", + "javax.resource:connector-api" : "1.5", + "javax.servlet:javax.servlet-api" : "3.1.0", + "javax.servlet:jstl" : "1.2", + "javax.servlet.jsp:javax.servlet.jsp-api" : "2.3.1", + "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api" : "1.2.1", + "javax.transaction:javax.transaction-api" : "1.2", + "javax.validation:validation-api" : "1.1.0.Final", + "javax.websocket:javax.websocket-api" : "1.1", + "javax.ws.rs:javax.ws.rs-api" : "2.0.1", + "jaxen:jaxen" : "1.1.6", + "jline:jline" : "2.14.3", + "joda-time:joda-time" : "2.9.7", + "junit:junit" : "4.12", + "ldapsdk:ldapsdk" : "4.1", + "log4j:log4j" : "1.2.17", + "mysql:mysql-connector-java" : "5.1.40", + "net.java.dev.jna:jna" : "4.2.2", + "net.openhft:chronicle" : "3.4.4", + "net.openhft:lang" : "6.6.16", + "net.sf.ehcache:ehcache" : "2.10.3", + "net.sf.jasperreports:jasperreports" : "6.4.0", + "net.sf.jopt-simple:jopt-simple" : "5.0.3", + "net.sourceforge.htmlunit:htmlunit" : "2.21", + "net.sourceforge.jexcelapi:jxl" : "2.6.12", + "net.sourceforge.jtds:jtds" : "1.3.1", + "net.sourceforge.nekohtml:nekohtml" : "1.9.22", + "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect" : "1.4.0", + "opensymphony:ognl" : "2.6.11", + "org.apache.activemq:activemq-amqp" : "5.14.3", + "org.apache.activemq:activemq-blueprint" : "5.14.3", + "org.apache.activemq:activemq-broker" : "5.14.3", + "org.apache.activemq:activemq-camel" : "5.14.3", + "org.apache.activemq:activemq-client" : "5.14.3", + "org.apache.activemq:activemq-console" : "5.14.3", + "org.apache.activemq:activemq-http" : "5.14.3", + "org.apache.activemq:activemq-jaas" : "5.14.3", + "org.apache.activemq:activemq-jdbc-store" : "5.14.3", + "org.apache.activemq:activemq-jms-pool" : "5.14.3", + "org.apache.activemq:activemq-kahadb-store" : "5.14.3", + "org.apache.activemq:activemq-karaf" : "5.14.3", + "org.apache.activemq:activemq-leveldb-store" : "5.14.3", + "org.apache.activemq:activemq-log4j-appender" : "5.14.3", + "org.apache.activemq:activemq-mqtt" : "5.14.3", + "org.apache.activemq:activemq-openwire-generator" : "5.14.3", + "org.apache.activemq:activemq-openwire-legacy" : "5.14.3", + "org.apache.activemq:activemq-osgi" : "5.14.3", + "org.apache.activemq:activemq-partition" : "5.14.3", + "org.apache.activemq:activemq-pool" : "5.14.3", + "org.apache.activemq:activemq-ra" : "5.14.3", + "org.apache.activemq:activemq-run" : "5.14.3", + "org.apache.activemq:activemq-runtime-config" : "5.14.3", + "org.apache.activemq:activemq-shiro" : "5.14.3", + "org.apache.activemq:activemq-spring" : "5.14.3", + "org.apache.activemq:activemq-stomp" : "5.14.3", + "org.apache.activemq:activemq-web" : "5.14.3", + "org.apache.activemq:artemis-amqp-protocol" : "1.5.2", + "org.apache.activemq:artemis-commons" : "1.5.2", + "org.apache.activemq:artemis-core-client" : "1.5.2", + "org.apache.activemq:artemis-jms-client" : "1.5.2", + "org.apache.activemq:artemis-jms-server" : "1.5.2", + "org.apache.activemq:artemis-journal" : "1.5.2", + "org.apache.activemq:artemis-native" : "1.5.2", + "org.apache.activemq:artemis-selector" : "1.5.2", + "org.apache.activemq:artemis-server" : "1.5.2", + "org.apache.activemq:artemis-service-extensions" : "1.5.2", + "org.apache.commons:commons-dbcp2" : "2.1.1", + "org.apache.commons:commons-lang3" : "3.5", + "org.apache.commons:commons-pool2" : "2.4.2", + "org.apache.curator:curator-recipes" : "2.11.1", + "org.apache.derby:derby" : "10.13.1.1", + "org.apache.derby:derbyclient" : "10.13.1.1", + "org.apache.directory.server:apacheds-core" : "1.5.5", + "org.apache.directory.server:apacheds-core-entry" : "1.5.5", + "org.apache.directory.server:apacheds-protocol-ldap" : "1.5.5", + "org.apache.directory.server:apacheds-protocol-shared" : "1.5.5", + "org.apache.directory.server:apacheds-server-jndi" : "1.5.5", + "org.apache.directory.shared:shared-ldap" : "0.9.15", + "org.apache.httpcomponents:httpasyncclient" : "4.1.2", + "org.apache.httpcomponents:httpclient" : "4.5.2", + "org.apache.httpcomponents:httpcore" : "4.4.6", + "org.apache.httpcomponents:httpmime" : "4.5.2", + "org.apache.ibatis:ibatis-sqlmap" : "2.3.4.726", + "org.apache.kafka:kafka-clients" : "0.10.1.1", + "org.apache.kafka:kafka_2.11" : "0.10.1.1", + "org.apache.logging.log4j:log4j-1.2-api" : "2.7", + "org.apache.logging.log4j:log4j-api" : "2.7", + "org.apache.logging.log4j:log4j-api-scala_2.10" : "2.7", + "org.apache.logging.log4j:log4j-api-scala_2.11" : "2.7", + "org.apache.logging.log4j:log4j-core" : "2.7", + "org.apache.logging.log4j:log4j-flume-ng" : "2.7", + "org.apache.logging.log4j:log4j-iostreams" : "2.7", + "org.apache.logging.log4j:log4j-jcl" : "2.7", + "org.apache.logging.log4j:log4j-jmx-gui" : "2.7", + "org.apache.logging.log4j:log4j-jul" : "2.7", + "org.apache.logging.log4j:log4j-liquibase" : "2.7", + "org.apache.logging.log4j:log4j-nosql" : "2.7", + "org.apache.logging.log4j:log4j-slf4j-impl" : "2.7", + "org.apache.logging.log4j:log4j-taglib" : "2.7", + "org.apache.logging.log4j:log4j-web" : "2.7", + "org.apache.myfaces.core:myfaces-impl" : "2.2.11", + "org.apache.openjpa:openjpa" : "2.4.2", + "org.apache.openjpa:openjpa-persistence-jdbc" : "2.4.2", + "org.apache.poi:poi" : "3.15", + "org.apache.poi:poi-ooxml" : "3.15", + "org.apache.poi:poi-scratchpad" : "3.15", + "org.apache.solr:solr-core" : "5.5.3", + "org.apache.solr:solr-solrj" : "5.5.3", + "org.apache.taglibs:taglibs-standard-impl" : "1.2.5", + "org.apache.taglibs:taglibs-standard-jstlel" : "1.2.5", + "org.apache.taglibs:taglibs-standard-spec" : "1.2.5", + "org.apache.tiles:tiles-api" : "3.0.7", + "org.apache.tiles:tiles-core" : "3.0.7", + "org.apache.tiles:tiles-el" : "3.0.7", + "org.apache.tiles:tiles-extras" : "3.0.7", + "org.apache.tiles:tiles-jsp" : "3.0.7", + "org.apache.tiles:tiles-request-api" : "1.0.6", + "org.apache.tiles:tiles-servlet" : "3.0.7", + "org.apache.tomcat:tomcat-catalina" : "8.5.11", + "org.apache.tomcat:tomcat-dbcp" : "8.5.11", + "org.apache.tomcat:tomcat-jdbc" : "8.5.11", + "org.apache.tomcat:tomcat-jsp-api" : "8.5.11", + "org.apache.tomcat:tomcat-websocket" : "8.5.11", + "org.apache.tomcat.embed:tomcat-embed-core" : "8.5.11", + "org.apache.tomcat.embed:tomcat-embed-el" : "8.5.11", + "org.apache.tomcat.embed:tomcat-embed-jasper" : "8.5.11", + "org.apache.tomcat.embed:tomcat-embed-websocket" : "8.5.11", + "org.apache.velocity:velocity" : "1.7", + "org.apache.ws.commons.axiom:axiom-api" : "1.2.20", + "org.apache.ws.commons.axiom:axiom-impl" : "1.2.20", + "org.apache.ws.security:wss4j" : "1.6.19", + "org.apache.ws.xmlschema:xmlschema-core" : "2.2.1", + "org.apache.wss4j:wss4j-ws-security-common" : "2.1.8", + "org.apache.wss4j:wss4j-ws-security-dom" : "2.1.8", + "org.apache.xmlbeans:xmlbeans" : "2.6.0", + "org.aspectj:aspectjrt" : "1.8.9", + "org.aspectj:aspectjtools" : "1.8.9", + "org.aspectj:aspectjweaver" : "1.8.9", + "org.assertj:assertj-core" : "2.6.0", + "org.atteo:evo-inflector" : "1.2.2", + "org.beanshell:bsh" : "2.0b4", + "org.bouncycastle:bcpkix-jdk15on" : "1.56", + "org.codehaus.btm:btm" : "2.1.4", + "org.codehaus.castor:castor-xml" : "1.4.1", + "org.codehaus.fabric3.api:commonj" : "1.1.1", + "org.codehaus.groovy:groovy" : "2.4.7", + "org.codehaus.groovy:groovy-all" : "2.4.7", + "org.codehaus.groovy:groovy-ant" : "2.4.7", + "org.codehaus.groovy:groovy-bsf" : "2.4.7", + "org.codehaus.groovy:groovy-console" : "2.4.7", + "org.codehaus.groovy:groovy-docgenerator" : "2.4.7", + "org.codehaus.groovy:groovy-groovydoc" : "2.4.7", + "org.codehaus.groovy:groovy-groovysh" : "2.4.7", + "org.codehaus.groovy:groovy-jmx" : "2.4.7", + "org.codehaus.groovy:groovy-json" : "2.4.7", + "org.codehaus.groovy:groovy-jsr223" : "2.4.7", + "org.codehaus.groovy:groovy-nio" : "2.4.7", + "org.codehaus.groovy:groovy-servlet" : "2.4.7", + "org.codehaus.groovy:groovy-sql" : "2.4.7", + "org.codehaus.groovy:groovy-swing" : "2.4.7", + "org.codehaus.groovy:groovy-templates" : "2.4.7", + "org.codehaus.groovy:groovy-test" : "2.4.7", + "org.codehaus.groovy:groovy-testng" : "2.4.7", + "org.codehaus.groovy:groovy-xml" : "2.4.7", + "org.codehaus.jackson:jackson-core-asl" : "1.9.13", + "org.codehaus.jackson:jackson-mapper-asl" : "1.9.13", + "org.codehaus.janino:janino" : "2.7.8", + "org.codehaus.jettison:jettison" : "1.2", + "org.codehaus.woodstox:woodstox-core-asl" : "4.4.1", + "org.crashub:crash.cli" : "1.3.2", + "org.crashub:crash.connectors.ssh" : "1.3.2", + "org.crashub:crash.connectors.telnet" : "1.3.2", + "org.crashub:crash.embed.spring" : "1.3.2", + "org.crashub:crash.plugins.cron" : "1.3.2", + "org.crashub:crash.plugins.mail" : "1.3.2", + "org.crashub:crash.shell" : "1.3.2", + "org.eclipse.jetty:apache-jsp" : "9.4.1.v20170120", + "org.eclipse.jetty:apache-jstl" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-annotations" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-client" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-continuation" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-deploy" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-http" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-io" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-jmx" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-plus" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-proxy" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-security" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-server" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-servlet" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-servlets" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-util" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-webapp" : "9.4.1.v20170120", + "org.eclipse.jetty:jetty-xml" : "9.4.1.v20170120", + "org.eclipse.jetty.orbit:javax.servlet.jsp" : "2.2.0.v201112011158", + "org.eclipse.jetty.websocket:javax-websocket-server-impl" : "9.4.1.v20170120", + "org.eclipse.jetty.websocket:websocket-client" : "9.4.1.v20170120", + "org.eclipse.jetty.websocket:websocket-server" : "9.4.1.v20170120", + "org.eclipse.paho:org.eclipse.paho.client.mqttv3" : "1.1.0", + "org.eclipse.persistence:javax.persistence" : "2.1.1", + "org.eclipse.persistence:org.eclipse.persistence.core" : "2.6.4", + "org.eclipse.persistence:org.eclipse.persistence.jpa" : "2.6.4", + "org.ehcache:ehcache" : "3.2.0", + "org.ehcache:ehcache-clustered" : "3.2.0", + "org.ehcache:ehcache-transactions" : "3.2.0", + "org.elasticsearch:elasticsearch" : "2.4.4", + "org.firebirdsql.jdbc:jaybird-jdk16" : "2.2.12", + "org.firebirdsql.jdbc:jaybird-jdk17" : "2.2.12", + "org.firebirdsql.jdbc:jaybird-jdk18" : "2.2.12", + "org.flywaydb:flyway-core" : "3.2.1", + "org.freemarker:freemarker" : "2.3.25-incubating", + "org.glassfish:javax.el" : "3.0.0", + "org.glassfish.jersey.containers:jersey-container-servlet" : "2.25.1", + "org.glassfish.jersey.containers:jersey-container-servlet-core" : "2.25.1", + "org.glassfish.jersey.core:jersey-server" : "2.25.1", + "org.glassfish.jersey.ext:jersey-bean-validation" : "2.25.1", + "org.glassfish.jersey.ext:jersey-spring3" : "2.25.1", + "org.glassfish.jersey.media:jersey-media-json-jackson" : "2.25.1", + "org.glassfish.tyrus:tyrus-container-servlet" : "1.3.5", + "org.glassfish.tyrus:tyrus-core" : "1.3.5", + "org.glassfish.tyrus:tyrus-server" : "1.3.5", + "org.glassfish.tyrus:tyrus-spi" : "1.3.5", + "org.hamcrest:hamcrest-all" : "1.3", + "org.hamcrest:hamcrest-core" : "1.3", + "org.hamcrest:hamcrest-library" : "1.3", + "org.hibernate:hibernate-core" : "5.0.11.Final", + "org.hibernate:hibernate-ehcache" : "5.0.11.Final", + "org.hibernate:hibernate-entitymanager" : "5.0.11.Final", + "org.hibernate:hibernate-envers" : "5.0.11.Final", + "org.hibernate:hibernate-java8" : "5.0.11.Final", + "org.hibernate:hibernate-jpamodelgen" : "5.0.11.Final", + "org.hibernate:hibernate-validator" : "5.3.4.Final", + "org.hibernate:hibernate-validator-annotation-processor" : "5.3.4.Final", + "org.hsqldb:hsqldb" : "2.3.3", + "org.igniterealtime.smack:smack-extensions" : "4.1.9", + "org.igniterealtime.smack:smack-java7" : "4.1.9", + "org.igniterealtime.smack:smack-resolver-javax" : "4.1.9", + "org.igniterealtime.smack:smack-tcp" : "4.1.9", + "org.infinispan:infinispan-jcache" : "8.2.5.Final", + "org.infinispan:infinispan-spring4-common" : "8.2.5.Final", + "org.infinispan:infinispan-spring4-embedded" : "8.2.5.Final", + "org.jasig.cas.client:cas-client-core" : "3.4.1", + "org.javassist:javassist" : "3.21.0-GA", + "org.jboss:jboss-transaction-spi" : "7.5.0.Final", + "org.jboss.logging:jboss-logging" : "3.3.0.Final", + "org.jboss.narayana.jta:jdbc" : "5.5.1.Final", + "org.jboss.narayana.jta:jms" : "5.5.1.Final", + "org.jboss.narayana.jta:jta" : "5.5.1.Final", + "org.jboss.narayana.jts:narayana-jts-integration" : "5.5.1.Final", + "org.jdom:jdom2" : "2.0.6", + "org.jibx:jibx-run" : "1.3.1", + "org.jolokia:jolokia-core" : "1.3.5", + "org.jooq:jooq" : "3.9.1", + "org.jooq:jooq-codegen" : "3.9.1", + "org.jooq:jooq-meta" : "3.9.1", + "org.jredis:jredis-core-api" : "06052013", + "org.jredis:jredis-core-ri" : "06052013", + "org.jruby:jruby" : "1.7.26", + "org.json:json" : "20140107", + "org.liquibase:liquibase-core" : "3.5.3", + "org.mariadb.jdbc:mariadb-java-client" : "1.5.7", + "org.mockito:mockito-core" : "1.10.19", + "org.mongodb:mongo-java-driver" : "3.4.1", + "org.mongodb:mongodb-driver" : "3.4.1", + "org.mortbay.jasper:apache-el" : "8.0.33", + "org.neo4j:neo4j-ogm-api" : "2.1.1", + "org.neo4j:neo4j-ogm-compiler" : "2.1.1", + "org.neo4j:neo4j-ogm-core" : "2.1.1", + "org.neo4j:neo4j-ogm-http-driver" : "2.1.1", + "org.objenesis:objenesis" : "2.5.1", + "org.openid4java:openid4java-nodeps" : "0.9.6", + "org.postgresql:postgresql" : "9.4.1212.jre7", + "org.projectlombok:lombok" : "1.16.12", + "org.quartz-scheduler:quartz" : "2.2.3", + "org.reactivestreams:reactive-streams" : "1.0.0", + "org.seleniumhq.selenium:htmlunit-driver" : "2.21", + "org.seleniumhq.selenium:selenium-api" : "2.53.1", + "org.seleniumhq.selenium:selenium-chrome-driver" : "2.53.1", + "org.seleniumhq.selenium:selenium-firefox-driver" : "2.53.1", + "org.seleniumhq.selenium:selenium-ie-driver" : "2.53.1", + "org.seleniumhq.selenium:selenium-java" : "2.53.1", + "org.seleniumhq.selenium:selenium-remote-driver" : "2.53.1", + "org.seleniumhq.selenium:selenium-safari-driver" : "2.53.1", + "org.seleniumhq.selenium:selenium-support" : "2.53.1", + "org.skyscreamer:jsonassert" : "1.4.0", + "org.slf4j:jcl-over-slf4j" : "1.7.22", + "org.slf4j:jul-to-slf4j" : "1.7.22", + "org.slf4j:log4j-over-slf4j" : "1.7.22", + "org.slf4j:slf4j-api" : "1.7.22", + "org.slf4j:slf4j-jdk14" : "1.7.22", + "org.slf4j:slf4j-log4j12" : "1.7.22", + "org.slf4j:slf4j-simple" : "1.7.22", + "org.spockframework:spock-core" : "1.0-groovy-2.4", + "org.spockframework:spock-spring" : "1.0-groovy-2.4", + "org.springframework:spring-aop" : "4.3.6.RELEASE", + "org.springframework:spring-aspects" : "4.3.6.RELEASE", + "org.springframework:spring-beans" : "4.3.6.RELEASE", + "org.springframework:spring-context" : "4.3.6.RELEASE", + "org.springframework:spring-context-support" : "4.3.6.RELEASE", + "org.springframework:spring-core" : "4.3.6.RELEASE", + "org.springframework:spring-expression" : "4.3.6.RELEASE", + "org.springframework:spring-instrument" : "4.3.6.RELEASE", + "org.springframework:spring-instrument-tomcat" : "4.3.6.RELEASE", + "org.springframework:spring-jdbc" : "4.3.6.RELEASE", + "org.springframework:spring-jms" : "4.3.6.RELEASE", + "org.springframework:spring-messaging" : "4.3.6.RELEASE", + "org.springframework:spring-orm" : "4.3.6.RELEASE", + "org.springframework:spring-oxm" : "4.3.6.RELEASE", + "org.springframework:spring-test" : "4.3.6.RELEASE", + "org.springframework:spring-tx" : "4.3.6.RELEASE", + "org.springframework:spring-web" : "4.3.6.RELEASE", + "org.springframework:spring-webmvc" : "4.3.6.RELEASE", + "org.springframework:spring-webmvc-portlet" : "4.3.6.RELEASE", + "org.springframework:spring-websocket" : "4.3.6.RELEASE", + "org.springframework:springloaded" : "1.2.6.RELEASE", + "org.springframework.amqp:spring-amqp" : "1.7.0.RELEASE", + "org.springframework.amqp:spring-rabbit" : "1.7.0.RELEASE", + "org.springframework.batch:spring-batch-core" : "3.0.7.RELEASE", + "org.springframework.batch:spring-batch-infrastructure" : "3.0.7.RELEASE", + "org.springframework.batch:spring-batch-integration" : "3.0.7.RELEASE", + "org.springframework.batch:spring-batch-test" : "3.0.7.RELEASE", + "org.springframework.boot:spring-boot" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-actuator" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-actuator-docs" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-autoconfigure" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-autoconfigure-processor" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-configuration-metadata" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-configuration-processor" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-devtools" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-loader" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-loader-tools" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-activemq" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-actuator" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-amqp" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-aop" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-artemis" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-batch" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-cache" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-cloud-connectors" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-cassandra" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-couchbase" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-elasticsearch" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-gemfire" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-jpa" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-ldap" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-mongodb" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-neo4j" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-redis" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-rest" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-data-solr" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-freemarker" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-groovy-templates" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-hateoas" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-integration" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jdbc" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jersey" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jetty" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jooq" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jta-atomikos" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jta-bitronix" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-jta-narayana" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-log4j2" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-logging" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-mail" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-mobile" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-mustache" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-remote-shell" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-security" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-social-facebook" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-social-linkedin" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-social-twitter" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-test" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-thymeleaf" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-tomcat" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-undertow" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-validation" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-web" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-web-services" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-starter-websocket" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-test" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-test-autoconfigure" : "1.5.1.RELEASE", + "org.springframework.boot:spring-boot-test-support" : "1.5.1.RELEASE", + "org.springframework.cloud:spring-cloud-cloudfoundry-connector" : "1.2.3.RELEASE", + "org.springframework.cloud:spring-cloud-core" : "1.2.3.RELEASE", + "org.springframework.cloud:spring-cloud-heroku-connector" : "1.2.3.RELEASE", + "org.springframework.cloud:spring-cloud-localconfig-connector" : "1.2.3.RELEASE", + "org.springframework.cloud:spring-cloud-spring-service-connector" : "1.2.3.RELEASE", + "org.springframework.data:spring-cql" : "1.5.0.RELEASE", + "org.springframework.data:spring-data-cassandra" : "1.5.0.RELEASE", + "org.springframework.data:spring-data-commons" : "1.13.0.RELEASE", + "org.springframework.data:spring-data-couchbase" : "2.2.0.RELEASE", + "org.springframework.data:spring-data-elasticsearch" : "2.1.0.RELEASE", + "org.springframework.data:spring-data-envers" : "1.1.0.RELEASE", + "org.springframework.data:spring-data-gemfire" : "1.9.0.RELEASE", + "org.springframework.data:spring-data-jpa" : "1.11.0.RELEASE", + "org.springframework.data:spring-data-keyvalue" : "1.2.0.RELEASE", + "org.springframework.data:spring-data-ldap" : "1.0.0.RELEASE", + "org.springframework.data:spring-data-mongodb" : "1.10.0.RELEASE", + "org.springframework.data:spring-data-mongodb-cross-store" : "1.10.0.RELEASE", + "org.springframework.data:spring-data-mongodb-log4j" : "1.10.0.RELEASE", + "org.springframework.data:spring-data-neo4j" : "4.2.0.RELEASE", + "org.springframework.data:spring-data-redis" : "1.8.0.RELEASE", + "org.springframework.data:spring-data-rest-core" : "2.6.0.RELEASE", + "org.springframework.data:spring-data-rest-hal-browser" : "2.6.0.RELEASE", + "org.springframework.data:spring-data-rest-webmvc" : "2.6.0.RELEASE", + "org.springframework.data:spring-data-solr" : "2.1.0.RELEASE", + "org.springframework.hateoas:spring-hateoas" : "0.23.0.RELEASE", + "org.springframework.integration:spring-integration-amqp" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-core" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-event" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-feed" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-file" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-flow" : "1.0.0.RELEASE", + "org.springframework.integration:spring-integration-ftp" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-gemfire" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-groovy" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-http" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-ip" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-java-dsl" : "1.2.1.RELEASE", + "org.springframework.integration:spring-integration-jdbc" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-jms" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-jmx" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-jpa" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-kafka" : "2.1.0.RELEASE", + "org.springframework.integration:spring-integration-mail" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-mongodb" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-mqtt" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-redis" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-rmi" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-scripting" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-security" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-sftp" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-splunk" : "1.1.0.RELEASE", + "org.springframework.integration:spring-integration-stomp" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-stream" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-syslog" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-test" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-twitter" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-websocket" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-ws" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-xml" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-xmpp" : "4.3.7.RELEASE", + "org.springframework.integration:spring-integration-zookeeper" : "4.3.7.RELEASE", + "org.springframework.kafka:spring-kafka" : "1.1.2.RELEASE", + "org.springframework.kafka:spring-kafka-test" : "1.1.2.RELEASE", + "org.springframework.ldap:spring-ldap-core" : "2.3.1.RELEASE", + "org.springframework.ldap:spring-ldap-core-tiger" : "2.3.1.RELEASE", + "org.springframework.ldap:spring-ldap-ldif-batch" : "2.3.1.RELEASE", + "org.springframework.ldap:spring-ldap-ldif-core" : "2.3.1.RELEASE", + "org.springframework.ldap:spring-ldap-odm" : "2.3.1.RELEASE", + "org.springframework.ldap:spring-ldap-test" : "2.3.1.RELEASE", + "org.springframework.mobile:spring-mobile-device" : "1.1.5.RELEASE", + "org.springframework.plugin:spring-plugin-core" : "1.2.0.RELEASE", + "org.springframework.plugin:spring-plugin-metadata" : "1.2.0.RELEASE", + "org.springframework.restdocs:spring-restdocs-core" : "1.1.2.RELEASE", + "org.springframework.restdocs:spring-restdocs-mockmvc" : "1.1.2.RELEASE", + "org.springframework.restdocs:spring-restdocs-restassured" : "1.1.2.RELEASE", + "org.springframework.retry:spring-retry" : "1.2.0.RELEASE", + "org.springframework.security:spring-security-acl" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-aspects" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-cas" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-config" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-core" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-crypto" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-data" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-jwt" : "1.0.7.RELEASE", + "org.springframework.security:spring-security-ldap" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-messaging" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-openid" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-remoting" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-taglibs" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-test" : "4.2.1.RELEASE", + "org.springframework.security:spring-security-web" : "4.2.1.RELEASE", + "org.springframework.security.oauth:spring-security-oauth" : "2.0.12.RELEASE", + "org.springframework.security.oauth:spring-security-oauth2" : "2.0.12.RELEASE", + "org.springframework.session:spring-session" : "1.3.0.RELEASE", + "org.springframework.session:spring-session-data-gemfire" : "1.3.0.RELEASE", + "org.springframework.session:spring-session-data-mongo" : "1.3.0.RELEASE", + "org.springframework.session:spring-session-data-redis" : "1.3.0.RELEASE", + "org.springframework.session:spring-session-hazelcast" : "1.3.0.RELEASE", + "org.springframework.session:spring-session-jdbc" : "1.3.0.RELEASE", + "org.springframework.shell:spring-shell" : "1.1.0.RELEASE", + "org.springframework.social:spring-social-config" : "1.1.4.RELEASE", + "org.springframework.social:spring-social-core" : "1.1.4.RELEASE", + "org.springframework.social:spring-social-facebook" : "2.0.3.RELEASE", + "org.springframework.social:spring-social-facebook-web" : "2.0.3.RELEASE", + "org.springframework.social:spring-social-linkedin" : "1.0.2.RELEASE", + "org.springframework.social:spring-social-security" : "1.1.4.RELEASE", + "org.springframework.social:spring-social-twitter" : "1.1.2.RELEASE", + "org.springframework.social:spring-social-web" : "1.1.4.RELEASE", + "org.springframework.webflow:spring-binding" : "2.4.4.RELEASE", + "org.springframework.webflow:spring-faces" : "2.4.4.RELEASE", + "org.springframework.webflow:spring-js" : "2.4.4.RELEASE", + "org.springframework.webflow:spring-js-resources" : "2.4.4.RELEASE", + "org.springframework.webflow:spring-webflow" : "2.4.4.RELEASE", + "org.springframework.ws:spring-ws-core" : "2.4.0.RELEASE", + "org.springframework.ws:spring-ws-security" : "2.4.0.RELEASE", + "org.springframework.ws:spring-ws-support" : "2.4.0.RELEASE", + "org.springframework.ws:spring-ws-test" : "2.4.0.RELEASE", + "org.springframework.ws:spring-xml" : "2.4.0.RELEASE", + "org.testng:testng" : "6.10", + "org.threeten:threetenbp" : "1.3.3", + "org.thymeleaf:thymeleaf" : "2.1.5.RELEASE", + "org.thymeleaf:thymeleaf-spring4" : "2.1.5.RELEASE", + "org.thymeleaf.extras:thymeleaf-extras-conditionalcomments" : "2.1.2.RELEASE", + "org.thymeleaf.extras:thymeleaf-extras-java8time" : "2.1.0.RELEASE", + "org.thymeleaf.extras:thymeleaf-extras-springsecurity4" : "2.1.3.RELEASE", + "org.webjars:bootstrap" : "2.3.2", + "org.webjars:hal-browser" : "9f96c74", + "org.webjars:html5shiv" : "3.7.3", + "org.webjars:json-editor" : "0.7.21", + "org.webjars:knockout" : "2.3.0", + "org.webjars:sockjs-client" : "0.3.4", + "org.webjars:stomp-websocket" : "2.3.0", + "org.webjars:webjars-locator" : "0.32", + "org.webjars:webjars-taglib" : "0.3", + "org.xerial:sqlite-jdbc" : "3.15.1", + "org.xerial.snappy:snappy-java" : "1.1.2.6", + "org.xmlbeam:xmlprojector" : "1.4.9", + "org.yaml:snakeyaml" : "1.17", + "org.zeromq:jeromq" : "0.3.4", + "redis.clients:jedis" : "2.9.0", + "velocity-tools:velocity-tools-view" : "1.4", + "wsdl4j:wsdl4j" : "1.6.3", + "xml-apis:xml-apis" : "1.4.01", + "xmlunit:xmlunit" : "1.6", + "xom:xom" : "1.2.5", + "org.gebish:geb-spock" : "1.1.1", + "org.powermock:powermock-core" : "1.6.2", + "org.powermock:powermock-api-support" : "1.6.2", + "org.powermock:powermock-module-junit4-common" : "1.6.2", + "org.powermock:powermock-module-junit4" : "1.6.2", + "org.powermock:powermock-api-mockito" : "1.6.2", + "org.powermock:powermock-reflect" : "1.6.2" +] + +configurations.all { + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + def id = "${details.requested.group}:${details.requested.name}" + + if(deps[id]) { + details.useVersion deps[id] + } + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-attribute/build.gradle b/buildSrc/src/test/resources/samples/docs/missing-attribute/build.gradle new file mode 100644 index 0000000000..91d6d7e151 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-attribute/build.gradle @@ -0,0 +1,6 @@ +plugins { + id 'io.spring.convention.docs' + id 'java' +} + +version = '1.0.0.BUILD-SNAPSHOT' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-attribute/settings.gradle b/buildSrc/src/test/resources/samples/docs/missing-attribute/settings.gradle new file mode 100644 index 0000000000..7378d4a349 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-attribute/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'simple' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-attribute/src/docs/asciidoc/index.adoc b/buildSrc/src/test/resources/samples/docs/missing-attribute/src/docs/asciidoc/index.adoc new file mode 100644 index 0000000000..ba2fbbe84b --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-attribute/src/docs/asciidoc/index.adoc @@ -0,0 +1,3 @@ += Example Manual + +This will fail due to {missing} attribute \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-cross-reference/build.gradle b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/build.gradle new file mode 100644 index 0000000000..91d6d7e151 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/build.gradle @@ -0,0 +1,6 @@ +plugins { + id 'io.spring.convention.docs' + id 'java' +} + +version = '1.0.0.BUILD-SNAPSHOT' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-cross-reference/settings.gradle b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/settings.gradle new file mode 100644 index 0000000000..1731930901 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'missing-include' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-cross-reference/src/docs/asciidoc/index.adoc b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/src/docs/asciidoc/index.adoc new file mode 100644 index 0000000000..2a41dd8a8c --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-cross-reference/src/docs/asciidoc/index.adoc @@ -0,0 +1,3 @@ += Example Manual + +This will fail due to <> cross reference \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-include/build.gradle b/buildSrc/src/test/resources/samples/docs/missing-include/build.gradle new file mode 100644 index 0000000000..91d6d7e151 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-include/build.gradle @@ -0,0 +1,6 @@ +plugins { + id 'io.spring.convention.docs' + id 'java' +} + +version = '1.0.0.BUILD-SNAPSHOT' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-include/settings.gradle b/buildSrc/src/test/resources/samples/docs/missing-include/settings.gradle new file mode 100644 index 0000000000..1731930901 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-include/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'missing-include' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/missing-include/src/docs/asciidoc/index.adoc b/buildSrc/src/test/resources/samples/docs/missing-include/src/docs/asciidoc/index.adoc new file mode 100644 index 0000000000..ecf2133e9a --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/missing-include/src/docs/asciidoc/index.adoc @@ -0,0 +1,5 @@ += Example Manual + +This will fail due to missing include + +include::missing.adoc[] \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/simple/build.gradle b/buildSrc/src/test/resources/samples/docs/simple/build.gradle new file mode 100644 index 0000000000..9deefc7e1a --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/build.gradle @@ -0,0 +1,13 @@ +plugins { + id 'io.spring.convention.docs' + id 'java' +} + +version = '1.0.0.BUILD-SNAPSHOT' + +asciidoctorj { + attributes \ + 'build-gradle': project.buildFile, + 'sourcedir': project.sourceSets.main.java.srcDirs[0], + 'endpoint-url': 'https://example.org' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/simple/settings.gradle b/buildSrc/src/test/resources/samples/docs/simple/settings.gradle new file mode 100644 index 0000000000..7378d4a349 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'simple' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/docinfo.html b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/docinfo.html new file mode 100644 index 0000000000..f399886516 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/docinfo.html @@ -0,0 +1 @@ + diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/images/sunset.jpg b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/images/sunset.jpg new file mode 100644 index 0000000000..48c9129b30 Binary files /dev/null and b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/images/sunset.jpg differ diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/index.adoc b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/index.adoc new file mode 100644 index 0000000000..ea4087750a --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/index.adoc @@ -0,0 +1,60 @@ += Example Manual +Doc Writer +2014-09-09 +:example-caption!: +ifndef::imagesdir[:imagesdir: images] +ifndef::sourcedir[:sourcedir: ../java] + +This is a user manual for an example project. + +== Introduction + +This project does something. +We just haven't decided what that is yet. + +== Source Code + +[source,java] +.Java code from project +---- +include::{sourcedir}/example/StringUtils.java[tags=contains,indent=0] +---- + +This page was built by the following command: + + $ ./gradlew asciidoctor + +== Images + +[.thumb] +image::sunset.jpg[scaledwidth=75%] + +== Attributes + +.Built-in +asciidoctor-version:: {asciidoctor-version} +safe-mode-name:: {safe-mode-name} +docdir:: {docdir} +docfile:: {docfile} +imagesdir:: {imagesdir} +revnumber:: {revnumber} + +.Custom +sourcedir:: {sourcedir} +endpoint-url:: {endpoint-url} + +== Includes + +.include::subdir/_b.adoc[] +==== +include::subdir/_b.adoc[] +==== + +WARNING: Includes can be tricky! + +== build.gradle + +[source,groovy] +---- +include::{build-gradle}[] +---- diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_b.adoc b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_b.adoc new file mode 100644 index 0000000000..422eb5ee04 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_b.adoc @@ -0,0 +1,7 @@ +content from _src/docs/asciidoc/subdir/_b.adoc_. + +.include::_c.adoc[] +[example] +-- +include::_c.adoc[] +-- diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_c.adoc b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_c.adoc new file mode 100644 index 0000000000..3aca173636 --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/src/docs/asciidoc/subdir/_c.adoc @@ -0,0 +1 @@ +content from _src/docs/asciidoc/subdir/c.adoc_. diff --git a/buildSrc/src/test/resources/samples/docs/simple/src/main/java/example/StringUtils.java b/buildSrc/src/test/resources/samples/docs/simple/src/main/java/example/StringUtils.java new file mode 100644 index 0000000000..3884f862bb --- /dev/null +++ b/buildSrc/src/test/resources/samples/docs/simple/src/main/java/example/StringUtils.java @@ -0,0 +1,9 @@ +package example; + +public class StringUtils { + // tag::contains[] + public boolean contains(String haystack, String needle) { + return haystack.contains(needle); + } + // end::contains[] +} diff --git a/buildSrc/src/test/resources/samples/integrationtest/withgroovy/build.gradle b/buildSrc/src/test/resources/samples/integrationtest/withgroovy/build.gradle new file mode 100644 index 0000000000..d5dd692337 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withgroovy/build.gradle @@ -0,0 +1,16 @@ +plugins { + id 'io.spring.convention.integration-test' +} + +apply plugin: 'java' +apply plugin: 'groovy' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' + integrationTestCompile 'org.springframework:spring-core:4.3.7.RELEASE' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/integrationtest/withgroovy/src/integration-test/groovy/sample/TheTest.groovy b/buildSrc/src/test/resources/samples/integrationtest/withgroovy/src/integration-test/groovy/sample/TheTest.groovy new file mode 100644 index 0000000000..d3a9898b03 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withgroovy/src/integration-test/groovy/sample/TheTest.groovy @@ -0,0 +1,31 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package sample; + +import org.springframework.core.Ordered; +import spock.lang.Specification; + +class TheTest extends Specification { + def "has Ordered"() { + expect: 'Loads Ordered fine' + Ordered ordered = new Ordered() { + @Override + int getOrder() { + return 0 + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/integrationtest/withjava/build.gradle b/buildSrc/src/test/resources/samples/integrationtest/withjava/build.gradle new file mode 100644 index 0000000000..69fe9fa8f6 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withjava/build.gradle @@ -0,0 +1,14 @@ +plugins { + id 'io.spring.convention.integration-test' +} + +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + integrationTestCompile 'org.springframework:spring-core:4.3.7.RELEASE' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/integrationtest/withjava/src/integration-test/java/sample/TheTest.java b/buildSrc/src/test/resources/samples/integrationtest/withjava/src/integration-test/java/sample/TheTest.java new file mode 100644 index 0000000000..dc82588cc7 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withjava/src/integration-test/java/sample/TheTest.java @@ -0,0 +1,16 @@ +package sample; + +import org.junit.Test; +import org.springframework.core.Ordered; + +public class TheTest { + @Test + public void compilesAndRuns() { + Ordered ordered = new Ordered() { + @Override + public int getOrder() { + return 0; + } + }; + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/build.gradle b/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/build.gradle new file mode 100644 index 0000000000..af2027d522 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/build.gradle @@ -0,0 +1,15 @@ +plugins { + id 'io.spring.convention.integration-test' +} + +apply plugin: 'java' +apply plugin: 'propdeps' + +repositories { + mavenCentral() +} + +dependencies { + optional 'javax.servlet:javax.servlet-api:3.1.0' + testCompile 'junit:junit:4.12' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/src/integration-test/java/sample/TheTest.java b/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/src/integration-test/java/sample/TheTest.java new file mode 100644 index 0000000000..de492ca0e6 --- /dev/null +++ b/buildSrc/src/test/resources/samples/integrationtest/withpropdeps/src/integration-test/java/sample/TheTest.java @@ -0,0 +1,11 @@ +package sample; + +import org.junit.Test; +import javax.servlet.http.HttpServletRequest; + +public class TheTest { + @Test + public void compilesAndRuns() { + HttpServletRequest request = null; + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/jacoco/java/build.gradle b/buildSrc/src/test/resources/samples/jacoco/java/build.gradle new file mode 100644 index 0000000000..f70cc9a714 --- /dev/null +++ b/buildSrc/src/test/resources/samples/jacoco/java/build.gradle @@ -0,0 +1,13 @@ +plugins { + id 'io.spring.convention.jacoco' +} + +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/jacoco/java/src/main/java/sample/TheClass.java b/buildSrc/src/test/resources/samples/jacoco/java/src/main/java/sample/TheClass.java new file mode 100644 index 0000000000..cb7daa5001 --- /dev/null +++ b/buildSrc/src/test/resources/samples/jacoco/java/src/main/java/sample/TheClass.java @@ -0,0 +1,11 @@ +package sample; + +public class TheClass { + public boolean doStuff(boolean b) { + if(b) { + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/jacoco/java/src/test/java/sample/TheClassTest.java b/buildSrc/src/test/resources/samples/jacoco/java/src/test/java/sample/TheClassTest.java new file mode 100644 index 0000000000..5e1c64bbf6 --- /dev/null +++ b/buildSrc/src/test/resources/samples/jacoco/java/src/test/java/sample/TheClassTest.java @@ -0,0 +1,19 @@ +package sample; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class TheClassTest { + TheClass theClass = new TheClass(); + + @Test + public void doStuffWhenTrueThenTrue() { + assertTrue(theClass.doStuff(true)); + } + + @Test + public void doStuffWhenTrueThenFalse() { + assertFalse(theClass.doStuff(false)); + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/build.gradle b/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/build.gradle new file mode 100644 index 0000000000..f9887e0719 --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/build.gradle @@ -0,0 +1 @@ +apply plugin: 'io.spring.convention.spring-module' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/src/main/java/sample/Api.java b/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/src/main/java/sample/Api.java new file mode 100644 index 0000000000..7177b85bcc --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/api/src/main/java/sample/Api.java @@ -0,0 +1,14 @@ +package sample; + +/** + * Testing this + * @author Rob Winch + * + */ +public class Api { + + /** + * This does stuff + */ + public void doStuff() {} +} diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/build.gradle b/buildSrc/src/test/resources/samples/javadocapi/multimodule/build.gradle new file mode 100644 index 0000000000..203102f976 --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/build.gradle @@ -0,0 +1,5 @@ +plugins { + id 'io.spring.convention.javadoc-api' + id 'io.spring.convention.spring-module' apply false + id 'io.spring.convention.spring-sample' apply false +} diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/build.gradle b/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/build.gradle new file mode 100644 index 0000000000..f9887e0719 --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/build.gradle @@ -0,0 +1 @@ +apply plugin: 'io.spring.convention.spring-module' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/src/main/java/sample/Impl.java b/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/src/main/java/sample/Impl.java new file mode 100644 index 0000000000..bf906a54f2 --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/impl/src/main/java/sample/Impl.java @@ -0,0 +1,14 @@ +package sample; + +/** + * Testing this + * @author Rob Winch + * + */ +public class Impl { + + /** + * This does stuff + */ + public void otherThings() {} +} diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/build.gradle b/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/build.gradle new file mode 100644 index 0000000000..1bf7c89a4f --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/build.gradle @@ -0,0 +1 @@ +apply plugin: 'io.spring.convention.spring-sample' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/src/main/java/sample/Sample.java b/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/src/main/java/sample/Sample.java new file mode 100644 index 0000000000..51b7f3f92f --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/sample/src/main/java/sample/Sample.java @@ -0,0 +1,14 @@ +package sample; + +/** + * Testing this + * @author Rob Winch + * + */ +public class Sample { + + /** + * This does stuff + */ + public void doSample() {} +} diff --git a/buildSrc/src/test/resources/samples/javadocapi/multimodule/settings.gradle b/buildSrc/src/test/resources/samples/javadocapi/multimodule/settings.gradle new file mode 100644 index 0000000000..eb6441477e --- /dev/null +++ b/buildSrc/src/test/resources/samples/javadocapi/multimodule/settings.gradle @@ -0,0 +1,3 @@ +include ':api' +include ':impl' +include ':sample' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/install-with-springio/build.gradle b/buildSrc/src/test/resources/samples/maven/install-with-springio/build.gradle new file mode 100644 index 0000000000..b4784e4467 --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/install-with-springio/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'io.spring.convention.spring-module' +} + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + compile 'org.springframework:spring-core' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/install-with-springio/gradle/dependency-management.gradle b/buildSrc/src/test/resources/samples/maven/install-with-springio/gradle/dependency-management.gradle new file mode 100644 index 0000000000..3169bca25b --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/install-with-springio/gradle/dependency-management.gradle @@ -0,0 +1,5 @@ +dependencyManagement { + dependencies { + dependency 'org.springframework:spring-core:3.0.0.RELEASE' + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/install/build.gradle b/buildSrc/src/test/resources/samples/maven/install/build.gradle new file mode 100644 index 0000000000..c6cd7a97a7 --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/install/build.gradle @@ -0,0 +1,15 @@ +plugins { + id 'io.spring.convention.root' +} + +apply plugin: 'propdeps-maven' +apply plugin: 'io.spring.convention.maven' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + optional 'aopalliance:aopalliance:1.0' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/signing/build.gradle b/buildSrc/src/test/resources/samples/maven/signing/build.gradle new file mode 100644 index 0000000000..544f987f0e --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/signing/build.gradle @@ -0,0 +1,17 @@ +plugins { + id 'io.spring.convention.root' +} + +version = "1.0.0.RELEASE" + +apply plugin: 'propdeps-maven' +apply plugin: 'io.spring.convention.maven' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + optional 'aopalliance:aopalliance:1.0' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/signing/settings.gradle b/buildSrc/src/test/resources/samples/maven/signing/settings.gradle new file mode 100644 index 0000000000..cf2aed0bac --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/signing/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'signing' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/maven/upload/build.gradle b/buildSrc/src/test/resources/samples/maven/upload/build.gradle new file mode 100644 index 0000000000..549c0551c3 --- /dev/null +++ b/buildSrc/src/test/resources/samples/maven/upload/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'io.spring.convention.root' +} + +apply plugin: 'propdeps-maven' + +repositories { + mavenCentral() +} + +dependencies { + testCompile 'junit:junit:4.12' + optional 'aopalliance:aopalliance:1.0' +} + +uploadArchives { + repositories { + mavenDeployer { + repository(url: "file:$buildDir/repo") + } + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/Jenkinsfile b/buildSrc/src/test/resources/samples/showcase/Jenkinsfile new file mode 100644 index 0000000000..ad9bfeaf7d --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/Jenkinsfile @@ -0,0 +1,52 @@ +parallel check: { + stage('Check') { + node { + checkout scm + sh "./gradlew check --refresh-dependencies --no-daemon" + } + } +}, +sonar: { + stage('Sonar') { + node { + checkout scm + withCredentials([string(credentialsId: 'spring-sonar.login', variable: 'SONAR_LOGIN')]) { + sh "./gradlew sonarqube -Dsonar.host.url=$SPRING_SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN --refresh-dependencies --no-daemon" + } + } + } +}, +ossrh: { + stage('OSSRH Deploy') { + node { + checkout scm + withCredentials([file(credentialsId: 'spring-signing-secring.gpg', variable: 'SIGNING_KEYRING_FILE')]) { + withCredentials([string(credentialsId: 'spring-gpg-passphrase', variable: 'SIGNING_PASSWORD')]) { + withCredentials([usernamePassword(credentialsId: 'oss-token', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USERNAME')]) { + sh "./gradlew uploadArchives -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE -Psigning.keyId=$SPRING_SIGNING_KEYID -Psigning.password=$SIGNING_PASSWORD -PossrhUsername=$OSSRH_USERNAME -PossrhPassword=$OSSRH_PASSWORD --refresh-dependencies --no-daemon" + } + } + } + } + } +}, +docs: { + stage('Deploy Docs') { + node { + checkout scm + withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) { + sh "./gradlew deployDocs -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace" + } + } + } +}, +schema: { + stage('Deploy Schema') { + node { + checkout scm + withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) { + sh "./gradlew deploySchema -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME --refresh-dependencies --no-daemon --stacktrace" + } + } + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/bom/bom.gradle b/buildSrc/src/test/resources/samples/showcase/bom/bom.gradle new file mode 100644 index 0000000000..19aa720c82 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/bom/bom.gradle @@ -0,0 +1,2 @@ +apply plugin: 'io.spring.convention.bom' + diff --git a/buildSrc/src/test/resources/samples/showcase/build.gradle b/buildSrc/src/test/resources/samples/showcase/build.gradle new file mode 100644 index 0000000000..163e7b7428 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/build.gradle @@ -0,0 +1,6 @@ +plugins { + id 'io.spring.convention.root' +} + +group = "org.springframework.build.test" +version = "1.0.0.BUILD-SNAPSHOT" diff --git a/buildSrc/src/test/resources/samples/showcase/etc/checkstyle/checkstyle.xml b/buildSrc/src/test/resources/samples/showcase/etc/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..fbe98f2380 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/etc/checkstyle/checkstyle.xml @@ -0,0 +1,5 @@ + + + + diff --git a/buildSrc/src/test/resources/samples/showcase/gradle/dependency-management.gradle b/buildSrc/src/test/resources/samples/showcase/gradle/dependency-management.gradle new file mode 100644 index 0000000000..9c6c3ce038 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/gradle/dependency-management.gradle @@ -0,0 +1,3 @@ +dependencies { + management platform('io.spring.platform:platform-bom:Brussels-RELEASE') +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/build.gradle b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/build.gradle new file mode 100644 index 0000000000..6ef34f76a8 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/build.gradle @@ -0,0 +1,7 @@ +apply plugin: 'io.spring.convention.spring-sample-war' + +dependencies { + provided 'javax.servlet:javax.servlet-api' + testCompile 'commons-io:commons-io' + testCompile 'junit:junit' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/integration-test/java/sample/HelloServletTest.java b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/integration-test/java/sample/HelloServletTest.java new file mode 100644 index 0000000000..fad44d0c98 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/integration-test/java/sample/HelloServletTest.java @@ -0,0 +1,23 @@ +package sample; + +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +public class HelloServletTest { + + @Test + public void hello() throws Exception { + String url = System.getProperty("app.baseURI"); + try(InputStream get = new URL(url).openConnection().getInputStream()) { + String hello = IOUtils.toString(get, Charset.defaultCharset()); + assertEquals("Hello", hello); + } + + } +} diff --git a/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/main/java/sample/HelloServlet.java b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/main/java/sample/HelloServlet.java new file mode 100644 index 0000000000..8d74375dab --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/samples/sgbcs-sample-war/src/main/java/sample/HelloServlet.java @@ -0,0 +1,35 @@ +/* + * Copyright 2002-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sample; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/") +public class HelloServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.getWriter().write("Hello"); + } + + private static final long serialVersionUID = -166535360229360350L; +} diff --git a/buildSrc/src/test/resources/samples/showcase/settings.gradle b/buildSrc/src/test/resources/samples/showcase/settings.gradle new file mode 100644 index 0000000000..1997a84cc3 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/settings.gradle @@ -0,0 +1,23 @@ +rootProject.name = 'spring-gradle-build-conventions-sample' + + +FileTree projects = fileTree(rootDir) { + include '**/*.gradle' + exclude '**/gradle', 'settings.gradle', 'buildSrc', '/build.gradle', '.*' +} + +String rootDirPath = rootDir.absolutePath + File.separator +projects.each { File buildFile -> + String buildFilePath = buildFile.parentFile.absolutePath + + String projectPath = buildFilePath.replace(rootDirPath, '').replaceAll(File.separator, ':') + + include projectPath + + def project = findProject(":${projectPath}") + if(!'build.gradle'.equals(buildFile.name)) { + project.name = buildFile.name.replace('.gradle','') + project.buildFileName = buildFile.name + } + project.projectDir = buildFile.parentFile +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-api/sgbcs-api.gradle b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/sgbcs-api.gradle new file mode 100644 index 0000000000..8d0c2dab27 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/sgbcs-api.gradle @@ -0,0 +1,8 @@ +apply plugin: 'io.spring.convention.spring-module' + +dependencies { + compile 'org.springframework:spring-web' + compile 'org.springframework:spring-core' + testCompile 'junit:junit' +} + diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/main/java/api/Api.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/main/java/api/Api.java new file mode 100644 index 0000000000..6ed5b9c60f --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/main/java/api/Api.java @@ -0,0 +1,10 @@ +package api; + +/** + * + * @author Rob Winch + * + */ +public class Api { + +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/test/java/api/ApiTest.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/test/java/api/ApiTest.java new file mode 100644 index 0000000000..e1ede21b2c --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-api/src/test/java/api/ApiTest.java @@ -0,0 +1,9 @@ +package api; + +import org.junit.Test; + +public class ApiTest { + + @Test + public void api() {} +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/sgbcs-core.gradle b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/sgbcs-core.gradle new file mode 100644 index 0000000000..f4a73751bc --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/sgbcs-core.gradle @@ -0,0 +1,6 @@ +apply plugin: 'io.spring.convention.spring-module' + +dependencies { + optional 'ch.qos.logback:logback-classic' + testCompile 'junit:junit' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/CoreClass.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/CoreClass.java new file mode 100644 index 0000000000..4a0ecdb526 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/CoreClass.java @@ -0,0 +1,13 @@ +package core; + +/** + * + * @author Rob Winch + * + */ +public class CoreClass { + + public void run() { + + } +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/HasOptional.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/HasOptional.java new file mode 100644 index 0000000000..8d1ace3c7a --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/java/core/HasOptional.java @@ -0,0 +1,14 @@ +package core; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class HasOptional { + + public static void doStuffWithOptionalDependency() { + Logger logger = LoggerFactory.getLogger(HasOptional.class); + logger.debug("This is optional"); + } +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.handlers b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.handlers new file mode 100644 index 0000000000..6838fba461 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.handlers @@ -0,0 +1 @@ +http\://www.springframework.org/schema/springgradlebuildsample=org.springframework.ldap.config.LdapNamespaceHandler \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.schemas b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.schemas new file mode 100644 index 0000000000..84285717f5 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/META-INF/spring.schemas @@ -0,0 +1,4 @@ +http\://www.springframework.org/schema/springgradlebuildsample/spring-springgradlebuildsample.xsd=org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.2.xsd +http\://www.springframework.org/schema/springgradlebuildsample/spring-springgradlebuildsample-2.0.xsd=org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.0.xsd +http\://www.springframework.org/schema/springgradlebuildsample/spring-springgradlebuildsample-2.1.xsd=org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.1.xsd +http\://www.springframework.org/schema/springgradlebuildsample/spring-springgradlebuildsample-2.2.xsd=org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.2.xsd \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.0.xsd b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.0.xsd new file mode 100644 index 0000000000..327f3a59c8 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.0.xsd @@ -0,0 +1,468 @@ + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + "contextSource". + + + + + + + Defines whether read-only operations will be performed using an anonymous (unauthenticated) context. + + + + + + + Id of the AuthenticationSource instance to use. If not specified, a SimpleAuthenticationSource will + be used. + + + + + + + Id of the DirContextAuthenticationStrategy instance to use. If not specified, a SimpleDirContextAuthenticationStrategy + will be used. + + + + + + + The base DN. If configured, all LDAP operations on contexts retrieved from this ContextSource will + be relative to this DN. Default is an empty distinguished name (i.e. all operations will be + relative to the directory root). + + + + + + + The password to use for authentication. + + + + + + + Specify whether native Java LDAP connection pooling should be used. Default is false. + + + + + + + Defines the strategy to handle referrals, as described on https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/jndi.html. + Default is null. + + + + + + + + + + + + + + URL of the LDAP server to use. If fail-over functionality is desired, more than one URL can + be specified, separated using comma (,). + + + + + + + The username (principal) to use for authentication. This will normally be the distinguished name + of an admin user. + + + + + + + Reference to a Map of custom environment properties that should supplied with the environment + sent to the DirContext on construction. + + + + + + + + + + The maximum number of active connections of each type (read-only|read-write) + that can be allocated from the pool at the same time, or non-positive for no limit. + Default is 8. + + + + + + + The overall maximum number of active connections (for all types) that can be allocated from + this pool at the same time, or non-positive for no limit. Default is -1 (no limit). + + + + + + + The maximum number of active connections of each type (read-only|read-write) that can remain idle in the pool, + without extra ones being released, or non-positive for no limit. Default is 8. + + + + + + + The minimum number of active connections of each type (read-only|read-write) that can remain + idle in the pool, without extra ones being created, or zero to create none. Default is 0. + + + + + + + The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception, or non-positive to wait indefinitely. + Default is -1. + + + + + + + Specifies the behaviour when the pool is exhausted. + + + + + + + + Throw a NoSuchElementException when the pool is exhausted + + + + + + + Wait until a new object is available. If max-wait is positive a NoSuchElementException + is thrown if no new object is available after the maxWait time expires. + + + + + + + Create and return a new object (essentially making maxActive meaningless). + + + + + + + + + + The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and an attempt to borrow another will be made. + Default is false. + + + + + + + The indication of whether objects will be validated before being returned to the pool. + Default is false. + + + + + + + The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + Default is false. + + + + + + + The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, + no idle object evictor thread will be run. Default is -1. + + + + + + + The number of objects to examine during each run of the idle object evictor thread (if any). + Default is 3. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible + for eviction by the idle object evictor (if any). Default is 1000 * 60 * 30. + + + + + + + The base dn to use for validation searches. Default is LdapUtils.emptyPath(). + + + + + + + The filter to use for validation queries. Default is (objectclass=*). + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + + + Creates a ContextSource instance to be used to get LdapContexts for communicating with an LDAP server. + + + + + + + + Defines the settings to use for the Spring LDAP connection pooling support. + + + + + + + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + Default is "ldapTemplate". + + + + + + + Id of the ContextSource instance to use. Default is "contextSource". + + + + + + + The default count limit for searches. Default is 0 (no limit). + + + + + + + The default time limit for searches. Default is 0 (no limit). + + + + + + + The default search scope for searches. Default is SUBTREE. + + + + + + + + + + + + + + Specifies whether NameNotFoundException should be ignored in searches. Setting this + attribute to true will cause errors caused by invalid search base to be silently swallowed. + Default is false. + + + + + + + Specifies whether PartialResultException should be ignored in searches. Some LDAP servers + have problems with referrals; these should normally be followed automatically, but if this + doesn't work it will manifest itself with a PartialResultException. Setting this attribute + to true presents a work-around to this problem. Default is false. + + + + + + + Id of the ObjectDirectoryMapper instance to use. Default is a default-configured DefaultObjectDirectoryMapper. + + + + + + + + + Creates an LdapTemplate instance. + + + + + + + + + + + + Id of this instance. Default is "transactionManager". + + + + + + + Id of the ContextSource instance to use. "contextSource". + + + + + + + Id of the DataSource instance to use. + + + + + + + Id of the Hibernate SessionFactory instance to use. + + + + + + + + + Creates an ContextSourceTransactionManager. If data-source-ref or session-factory-ref is specified, + a DataSourceAndContextSourceTransactionManager/HibernateAndContextSourceTransactionManager will be + created. + + + + + + + + The default (simplistic) TempEntryRenamingStrategy. Please note that this + strategy will not work for more advanced scenarios. See reference documentation + for details. + + + + + + + The default suffix that will be added to modified entries. + Default is "_temp". + + + + + + + + + TempEntryRenamingStrategy that moves the entry to a different subtree than + the original entry. + + + + + + + The subtree base where changed entries should be moved. + + + + + + + + + + + + + + + + + + The reference to an LdapTemplate. Will default to 'ldapTemplate'. + + + + + + + + \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.1.xsd b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.1.xsd new file mode 100644 index 0000000000..3b5e71988b --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.1.xsd @@ -0,0 +1,685 @@ + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + "contextSource". + + + + + + + Defines whether read-only operations will be performed using an anonymous (unauthenticated) context. + + + + + + + Id of the AuthenticationSource instance to use. If not specified, a SimpleAuthenticationSource will + be used. + + + + + + + Id of the DirContextAuthenticationStrategy instance to use. If not specified, a SimpleDirContextAuthenticationStrategy + will be used. + + + + + + + The base DN. If configured, all LDAP operations on contexts retrieved from this ContextSource will + be relative to this DN. Default is an empty distinguished name (i.e. all operations will be + relative to the directory root). + + + + + + + The password to use for authentication. + + + + + + + Specify whether native Java LDAP connection pooling should be used. Default is false. + + + + + + + Defines the strategy to handle referrals, as described on https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/jndi.html. + Default is null. + + + + + + + + + + + + + + URL of the LDAP server to use. If fail-over functionality is desired, more than one URL can + be specified, separated using comma (,). + + + + + + + The username (principal) to use for authentication. This will normally be the distinguished name + of an admin user. + + + + + + + Reference to a Map of custom environment properties that should supplied with the environment + sent to the DirContext on construction. + + + + + + + + + + The maximum number of active connections of each type (read-only|read-write) + that can be allocated from the pool at the same time, or non-positive for no limit. + Default is 8. + + + + + + + The overall maximum number of active connections (for all types) that can be allocated from + this pool at the same time, or non-positive for no limit. Default is -1 (no limit). + + + + + + + The maximum number of active connections of each type (read-only|read-write) that can remain idle in the pool, + without extra ones being released, or non-positive for no limit. Default is 8. + + + + + + + The minimum number of active connections of each type (read-only|read-write) that can remain + idle in the pool, without extra ones being created, or zero to create none. Default is 0. + + + + + + + The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception, or non-positive to wait indefinitely. + Default is -1. + + + + + + + Specifies the behaviour when the pool is exhausted. + + + + + + + + Throw a NoSuchElementException when the pool is exhausted + + + + + + + Wait until a new object is available. If max-wait is positive a NoSuchElementException + is thrown if no new object is available after the maxWait time expires. + + + + + + + Create and return a new object (essentially making maxActive meaningless). + + + + + + + + + + The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and an attempt to borrow another will be made. + Default is false. + + + + + + + The indication of whether objects will be validated before being returned to the pool. + Default is false. + + + + + + + The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + Default is false. + + + + + + + The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, + no idle object evictor thread will be run. Default is -1. + + + + + + + The number of objects to examine during each run of the idle object evictor thread (if any). + Default is 3. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible + for eviction by the idle object evictor (if any). Default is 1000 * 60 * 30. + + + + + + + The base dn to use for validation searches. Default is LdapUtils.emptyPath(). + + + + + + + The filter to use for validation queries. Default is (objectclass=*). + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + + + + The overall maximum number of active connections (for all types) that can be allocated from + this pool at the same time, or non-positive for no limit. Default is -1 (no limit). + + + + + + + The limit on the number of object instances allocated by the pool (checked out or idle), + per key. When the limit is reached, the sub-pool is said to be exhausted. A negative value + indicates no limit. Default is 8. + + + + + + + The maximum number of active connections per type (read-only|read-write) that can remain idle in the pool, + without extra ones being released, or non-positive for no limit. Default is 8. + + + + + + + The minimum number of active connections per type (read-only|read-write) that can remain + idle in the pool, without extra ones being created, or zero to create none. Default is 0. + + + + + + + The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception, or non-positive to wait indefinitely. + Default is -1. + + + + + + + Sets to wait until a new object is available. If max-wait is positive a NoSuchElementException + is thrown if no new object is available after the maxWait time expires.. + + + + + + + Sets whether objects created for the pool will be validated before borrowing. If the object + fails to validate, then borrowing will fail. Default is false. + + + + + + + The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and an attempt to borrow another will be made. + Default is false. + + + + + + + The indication of whether objects will be validated before being returned to the pool. + Default is false. + + + + + + + The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + Default is false. + + + + + + + The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, + no idle object evictor thread will be run. Default is -1. + + + + + + + The number of objects to examine during each run of the idle object evictor thread (if any). + Default is 3. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible + for eviction by the idle object evictor (if any). Default is 1000 * 60 * 30. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible for + eviction by the idle object evictor, with the extra condition that at least minimum number + of object instances per key remain in the pool. This settings is overridden by min-evictable-time-millis if + it is set to a positive value. Default is -1. + + + + + + + The name of the eviction policy implementation that is used by this pool. The Pool will + attempt to load the class using the thread context class loader. If that fails, the Pool + will attempt to load the class using the class loader that loaded this class. Default is + org.apache.commons.pool2.impl.DefaultEvictionPolicy. + + + + + + + Sets whether or not the pool serves threads waiting to borrow connections fairly. + True means that waiting threads are served as if waiting in a FIFO queue. Default is false. + + + + + + + Sets whether JMX will be enabled with the platform MBean server for the pool. Default + is true. + + + + + + + The value of the JMX name base that will be used as part of the name assigned + to JMX enabled pools. Default is null. + + + + + + + The value of the JMX name prefix that will be used as part of the name assigned + to JMX enabled pools. Default value is pool. + + + + + + + Sets whether the pool has LIFO (last in, first out) behaviour with + respect to idle objects - always returning the most recently used object + from the pool, or as a FIFO (first in, first out) queue, where the pool + always returns the oldest object in the idle object pool. Default is true. + + + + + + + The base dn to use for validation searches. Default is LdapUtils.emptyPath(). + + + + + + + The filter to use for validation queries. Default is (objectclass=*). + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + + + Creates a ContextSource instance to be used to get LdapContexts for communicating with an LDAP server. + + + + + + + + + Defines the settings to use for the Spring LDAP connection pooling support. + + + + + + + + + + + + Defines the settings to use for the Spring LDAP connection pooling support based on commons-pool2 library. + + + + + + + + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + Default is "ldapTemplate". + + + + + + + Id of the ContextSource instance to use. Default is "contextSource". + + + + + + + The default count limit for searches. Default is 0 (no limit). + + + + + + + The default time limit for searches. Default is 0 (no limit). + + + + + + + The default search scope for searches. Default is SUBTREE. + + + + + + + + + + + + + + Specifies whether NameNotFoundException should be ignored in searches. Setting this + attribute to true will cause errors caused by invalid search base to be silently swallowed. + Default is false. + + + + + + + Specifies whether PartialResultException should be ignored in searches. Some LDAP servers + have problems with referrals; these should normally be followed automatically, but if this + doesn't work it will manifest itself with a PartialResultException. Setting this attribute + to true presents a work-around to this problem. Default is false. + + + + + + + Id of the ObjectDirectoryMapper instance to use. Default is a default-configured DefaultObjectDirectoryMapper. + + + + + + + + + Creates an LdapTemplate instance. + + + + + + + + + + + + Id of this instance. Default is "transactionManager". + + + + + + + Id of the ContextSource instance to use. "contextSource". + + + + + + + Id of the DataSource instance to use. + + + + + + + Id of the Hibernate SessionFactory instance to use. + + + + + + + + + Creates an ContextSourceTransactionManager. If data-source-ref or session-factory-ref is specified, + a DataSourceAndContextSourceTransactionManager/HibernateAndContextSourceTransactionManager will be + created. + + + + + + + + The default (simplistic) TempEntryRenamingStrategy. Please note that this + strategy will not work for more advanced scenarios. See reference documentation + for details. + + + + + + + The default suffix that will be added to modified entries. + Default is "_temp". + + + + + + + + + TempEntryRenamingStrategy that moves the entry to a different subtree than + the original entry. + + + + + + + The subtree base where changed entries should be moved. + + + + + + + + + + + + + + + + + + The reference to an LdapTemplate. Will default to 'ldapTemplate'. + + + + + + + + diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.2.xsd b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.2.xsd new file mode 100644 index 0000000000..e76d784674 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/main/resources/org/springframework/springgradlebuildsample/config/spring-springgradlebuildsample-2.2.xsd @@ -0,0 +1,685 @@ + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + "contextSource". + + + + + + + Defines whether read-only operations will be performed using an anonymous (unauthenticated) context. + + + + + + + Id of the AuthenticationSource instance to use. If not specified, a SimpleAuthenticationSource will + be used. + + + + + + + Id of the DirContextAuthenticationStrategy instance to use. If not specified, a SimpleDirContextAuthenticationStrategy + will be used. + + + + + + + The base DN. If configured, all LDAP operations on contexts retrieved from this ContextSource will + be relative to this DN. Default is an empty distinguished name (i.e. all operations will be + relative to the directory root). + + + + + + + The password to use for authentication. + + + + + + + Specify whether native Java LDAP connection pooling should be used. Default is false. + + + + + + + Defines the strategy to handle referrals, as described on https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/jndi.html. + Default is null. + + + + + + + + + + + + + + URL of the LDAP server to use. If fail-over functionality is desired, more than one URL can + be specified, separated using comma (,). + + + + + + + The username (principal) to use for authentication. This will normally be the distinguished name + of an admin user. + + + + + + + Reference to a Map of custom environment properties that should supplied with the environment + sent to the DirContext on construction. + + + + + + + + + + The maximum number of active connections of each type (read-only|read-write) + that can be allocated from the pool at the same time, or non-positive for no limit. + Default is 8. + + + + + + + The overall maximum number of active connections (for all types) that can be allocated from + this pool at the same time, or non-positive for no limit. Default is -1 (no limit). + + + + + + + The maximum number of active connections of each type (read-only|read-write) that can remain idle in the pool, + without extra ones being released, or non-positive for no limit. Default is 8. + + + + + + + The minimum number of active connections of each type (read-only|read-write) that can remain + idle in the pool, without extra ones being created, or zero to create none. Default is 0. + + + + + + + The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception, or non-positive to wait indefinitely. + Default is -1. + + + + + + + Specifies the behaviour when the pool is exhausted. + + + + + + + + Throw a NoSuchElementException when the pool is exhausted + + + + + + + Wait until a new object is available. If max-wait is positive a NoSuchElementException + is thrown if no new object is available after the maxWait time expires. + + + + + + + Create and return a new object (essentially making maxActive meaningless). + + + + + + + + + + The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and an attempt to borrow another will be made. + Default is false. + + + + + + + The indication of whether objects will be validated before being returned to the pool. + Default is false. + + + + + + + The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + Default is false. + + + + + + + The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, + no idle object evictor thread will be run. Default is -1. + + + + + + + The number of objects to examine during each run of the idle object evictor thread (if any). + Default is 3. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible + for eviction by the idle object evictor (if any). Default is 1000 * 60 * 30. + + + + + + + The base dn to use for validation searches. Default is LdapUtils.emptyPath(). + + + + + + + The filter to use for validation queries. Default is (objectclass=*). + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + + + + The overall maximum number of active connections (for all types) that can be allocated from + this pool at the same time, or non-positive for no limit. Default is -1 (no limit). + + + + + + + The limit on the number of object instances allocated by the pool (checked out or idle), + per key. When the limit is reached, the sub-pool is said to be exhausted. A negative value + indicates no limit. Default is 8. + + + + + + + The maximum number of active connections per type (read-only|read-write) that can remain idle in the pool, + without extra ones being released, or non-positive for no limit. Default is 8. + + + + + + + The minimum number of active connections per type (read-only|read-write) that can remain + idle in the pool, without extra ones being created, or zero to create none. Default is 0. + + + + + + + The maximum number of milliseconds that the pool will wait (when there are no available connections) + for a connection to be returned before throwing an exception, or non-positive to wait indefinitely. + Default is -1. + + + + + + + Sets to wait until a new object is available. If max-wait is positive a NoSuchElementException + is thrown if no new object is available after the maxWait time expires. Default is true. + + + + + + + Sets whether objects created for the pool will be validated before borrowing. If the object + fails to validate, then borrowing will fail. Default is false. + + + + + + + The indication of whether objects will be validated before being borrowed from the pool. + If the object fails to validate, it will be dropped from the pool, and an attempt to borrow another will be made. + Default is false. + + + + + + + The indication of whether objects will be validated before being returned to the pool. + Default is false. + + + + + + + The indication of whether objects will be validated by the idle object evictor (if any). + If an object fails to validate, it will be dropped from the pool. + Default is false. + + + + + + + The number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, + no idle object evictor thread will be run. Default is -1. + + + + + + + The number of objects to examine during each run of the idle object evictor thread (if any). + Default is 3. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible + for eviction by the idle object evictor (if any). Default is 1000 * 60 * 30. + + + + + + + The minimum amount of time an object may sit idle in the pool before it is eligible for + eviction by the idle object evictor, with the extra condition that at least minimum number + of object instances per key remain in the pool. This settings is overridden by min-evictable-time-millis if + it is set to a positive value. Default is -1. + + + + + + + The name of the eviction policy implementation that is used by this pool. The Pool will + attempt to load the class using the thread context class loader. If that fails, the Pool + will attempt to load the class using the class loader that loaded this class. Default is + org.apache.commons.pool2.impl.DefaultEvictionPolicy. + + + + + + + Sets whether or not the pool serves threads waiting to borrow connections fairly. + True means that waiting threads are served as if waiting in a FIFO queue. Default is false. + + + + + + + Sets whether JMX will be enabled with the platform MBean server for the pool. Default + is true. + + + + + + + The value of the JMX name base that will be used as part of the name assigned + to JMX enabled pools. Default is null. + + + + + + + The value of the JMX name prefix that will be used as part of the name assigned + to JMX enabled pools. Default value is pool. + + + + + + + Sets whether the pool has LIFO (last in, first out) behaviour with + respect to idle objects - always returning the most recently used object + from the pool, or as a FIFO (first in, first out) queue, where the pool + always returns the oldest object in the idle object pool. Default is true. + + + + + + + The base dn to use for validation searches. Default is LdapUtils.emptyPath(). + + + + + + + The filter to use for validation queries. Default is (objectclass=*). + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + Id of the SearchControls instance to use for searches. Default is searchScope=OBJECT_SCOPE; + countLimit: 1; timeLimit: 500; returningAttributes: [objectclass]. + + + + + + + + + Creates a ContextSource instance to be used to get LdapContexts for communicating with an LDAP server. + + + + + + + + + Defines the settings to use for the Spring LDAP connection pooling support. + + + + + + + + + + + + Defines the settings to use for the Spring LDAP connection pooling support based on commons-pool2 library. + + + + + + + + + + + + + + + + + A bean identifier, used for referring to the bean elsewhere in the context. + Default is "ldapTemplate". + + + + + + + Id of the ContextSource instance to use. Default is "contextSource". + + + + + + + The default count limit for searches. Default is 0 (no limit). + + + + + + + The default time limit for searches. Default is 0 (no limit). + + + + + + + The default search scope for searches. Default is SUBTREE. + + + + + + + + + + + + + + Specifies whether NameNotFoundException should be ignored in searches. Setting this + attribute to true will cause errors caused by invalid search base to be silently swallowed. + Default is false. + + + + + + + Specifies whether PartialResultException should be ignored in searches. Some LDAP servers + have problems with referrals; these should normally be followed automatically, but if this + doesn't work it will manifest itself with a PartialResultException. Setting this attribute + to true presents a work-around to this problem. Default is false. + + + + + + + Id of the ObjectDirectoryMapper instance to use. Default is a default-configured DefaultObjectDirectoryMapper. + + + + + + + + + Creates an LdapTemplate instance. + + + + + + + + + + + + Id of this instance. Default is "transactionManager". + + + + + + + Id of the ContextSource instance to use. "contextSource". + + + + + + + Id of the DataSource instance to use. + + + + + + + Id of the Hibernate SessionFactory instance to use. + + + + + + + + + Creates an ContextSourceTransactionManager. If data-source-ref or session-factory-ref is specified, + a DataSourceAndContextSourceTransactionManager/HibernateAndContextSourceTransactionManager will be + created. + + + + + + + + The default (simplistic) TempEntryRenamingStrategy. Please note that this + strategy will not work for more advanced scenarios. See reference documentation + for details. + + + + + + + The default suffix that will be added to modified entries. + Default is "_temp". + + + + + + + + + TempEntryRenamingStrategy that moves the entry to a different subtree than + the original entry. + + + + + + + The subtree base where changed entries should be moved. + + + + + + + + + + + + + + + + + + The reference to an LdapTemplate. Will default to 'ldapTemplate'. + + + + + + + + diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/CoreClassTest.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/CoreClassTest.java new file mode 100644 index 0000000000..3ec9b922d7 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/CoreClassTest.java @@ -0,0 +1,12 @@ +package core; + +import org.junit.Test; + +public class CoreClassTest { + + @Test + public void test() { + new CoreClass().run(); + } + +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/HasOptionalTest.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/HasOptionalTest.java new file mode 100644 index 0000000000..bded2c97af --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-core/src/test/java/core/HasOptionalTest.java @@ -0,0 +1,12 @@ +package core; + +import org.junit.Test; + +public class HasOptionalTest { + + @Test + public void test() { + HasOptional.doStuffWithOptionalDependency(); + } + +} diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/sgbcs-docs.gradle b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/sgbcs-docs.gradle new file mode 100644 index 0000000000..f3d52b8c1f --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/sgbcs-docs.gradle @@ -0,0 +1,11 @@ +apply plugin: 'java' +apply plugin: 'io.spring.convention.docs' + +version = "1.0.0.BUILD-SNAPSHOT" + +asciidoctorj { + attributes \ + 'build-gradle': project.buildFile, + 'sourcedir': project.sourceSets.main.java.srcDirs[0], + 'endpoint-url': 'https://example.org' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/docinfo.html b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/docinfo.html new file mode 100644 index 0000000000..f399886516 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/docinfo.html @@ -0,0 +1 @@ + diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/images/sunset.jpg b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/images/sunset.jpg new file mode 100644 index 0000000000..48c9129b30 Binary files /dev/null and b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/images/sunset.jpg differ diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/index.adoc b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/index.adoc new file mode 100644 index 0000000000..ea4087750a --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/index.adoc @@ -0,0 +1,60 @@ += Example Manual +Doc Writer +2014-09-09 +:example-caption!: +ifndef::imagesdir[:imagesdir: images] +ifndef::sourcedir[:sourcedir: ../java] + +This is a user manual for an example project. + +== Introduction + +This project does something. +We just haven't decided what that is yet. + +== Source Code + +[source,java] +.Java code from project +---- +include::{sourcedir}/example/StringUtils.java[tags=contains,indent=0] +---- + +This page was built by the following command: + + $ ./gradlew asciidoctor + +== Images + +[.thumb] +image::sunset.jpg[scaledwidth=75%] + +== Attributes + +.Built-in +asciidoctor-version:: {asciidoctor-version} +safe-mode-name:: {safe-mode-name} +docdir:: {docdir} +docfile:: {docfile} +imagesdir:: {imagesdir} +revnumber:: {revnumber} + +.Custom +sourcedir:: {sourcedir} +endpoint-url:: {endpoint-url} + +== Includes + +.include::subdir/_b.adoc[] +==== +include::subdir/_b.adoc[] +==== + +WARNING: Includes can be tricky! + +== build.gradle + +[source,groovy] +---- +include::{build-gradle}[] +---- diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_b.adoc b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_b.adoc new file mode 100644 index 0000000000..422eb5ee04 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_b.adoc @@ -0,0 +1,7 @@ +content from _src/docs/asciidoc/subdir/_b.adoc_. + +.include::_c.adoc[] +[example] +-- +include::_c.adoc[] +-- diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_c.adoc b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_c.adoc new file mode 100644 index 0000000000..3aca173636 --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/docs/asciidoc/subdir/_c.adoc @@ -0,0 +1 @@ +content from _src/docs/asciidoc/subdir/c.adoc_. diff --git a/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/main/java/example/StringUtils.java b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/main/java/example/StringUtils.java new file mode 100644 index 0000000000..3884f862bb --- /dev/null +++ b/buildSrc/src/test/resources/samples/showcase/sgbcs-docs/src/main/java/example/StringUtils.java @@ -0,0 +1,9 @@ +package example; + +public class StringUtils { + // tag::contains[] + public boolean contains(String haystack, String needle) { + return haystack.contains(needle); + } + // end::contains[] +} diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/build.gradle b/buildSrc/src/test/resources/samples/testsconfiguration/build.gradle new file mode 100644 index 0000000000..364b3bd00c --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/build.gradle @@ -0,0 +1,4 @@ +plugins { + id 'io.spring.convention.tests-configuration' + id 'java' +} diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/core/build.gradle b/buildSrc/src/test/resources/samples/testsconfiguration/core/build.gradle new file mode 100644 index 0000000000..3cad4d41a1 --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/core/build.gradle @@ -0,0 +1,2 @@ +apply plugin: 'io.spring.convention.tests-configuration' +apply plugin: 'java' // second to test ordering diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/core/src/test/java/sample/Dependency.java b/buildSrc/src/test/resources/samples/testsconfiguration/core/src/test/java/sample/Dependency.java new file mode 100644 index 0000000000..e0dcbbe402 --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/core/src/test/java/sample/Dependency.java @@ -0,0 +1,3 @@ +package sample; + +public class Dependency {} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/settings.gradle b/buildSrc/src/test/resources/samples/testsconfiguration/settings.gradle new file mode 100644 index 0000000000..eadf90b294 --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/settings.gradle @@ -0,0 +1,2 @@ +include ':core' +include ':web' \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/web/build.gradle b/buildSrc/src/test/resources/samples/testsconfiguration/web/build.gradle new file mode 100644 index 0000000000..44d134d9b4 --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/web/build.gradle @@ -0,0 +1,10 @@ +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + testCompile project(path: ':core', configuration: 'tests') + testCompile 'junit:junit:4.12' +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/samples/testsconfiguration/web/src/test/java/sample/DependencyTest.java b/buildSrc/src/test/resources/samples/testsconfiguration/web/src/test/java/sample/DependencyTest.java new file mode 100644 index 0000000000..8c37864320 --- /dev/null +++ b/buildSrc/src/test/resources/samples/testsconfiguration/web/src/test/java/sample/DependencyTest.java @@ -0,0 +1,10 @@ +package sample; + +import org.junit.*; + +public class DependencyTest { + @Test + public void findsDependencyOnClasspath() { + new Dependency(); + } +} \ No newline at end of file diff --git a/buildSrc/src/test/resources/test-private.pgp b/buildSrc/src/test/resources/test-private.pgp new file mode 100644 index 0000000000..b56a134d67 --- /dev/null +++ b/buildSrc/src/test/resources/test-private.pgp @@ -0,0 +1,83 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQWGBF7sxWEBDADekNzn2KDfbb8QGPTHZLzqvNgfYVGXIWLFfEWsA0wTPn3YQh78 +vhsK+nq598R5Rjt2s4lm/L8y5eQ4GWpok9wu5gna4s+nHbdwDjJKoXA/GVN8Y/oi +g37CafIqWACdzGpN5fjvblsfrNjVmwLdgq2kYoYqduOtiFeeQDivRJdZp3417e3C +xAdarksMkWOuDKD7JQU46ofxoMX5+WsvZ0DYuKybXAiVhNTpn3rl/4MIvu6XlMBS +EdLCdQkrdiSs6dBt8iQWkSDmwl4qaFyOmtlwjtzpJ+mPYpTWWWN3ukBRCM/AJRqm +IgLXnYnrvTmEmuZwfcZrLGwPDa30aaCK5Jjq4WLD1lwpFBuZMT46saLA+y8CvcSW +8vPAvQFzSrbBaEGu4ZIpU2aWBRW4JYpN+l90RFoWfdPyxrQ4rmPp4BIoEG25+zxI +8XMJNwr4T/t8C4I6YQfCKqnyeeR94ZF8JjGJh3Ts6nLHDN84IZbeJRypvYpcTPAD +HZiWnk4QREuSyhEAEQEAAf4HAwLsRiB8Oo4Nef+LrgBEtQ86fdfs5mTbxPv+XNGb +Wugl7HtIbgjhcmDw1zaWt9B7PKhSn2FQwJQduijE/Ae7OmNkFBQoeUeN0QADlarA +Xb5dlANIbfEJk/9KR769YL9HTy6y25LxrfgH3mrV2848dA/ilgv/WGmAz0SGER1t +OKvgOfGrmQECKbw7+U9EyEPl7nWRgJrkRK8/zgMnAA1TuXG3Rr3FvuUlw51MnBxx +sYOj6A7Xk0ijvh1szMwcUwVtZWDAiRFVhMcgopf7jCKs1UlrWJ98sa7WNXje25Mo +WXZ8VRA1/FbM/ifzuICOmKc7C+rNff7H3U7PBwRCGJrG6m0EJ/Cwrko5uHVq+fG5 +s2Vl7817ztM3/rkmNkC9jmE/sKHlkPlVc9hZGPTbqBC6BThpbBzNLUoTPmAgzbqU +hgW2ES938D7ipt7IzhRxTitQN8a1JRk8v710g/D2skLhTx9T3SkJyJkXbmOVJJXc +IN/mtlzRykR/c/TGOsMQR6v+nz42jZ1AY406AKMjd1R15wamscg4d457qVxn89T0 +wne+eShON8vPNpu1bAaN8soHxC5a4eVnLNVguxs+Abc0x/qwpwvd0VOMd86Aukte +YsS+fzGSSpX9PqHVNThK9Z1dU13J7RONeO+2xZnThhiMyGvpqL5PQ3lE3P4zkccB +jlQuuHW/6jD0/W1tlPPcsTcWDS4Ku7xxXg+ZSR3LfC4ukBWQLGiYNBWA2Zi1zW0A +xXB9kdP9MJcxdBlsUa+xVrI71LcWaREGA/O5KGMmTXQaJJNvp/2bCauAIE8AJEN9 +MrGLe+SBu3n0PJxpCB3iqLXNe9nebf0I4E8uisKB6zcQMFMEWxI5R3oRweVKYIBo +8Le5tlJ9DSwvwTI0tyDMW7Y9KCrAcIpz7tx0cIn4RzMGzCtDaLpwDk973jUQcFeE +OQBLCWPm2pIuoKO4RkIHaqhYXc9SYG3E+qQ481DohAoB/Gr3Vf80wQyIGAorg4wM +OhYmFp5pl8XDDpa7Sth8w/0flA08IRA466IYaBAhuP0ug+rhMjNfLwy+anurUd9f +M3UD21WqIUEscN5SkPI2OhGCXf5rbAQ+PkyrbgHXZpW29fGeUrAEP7FBWnCxylvL +ijP/camoJLlOzr5CKi1TTkhitbfSMH1jQosw6JeiHtbnvCyrqNbPYw57gkpRH4FD +Iql0TGAiHRe8l4s0xW79oiqN6vWKICCkekwcuc3NdNFsyxjtPdWI3ni0FulkHX0Y +O+R0Ge+uwoPKiwCT6POzn1sPP6q8kbcvP0QmkNAx7b/JKRPEoe4u9oUNc5qS9gEC +GxzvbXqq7Zv7UmYcTfNSjEWluIy0SYkVB7QkU3ByaW5nICh0ZXN0aW5nKSA8bm9y +ZXBseUBzcHJpbmcuaW8+iQHOBBMBCgA4FiEEkkystQ8WdKVRsEMQjGaXsjMvWqAF +Al7sxWECGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQjGaXsjMvWqCNTAwA +pg4/XCj0vqdeVNepw4p4mU/62yu2pKXh5usU2BcEvD8dEidUpGRJkyt5n1vWzvC6 +8pbmn+Qa/6QKyL300RHeb3lpKQXbrtx3WWAMIO/JXh5lLtNaytw/N1IpqIVpg85G +L27sjeGwInQ4MleLzKykxygIsqZYUE3KWCb75JmgtEQiyaivAmDxlFClaav35LQp +aAyX2jrRPxPcD3qEL8JwDRpIlYwi1rcJgun9HIPAdma4AIarBBlEmEcXUus4rNAl +5vVgzB+v6dH3V+TiBL2QpepSoj4snA0iVyxGmLhhuuLf5gdb5sQgBY+BVxmqEji/ +is9/Steis5d25JG5G2qaflv5H00aZBJeCsARKkhBMKqBILHAAkBdr611gGLcHusq +T4GdhYx4BJK1mHjgY08pDV+My4xnwz1wcsS3iAl7efCu8X2lfe9ju+sV1EhXAtj0 +XAIaHz1k8bN4dPZDZG8Lk+2kH6WDLr7EOIsJCCsBp4HUFrxUUEdYaUsNDFxKxmmA +nQWGBF7sxWEBDADRHc69S/XH4yDv7Msg7OWW2eEBKkFV7i6lMHCp+lNBqNtxx83Z +ww8BRzqJZqvPRw219hwsVw7XN9YB1c8k5bw14mPx/VMK84oChPKRF58K9Ak8hyV5 +3BSrd4N+DKPYut0l+WhHTfkPIguFGeHp8Kg/GphAlK2eieE8vzrwrUZdNqWCBbuF ++JqU84g9XIMUtfPSIwbnaRh6DkU59cbEaHYl4ltr5+ZExhHypMKt4G0sJu3Vo1iq +nA4NiB1rUwzsvB5NUvTErLDKHscdeKSfbf7VeMe/Oqaa5EHWQuDVWBMDhyqRt4bV +kdHnHogjtNT8Ose2eYgqY+8rzJ1vs84DUuo6Osd/ATc0K6jodZpueYN1NQEP9l2s +VsjJzT4rFb6RUglnEyp4LANrz4ogkx9Y9wnvti0Z3vtLQyAf/DmXBKXzos5lRLBw +Ju+zqUUe6fww11LaftKdSI9yzhAP2ZnZFZ1FtVvuypLBrhZVsiYyRnDN6XhPxJgq +2A6yIoTNaq/xIA0AEQEAAf4HAwJBDiLQbcpQ8v9Dq9OdYRBZQxhMbhpVB45r8BeR +obnNmZWHRrZcQ7xqaqqWLEb8dtqvAR6lo7c6uZNSpzW59s72HCCvNLm8W8J6iMIb +oPD5Idbk1a0YXETUQOO5MP4NGzb/g6MInXhMM3TeC66YeZecXHiWwdDYk9nSiH7Q +207vKvDYCxNC1wIV8UqPI7ck0ekAczJB9PlpFDXD2W0JX/JB0hnBAIKKEsVshPEv +FKlDXOrjx2fKV1kzrB9fSewfaKW5MrqWEEElikPwoo5o+mv57ClkhE6TmGqPSA+t +4kuTOlQwtVwlnLn0n0uyagRDs1eFUFuNXhFlAPAHbSMQeEVboYn7m9h7MYlVJwIT +4N/8w2cEnjAd/xX/O1maTxI/7MXTboCCE6j9NmLHWTX3MM/xhO248zhXbttwUkxf +2amL6QhsQiGtoyFKjhQtVTH8VVik05caEkWBOzKfldEVBrky8bacemW2EQp0uNAt +7IOwzv9uUuWOUd8yAyDb7rI4+JrYsUwFLFk49zFZrYwrn30WvaWTEkRRgL+xGfjC +W4ZLa8OmOO8O6C2sbTZyyCN0noG2IUGdIsIEhVFPIoqyqGlZ8IxF6EovZniz4sf8 +Lu0Fo8YN+5LMiS9hCXs2Guv0jaSQ3vJtxU00/hT1zCc7/x9P1G6ks79r4aKJYCwS +c/nAnT87YrXfQS3Zqa50HkbGqey7TwzwyrexC+eXgYvNhvXElG78hpPDhs/cyMcT +ApQNy3jQcXbdXeVL9AfEl6DmDR/XWtWOpz9Cpxz321IT8t6j8ZOdan1F5rgVfNbv +z7lx6AmI5GVZlTA2DBQGjmSHcfHbvo9EPcodALdSvAqwsSmuF72bJBYnkdyiO/6A +/ElYpcHv3X0NRyC93hkipnyUkoBkyWEeDJb69w9tUCleqA4Rd6TuicEIep010lMT +tbzy8wHAciN716PzfJPsnZBB2Mv9sXCzpbbZjT8TNmz6/O0d/a+LNaSCiTvjwqNd +ERvWTgp6f6kcBQZFDSzZIMN9SHNaQAHAFOFVBA0IQfelcSz/bFz21Z9f0ZQ8b3ML +FUMhx59D5Fcrvqn+5D6m8bAXw9gElRmUzi8BKyQay7JkHsQauS66yUrj2EEp94ch +8WdbE/zTNxbUWkIJxYg36EIYgrH8zf7/M00+tXk6HMZRy0wLbbJqQEh5tDV9Ht8z ++Eu3x6/VKGIFjhtIhVY7ZDCM9wFZjsbq/kQDT8PB9X9wt5o/quDo8wg8Zm0qnJkD +msPMXLh2ZVvKXiFM7WkhUYTOpxApOt+/jMGSqP2peCBqVIwQTdtQQ+wJZjx5sBmz +2eXKwEu+pmsRAsM3dtPuqXpJWUzrrcuI+okBtgQYAQoAIBYhBJJMrLUPFnSlUbBD +EIxml7IzL1qgBQJe7MVhAhsMAAoJEIxml7IzL1qg9YsMAJXUf1+CJd5mVkOZ551+ +INV3eIf+r5wXO7KoiK8CBUEnAqSNMrQ7QHTXwo9pSjuWR1O5JcRJumvZg/dj4Vox +tb/l26Y5gdyYVkzwjKA6OnuHmICB3Y6xZVNrq1FUMiDThytHbuJz7mZZugJ69lMV +ITA0iKJV+nFNP7slthTSpfP0XkQ74hnteWf+HadXU11MHFEw2Doi2xANMxzoQgy9 +8uY6tp1/07Ll/Te5Y6YB1dlXrHiuJcX7/nUvmNa13y1cq28W2fqVsNVmZPZB7/SK +DNyv6OT0iSIOBH/6AwoTzWo+Rcwr9PDKnII2fxizc3Jq75zjA+7F/Ol8fyaVrIbn +8oxh88rujnORKevIextgcrAlu+Q8dnspZ9oACqoKQM/W+mVb5ISr9Xf+qnicXWem +uGi6ofVHUZzzJsVRdrASSA6B2+Aup+PP+SuxFSok02/DkxkD2zgT8Xt/T+/usBsy +c9LeCkYBwNlcZZc7jWAJZ6Tt514F4wmJgKFgiuZ6MqBrRQ== +=1LV7 +-----END PGP PRIVATE KEY BLOCK----- \ No newline at end of file