diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efea846 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Gradle +.gradle/ +build/ + +# IntelliJ IDEA files +.idea/ +*.iml +*.ipr +*.iws + +# Eclipse files +.settings +.project +.classpath +.projectbuild +bin diff --git a/README.md b/README.md new file mode 100644 index 0000000..3833177 --- /dev/null +++ b/README.md @@ -0,0 +1,93 @@ +# Gradle Test Kit + +The content of src/mainTest/java/ is a copy of Luke Daley's gradle test kit prototype (https://github.com/alkemist/gradle-test-kit). +There is an open ticket (https://github.com/alkemist/gradle-test-kit/issues/3) for this to be published to central. +If that happens (or better yet, something is released as part of gradle to aid in integration testing), this code +can be removed. + +As of this writing, this code is released under the Apache License 2.0, http://www.apache.org/licenses/LICENSE-2.0 + + +# BancvueProjectPlugin (bancvue) + +The 'root' of the Bancvue plugin heirarchy, this plugin defines behavior all Bancvue projects will likely need. + +The [java](http://www.gradle.org/docs/current/userguide/java_plugin.html) +and [groovy](http://www.gradle.org/docs/current/userguide/groovy_plugin.html) plugins are applied first. + +All other behavior is split into individual plugins covered below. Each of these plugins (except integration test) +is applied as part of the BancvuePlugin. + +## BancvueDefaultsPlugin (bancvue-defaults) + + +## MavenPublishExtPlugin (maven-publish-ext) + +The [maven-publish](http://www.gradle.org/docs/current/userguide/publishing_maven.html) +and [maven-publish-auth](https://github.com/sebersole/gradle-maven-publish-auth) +plugins are applied, adding support for dependency resolution and artifact publishing. + + +## TestExtPlugin (test-ext) + + addMainTestConfigurationIfMainTestDirDefined() + +#### Added tasks + +* styledTestOutput, adds incremental (and colored) output when running tests, especially useful with longer-running tests to visually track progress + +#### Logging updates to Test tasks + +Full stack traces are enabled rather than just the first line of the exception. For example, if a Groovy power +assertion fails, the complete failure will be displayed on the console rather than forcing you to open up +the test results. In addition, groovy stack trace filters are enabled so that the groovy internals are excluded +from all exception stack traces. + +Skipped events are output to the console in addition to test faiures. + + +## ComponentTestPlugin (component-test) + + +## IntegrationTestPlugin (integration-test) + + +## IdeExtPlugin (ide-ext) + +The [idea](http://www.gradle.org/docs/current/userguide/idea_plugin.html) +and [eclipse](http://www.gradle.org/docs/current/userguide/idea_plugin.html) +plugins are applied, adding support for generating IDE project files for both IDEA and Eclipse. + +#### Added tasks + +* refreshIdea, wipe out and regenerate the IDEA project, workspace and module files +* refreshIdeaModule, wipe out and regenerate the IDEA module file +* refreshEclipse, wipe out and regenerate the Eclipse classpath and project files + + +## ProjectSupportPlugin (project-support) + + +## CustomGradlePlugin (custom-gradle) + +A plugin for generating a custom gradle build which can then be used to codify certain +attributes (e.g. artifact repository urls) or behavior (e.g. default plugins) for an +organization. The idea is to provide a gradle wrapper customized to an organization +which can used for all internal projects. + +

+group='com.bancvue'
+ext {
+    repositoryName = 'nexus'
+    repositoryPublicUrl = 'http://internal.domain/nexus/content/groups/public'
+    repositorySnapshotUrl = 'http://internal.domain/nexus/content/repositories/snapshots'
+    repositoryReleaseUrl = 'http://internal.domain/nexus/content/repositories/releases'
+
+    customGradleBaseVersion = "1.7"
+    customGradleVersion = "${customGradleBaseVersion}-bv.1.0"
+    customGradleGroupName = "${group}"
+    customGradleArtifactId = "gradle-bancvue"
+}
+
+apply plugin: 'custom-gradle'
+
\ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..14b1ed4 --- /dev/null +++ b/build.gradle @@ -0,0 +1,23 @@ +buildscript { + dependencies { + classpath gradleApi() + classpath localGroovy() + } +} + +apply plugin: 'bancvue' +apply plugin: 'integration-test' + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + compile gradleApi() + compile localGroovy() + + testCompile 'junit:junit:4.11' +} + +check.dependsOn integrationTest \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..377ff17 --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,19 @@ +repositories { + mavenLocal() +} + +dependencies { + compile gradleApi() + compile localGroovy() +} + +sourceSets { + main { + groovy { + srcDir '../src/main/groovy' + } + resources { + srcDir '../src/main/resources' + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..ca4b648 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +artifactId=gradle-core +version=0.1-SNAPSHOT \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..b979729 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0edb183 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Aug 23 19:49:13 CDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.7-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/integrationTest/groovy/com/bancvue/gradle/IdeExtPluginIntegrationTest.groovy b/src/integrationTest/groovy/com/bancvue/gradle/IdeExtPluginIntegrationTest.groovy new file mode 100644 index 0000000..85ecf74 --- /dev/null +++ b/src/integrationTest/groovy/com/bancvue/gradle/IdeExtPluginIntegrationTest.groovy @@ -0,0 +1,84 @@ +package com.bancvue.gradle + +import com.bancvue.gradle.test.AbstractPluginIntegrationTest +import org.junit.Test + +import static org.junit.Assert.fail + +class IdeExtPluginIntegrationTest extends AbstractPluginIntegrationTest { + + @Test + void idea_ShouldAddStandardSourceDirectoriesAndAdditionalTestConfigurations_IfIdePluginDeclaredBeforeTestPlugin() { + projectDir.newFile('build.gradle') << """ + apply plugin: 'groovy' + apply plugin: 'ide-ext' + apply plugin: 'integration-test' + """ + projectDir.newFolder('src', 'main', 'java') + projectDir.newFolder('src', 'test', 'groovy') + projectDir.newFolder('src', 'integrationTest', 'groovy') + + run('idea') + + File expectedImlFile = new File(projectDir.root, "${projectDir.root.name}.iml") + assert expectedImlFile.exists() + assertIdeaModuleFileContainsExpectedSourceFolder(expectedImlFile, 'src/main/java', false) + assertIdeaModuleFileContainsExpectedSourceFolder(expectedImlFile, 'src/test/groovy', true) + assertIdeaModuleFileContainsExpectedSourceFolder(expectedImlFile, 'src/integrationTest/groovy', true) + try { + assertIdeaModuleFileContainsExpectedSourceFolder(expectedImlFile, 'src/someOtherTest/groovy', true) + fail("Test should have failed, something is likely wrong with positive validations") + } catch (Throwable ex) {} + } + + private void assertIdeaModuleFileContainsExpectedSourceFolder(File expectedImlFile, String folderName, boolean isTestFolder) { + String expectedUrl = "file://\$MODULE_DIR\$/${folderName}" + def module = new XmlParser().parseText(expectedImlFile.text) + + List result = module.component.content.sourceFolder.findAll { + it.@url == expectedUrl + } + + if (!result) { + fail("Expected sourceFolder url=${expectedUrl} not found in iml content=${expectedImlFile.text}") + } + assert result.size() == 1 + assert Boolean.parseBoolean(result[0].@isTestSource) == isTestFolder + } + + @Test + void eclipse_ShouldAddStandardSourceDirectoriesAndAdditionalTestConfigurations_IfIdePluginDeclaredAfterTestPlugin() { + projectDir.newFile('build.gradle') << """ + apply plugin: 'groovy' + apply plugin: 'component-test' + apply plugin: 'ide-ext' + """ + projectDir.newFolder('src', 'main', 'java') + projectDir.newFolder('src', 'test', 'groovy') + projectDir.newFolder('src', 'componentTest', 'groovy') + + run('eclipse') + + File expectedClasspathFile = new File(projectDir.root, ".classpath") + assert expectedClasspathFile.exists() + assertEclipseModuleFileContainsExpectedSourceFolder(expectedClasspathFile, 'src/main/java') + assertEclipseModuleFileContainsExpectedSourceFolder(expectedClasspathFile, 'src/test/groovy') + assertEclipseModuleFileContainsExpectedSourceFolder(expectedClasspathFile, 'src/componentTest/groovy') + try { + assertEclipseModuleFileContainsExpectedSourceFolder(expectedClasspathFile, 'src/someOtherTest/groovy') + fail("Test should have failed, something is likely wrong with positive validations") + } catch (Throwable ex) {} + } + + private void assertEclipseModuleFileContainsExpectedSourceFolder(File expectedClasspathFile, String folderName) { + def classpath = new XmlParser().parseText(expectedClasspathFile.text) + List result = classpath.classpathentry.findAll { + it.@kind == 'src' && it.@path == folderName + } + + if (!result) { + fail("Expected classpathentry path=${folderName} not found in .classpath content=${expectedClasspathFile.text}") + } + } + +} \ No newline at end of file diff --git a/src/integrationTest/groovy/com/bancvue/gradle/custom/CustomGradlePluginIntegrationTest.groovy b/src/integrationTest/groovy/com/bancvue/gradle/custom/CustomGradlePluginIntegrationTest.groovy new file mode 100644 index 0000000..a0c800d --- /dev/null +++ b/src/integrationTest/groovy/com/bancvue/gradle/custom/CustomGradlePluginIntegrationTest.groovy @@ -0,0 +1,54 @@ +package com.bancvue.gradle.custom + +import com.bancvue.gradle.test.AbstractPluginIntegrationTest +import com.bancvue.zip.ZipArchive +import org.junit.Test + +class CustomGradlePluginIntegrationTest extends AbstractPluginIntegrationTest { + + @Test + void buildCustomGradleDistro_ShouldBundleGradleCustomizationScript() { + File zipBaseDir = projectDir.newFolder('zipBase') + new File(zipBaseDir, 'emptyfile.txt').write("") + projectDir.newFile('build.gradle') << """ +ext { + repositoryName = 'repo' + repositoryPublicUrl = 'http://repo.domain/public' + repositorySnapshotUrl = 'http://repo.domain/snapshots' + repositoryReleaseUrl = 'http://repo.domain/releases' + + customGradleBaseVersion = "1.7" + customGradleVersion = "1.7-bv.1.0" + customGradleGroupName = "com.bancvue" + customGradleArtifactId = "gradle-bancvue" +} + +apply plugin: 'custom-gradle' + +// fake out the download and replace it with an empty zip +task createDownloadArchive(type: Zip) { + from 'zipBase' + includeEmptyDirs=true + archiveName=downloadGradle.downloadFileName + destinationDir=project.buildDir +} +downloadGradle.dependsOn { createDownloadArchive } +downloadGradle.gradleDownloadBase = "file:///\${createDownloadArchive.destinationDir}" + +println "Created cutomized gradle dist at \${buildCustomGradleDistro.archivePath}" + """ + + run('buildCustomGradleDistro') + + File expectedZipFile = new File(projectDir.root, "build/distributions/gradle-bancvue-1.7-bv.1.0-bin.zip") + assert expectedZipFile.exists() + ZipArchive archive = new ZipArchive(expectedZipFile) + String expectedCustomScript = archive.getContentForEntryWithNameLike('customized.gradle') + assert expectedCustomScript + assert expectedCustomScript =~ 'url "http://repo.domain/public"' + assert expectedCustomScript =~ 'repositoryPublicUrl = "http://repo.domain/public"' + assert expectedCustomScript =~ 'repositorySnapshotUrl = "http://repo.domain/snapshots"' + assert expectedCustomScript =~ 'repositoryReleaseUrl = "http://repo.domain/releases"' + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/BancvueProjectPlugin.groovy b/src/main/groovy/com/bancvue/gradle/BancvueProjectPlugin.groovy new file mode 100644 index 0000000..78a6378 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/BancvueProjectPlugin.groovy @@ -0,0 +1,106 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import com.bancvue.gradle.maven.MavenPublishExtPlugin +import com.bancvue.gradle.test.ComponentTestPlugin +import com.bancvue.gradle.test.TestExtPlugin +import org.gradle.api.GradleException +import org.gradle.api.Plugin +import org.gradle.api.Project + +class BancvueProjectPlugin implements Plugin { + + static class VersionNotDefinedException extends GradleException { + public VersionNotDefinedException() { + super('Required property "version" must be specified') + } + } + + static class ArtifactIdNotDefinedException extends GradleException { + public ArtifactIdNotDefinedException() { + super('Required property "artifactId" must be specified') + } + } + + static final String PLUGIN_NAME = 'bancvue' + + private Project project + + public void apply(Project project) { + this.project = project + project.group = 'com.bancvue' + assertRequiredPropertiesDefined() + applyJavaPlugin() + applyGroovyPlugin() + applyBancvueDefaultsPlugin() + applyMavenPublishExtPlugin() + applyTestExtPlugin() + applyComponentTestPlugin() + applyIdeExtPlugin() + applyBancvueUtilPlugin() + } + + private void assertRequiredPropertiesDefined() { + assertVersionDefined() + assertArtifactIdDefined() + } + + private void assertVersionDefined() { + if (!project.version || (project.version == Project.DEFAULT_VERSION)) { + throw new VersionNotDefinedException() + } + } + + private void assertArtifactIdDefined() { + if (!project.ext.properties.containsKey('artifactId')) { + throw new ArtifactIdNotDefinedException() + } + } + + private void applyJavaPlugin() { + project.apply(plugin: 'java') + } + + private void applyGroovyPlugin() { + project.apply(plugin: 'groovy') + } + + private void applyIdeExtPlugin() { + project.apply(plugin: IdeExtPlugin.PLUGIN_NAME) + } + + private void applyMavenPublishExtPlugin() { + project.apply(plugin: MavenPublishExtPlugin.PLUGIN_NAME) + } + + private void applyTestExtPlugin() { + project.apply(plugin: TestExtPlugin.PLUGIN_NAME) + } + + private void applyComponentTestPlugin() { + project.apply(plugin: ComponentTestPlugin.PLUGIN_NAME) + } + + private void applyBancvueUtilPlugin() { + project.apply(plugin: ProjectSupportPlugin.PLUGIN_NAME) + } + + private void applyBancvueDefaultsPlugin() { + project.apply(plugin: ProjectDefaultsPlugin.PLUGIN_NAME) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/DefaultProjectPropertyContainer.groovy b/src/main/groovy/com/bancvue/gradle/DefaultProjectPropertyContainer.groovy new file mode 100644 index 0000000..7293801 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/DefaultProjectPropertyContainer.groovy @@ -0,0 +1,55 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import groovy.util.logging.Slf4j +import org.gradle.api.Project + +@Slf4j +class DefaultProjectPropertyContainer { + + private Project project + private String containerName + + DefaultProjectPropertyContainer(Project project, String containerName) { + this.project = project + this.containerName = containerName + } + + def getProperty(String propertyName) { + String value = getProjectProperty(propertyName) + if (value == null) { + value = getDefaultProperty(propertyName) + } + log.debug("getProperty(${propertyName}) : ${value}") + value + } + + private String getDefaultProperty(String propertyName) { + MetaProperty meta = metaClass.getMetaProperty(propertyName) + meta.getProperty(this) + } + + private String getProjectProperty(String propertyName) { + String containerPropertyName = "${containerName}${propertyName.capitalize()}" + String value = null + if (project?.hasProperty(containerPropertyName)) { + value = project.property(containerPropertyName) + } + value + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/GradlePluginMixin.groovy b/src/main/groovy/com/bancvue/gradle/GradlePluginMixin.groovy new file mode 100644 index 0000000..0cf6529 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/GradlePluginMixin.groovy @@ -0,0 +1,87 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.ConfigurableFileCollection +import org.slf4j.Logger + +class GradlePluginMixin { + + static FilenameFilter JAR_FILTER = { dir, file -> file ==~ /(?i).*\.jar$/ } as FilenameFilter + + Project acquirePluginProject() { + assertPropertyDefined('project') + project + } + + Logger acquirePluginLog() { + assertPropertyDefined('log') + log + } + + void assertPropertyDefined(String propertyName) { + if (!hasProperty(propertyName)) { + throw new RuntimeException("Mixin requires property '${propertyName}' on target class") + } + } + + void renameTask(Task task, String newTaskName) { + acquirePluginProject().tasks.remove(task) + Map properties = task.properties + properties[Task.TASK_OVERWRITE] = true + properties[Task.TASK_NAME] = newTaskName + acquirePluginProject().tasks.create(properties) + } + + ConfigurableFileCollection createJarFileCollection(File dir) { + File[] files = dir.listFiles(JAR_FILTER) + + if (!files) { + acquirePluginLog().warn("Failed to create file collection, no jar files in dir=${dir}") + return null + } + acquirePluginProject().files(files) + } + + void createNamedConfigurationExtendingFrom(String configurationName, String extendsFromConfigurationName) { + String extendsFromCompileConfigurationName = "${extendsFromConfigurationName}Compile" + String extendsFromRuntimeConfigurationName = "${extendsFromConfigurationName}Runtime" + createNamedConfigurationExtendingFrom(configurationName, extendsFromCompileConfigurationName, extendsFromRuntimeConfigurationName) + } + + void createNamedConfigurationExtendingFrom(String configurationName, String extendsFromCompileConfigurationName, String extendsFromRuntimeConfigurationName) { + Configuration extendsFromCompileConfiguration = acquireConfigurationByName(extendsFromCompileConfigurationName) + Configuration extendsFromRuntimeConfiguration = acquireConfigurationByName(extendsFromRuntimeConfigurationName) + + acquirePluginProject().configurations { + "${configurationName}" {} + "${configurationName}Compile" { + extendsFrom(extendsFromCompileConfiguration) + } + "${configurationName}Runtime" { + extendsFrom(extendsFromRuntimeConfiguration) + } + } + } + + Configuration acquireConfigurationByName(String extendsFromCompileConfigurationName) { + acquirePluginProject().configurations.getByName(extendsFromCompileConfigurationName) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/IdeExtPlugin.groovy b/src/main/groovy/com/bancvue/gradle/IdeExtPlugin.groovy new file mode 100644 index 0000000..7c33e1c --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/IdeExtPlugin.groovy @@ -0,0 +1,142 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +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.tasks.SourceSet + + +class IdeExtPlugin implements Plugin { + + static final String PLUGIN_NAME = 'ide-ext' + + private static final String IDE_GROUP_NAME = 'IDE' + + private Project project + + public void apply(Project project) { + this.project = project + project.apply(plugin: 'java') + applyIdeaPlugin() + applyEclipsePlugin() + } + + private void applyIdeaPlugin() { + project.apply(plugin: 'idea') + addRefreshIdeaTask() + addRefreshIdeaModuleTask() + updateIdeaSourcePathAndTestScopePriorToModuleTaskExecution() + } + + private void addRefreshIdeaTask() { + Task refreshIdea = project.tasks.create('refreshIdea') + Task cleanIdea = project.tasks.getByName('cleanIdea') + Task idea = project.tasks.getByName('idea') + + refreshIdea.group = IDE_GROUP_NAME + refreshIdea.description = 'Clean and generate IDEA project, workspace and module files' + refreshIdea.dependsOn(cleanIdea, idea) + } + + private void addRefreshIdeaModuleTask() { + Task refreshIdeaModule = project.tasks.create('refreshIdeaModule') + Task cleanIdeaModule = project.tasks.getByName('cleanIdeaModule') + Task ideaModule = project.tasks.getByName('ideaModule') + + refreshIdeaModule.group = IDE_GROUP_NAME + refreshIdeaModule.description = 'Clean and generate IDEA module file' + refreshIdeaModule.dependsOn(cleanIdeaModule, ideaModule) + } + + private void updateIdeaSourcePathAndTestScopePriorToModuleTaskExecution() { + Task ideaModule = project.tasks.getByName('ideaModule') + + ideaModule.doFirst { + updateIdeaSourcePathAndTestScope() + } + } + + private void updateIdeaSourcePathAndTestScope() { + resetIdeaModuleTestPaths() + addTestConfigurationsToIdeaTestScope() + } + + private void resetIdeaModuleTestPaths() { + project.idea { + module.conventionMapping.testSourceDirs = { getTestSourceDirs() } + } + } + + private Set getTestSourceDirs() { + project.sourceSets.findAll { SourceSet sourceSet -> + sourceSet.name =~ /(?i)test/ + }.collect { SourceSet sourceSet -> + sourceSet.allSource.srcDirs + }.flatten() + } + + private void addTestConfigurationsToIdeaTestScope() { + project.idea { + module { + scopes.TEST.plus = getTestRuntimeConfigurations() + } + } + } + + private Set getTestRuntimeConfigurations() { + Set runtimeConfigurations = project.configurations.findAll { Configuration config -> + config.name =~ /(?i)testruntime$/ + } as Set + runtimeConfigurations + } + + private void applyEclipsePlugin() { + project.apply(plugin: 'eclipse') + addRefreshEclipseTask() + updateEclipseSourcePathAndClassPathPriorToModuleTaskExecution() + } + + private void addRefreshEclipseTask() { + Task refreshEclipse = project.tasks.create('refreshEclipse') + Task cleanEclipse = project.tasks.getByName('cleanEclipse') + Task eclipse = project.tasks.getByName('eclipse') + + refreshEclipse.group = IDE_GROUP_NAME + refreshEclipse.description = 'Clean and generate all Eclipse files' + refreshEclipse.dependsOn(cleanEclipse, eclipse) + } + + + private void updateEclipseSourcePathAndClassPathPriorToModuleTaskExecution() { + Task eclipse = project.tasks.getByName('eclipse') + + eclipse.doFirst { + updateEclipseSourcePathAndClassPath() + } + } + + private void updateEclipseSourcePathAndClassPath() { + project.eclipse { + classpath { + plusConfigurations = getTestRuntimeConfigurations() + } + } + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/ProjectDefaultsPlugin.groovy b/src/main/groovy/com/bancvue/gradle/ProjectDefaultsPlugin.groovy new file mode 100644 index 0000000..970dbcd --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/ProjectDefaultsPlugin.groovy @@ -0,0 +1,96 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.tasks.compile.ForkOptions +import org.gradle.api.tasks.compile.GroovyCompile +import org.gradle.api.tasks.compile.GroovyForkOptions +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.api.tasks.testing.Test + +class ProjectDefaultsPlugin implements Plugin { + + static final String PLUGIN_NAME = 'project-defaults' + + private Project project + private ProjectDefaultsProperties defaultsProperties + + public void apply(Project project) { + this.project = project + this.defaultsProperties = new ProjectDefaultsProperties(project) + project.apply(plugin: 'java') + setDefaultCompileMemorySettings() + setDefaultTestMemorySettings() + setCompilerEncodingToUtf8() + addBuildDateAndJdkToJarManifest() + setJavaCompatibilityVersion() + setJarBaseNameToArtifactIdIfArtifactIdSet() + } + + private void setDefaultCompileMemorySettings() { + project.tasks.withType(GroovyCompile) { GroovyCompile compile -> + GroovyForkOptions forkOptions = compile.groovyOptions.forkOptions + setCompileMemorySettings(forkOptions) + } + project.tasks.withType(JavaCompile) { JavaCompile compile -> + ForkOptions forkOptions = compile.options.forkOptions + setCompileMemorySettings(forkOptions) + } + } + + private void setCompileMemorySettings(def forkOptions) { + forkOptions.memoryInitialSize = defaultsProperties.minHeapSize + forkOptions.memoryMaximumSize = defaultsProperties.maxHeapSize + forkOptions.jvmArgs << "-XX:MaxPermSize=${defaultsProperties.maxPermSize}".toString() + } + + private void setDefaultTestMemorySettings() { + project.tasks.withType(Test) { Test test -> + test.minHeapSize = defaultsProperties.minTestHeapSize + test.maxHeapSize = defaultsProperties.maxTestHeapSize + test.jvmArgs("-XX:MaxPermSize=${defaultsProperties.maxTestPermSize}".toString()) + } + } + + private void setCompilerEncodingToUtf8() { + project.tasks.withType(JavaCompile) { JavaCompile compile -> + compile.options.encoding = 'UTF-8' + } + } + + private void addBuildDateAndJdkToJarManifest() { + project.jar { + manifest { + attributes 'Built-Date': new Date() + attributes 'Build-Jdk': System.getProperty('java.version') + } + } + } + + private void setJavaCompatibilityVersion() { + project.setProperty('sourceCompatibility', defaultsProperties.javaVersion) + project.setProperty('targetCompatibility', defaultsProperties.javaVersion) + } + + private void setJarBaseNameToArtifactIdIfArtifactIdSet() { + if (project.hasProperty('artifactId')) { + project.jar.baseName = project.artifactId + } + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/ProjectDefaultsProperties.groovy b/src/main/groovy/com/bancvue/gradle/ProjectDefaultsProperties.groovy new file mode 100644 index 0000000..fd21eb8 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/ProjectDefaultsProperties.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import org.gradle.api.Project + + +class ProjectDefaultsProperties extends DefaultProjectPropertyContainer { + + private static final String NAME = 'defaults' + + String javaVersion = '1.7' + + String minHeapSize = '64m' + String maxHeapSize = '256m' + String maxPermSize = '64m' + + String minTestHeapSize = '64m' + String maxTestHeapSize = '512m' + String maxTestPermSize = '64m' + + ProjectDefaultsProperties(Project project) { + super(project, NAME) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/ProjectSupportPlugin.groovy b/src/main/groovy/com/bancvue/gradle/ProjectSupportPlugin.groovy new file mode 100644 index 0000000..1c6e6bd --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/ProjectSupportPlugin.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle + +import com.bancvue.gradle.tasks.ClearArtifactCache +import com.bancvue.gradle.tasks.PrintClasspath +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task + +class ProjectSupportPlugin implements Plugin { + + static final String PLUGIN_NAME = 'project-support' + + private static final String TASK_GROUP_NAME = 'Utilities' + + private Project project + + @Override + void apply(Project project) { + this.project = project + addPrintClasspathTask() + addClearGroupCacheTask() + } + + private void addPrintClasspathTask() { + Task printClasspath = project.tasks.create('printClasspath', PrintClasspath) + printClasspath.group = TASK_GROUP_NAME + } + + private void addClearGroupCacheTask() { + ClearArtifactCache clearCacheTask = project.task("clearGroupCache", type: ClearArtifactCache) + clearCacheTask.groupName = project.group + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/custom/CustomGradlePlugin.groovy b/src/main/groovy/com/bancvue/gradle/custom/CustomGradlePlugin.groovy new file mode 100644 index 0000000..d0e0a9b --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/custom/CustomGradlePlugin.groovy @@ -0,0 +1,144 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.custom + +import com.bancvue.gradle.maven.MavenPublishExtPlugin +import com.bancvue.gradle.maven.MavenRepositoryProperties +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.tasks.wrapper.Wrapper + +class CustomGradlePlugin implements Plugin { + + static final String PLUGIN_NAME = 'custom-gradle' + + private Project project + + public void apply(Project project) { + this.project = project + applyJavaPlugin() + applyMavenPublishExtPlugin() + addBuildCustomGradleDistroTask() + addMavenPublication() + addCustomWrapperTask() + } + + private void applyJavaPlugin() { + project.apply(plugin: 'java') + } + + private void applyMavenPublishExtPlugin() { + project.apply(plugin: MavenPublishExtPlugin.PLUGIN_NAME) + } + + private DownloadGradle addDownloadGradleTask() { + CustomGradleProperties gradleProperties = new CustomGradleProperties(project) + DownloadGradle downloadGradleTask = project.tasks.create('downloadGradle', DownloadGradle) + downloadGradleTask.configure { + description = 'Download Gradle version from Gradle distributions website' + gradleVersion = gradleProperties.baseVersion + destinationDir = project.file("${project.buildDir}/gradle-downloads") + } + downloadGradleTask + } + + private void addBuildCustomGradleDistroTask() { + CustomGradleProperties gradleProperties = new CustomGradleProperties(project) + DownloadGradle downloadGradleTask = addDownloadGradleTask() + Task buildCustomGradleDistroTask = project.tasks.create('buildCustomGradleDistro', Zip) + buildCustomGradleDistroTask.configure { + dependsOn { downloadGradleTask } + doFirst { println "configure internal zip" } + group = 'Build' + description = 'Add extra files to company Gradle distribution' + baseName = gradleProperties.artifactId + version = gradleProperties.version + classifier = 'bin' + from project.zipTree(downloadGradleTask.destinationFile) + into(downloadGradleTask.distributionNameBase) { + into('init.d') { + from createGradleInitializationScript() + } + } + } + } + + private File createGradleInitializationScript() { + File gradleInitializationScript = new File(project.buildDir, 'tmp/customized.gradle') + gradleInitializationScript.parentFile.mkdirs() + gradleInitializationScript.write(getGradleInitializationScriptContent()) + gradleInitializationScript + } + + private String getGradleInitializationScriptContent() { + MavenRepositoryProperties repositoryProperties = new MavenRepositoryProperties(project) + """ +println "Using the BancVue gradle" + +allprojects { + buildscript { + repositories { + mavenLocal() + maven { + url "${repositoryProperties.publicUrl}" + } + } + } + + project.ext { + repositoryName = "${repositoryProperties.name}" + repositoryPublicUrl = "${repositoryProperties.publicUrl}" + repositorySnapshotUrl = "${repositoryProperties.snapshotUrl}" + repositoryReleaseUrl = "${repositoryProperties.releaseUrl}" + } +} +""" + } + + private void addMavenPublication() { + CustomGradleProperties customGradle = new CustomGradleProperties(project) + project.publishing { + Task buildCustomGradleDistroTask = project.tasks.getByName('buildCustomGradleDistro') + publications { + "customGradleDistro"(MavenPublication) { + artifact buildCustomGradleDistroTask + artifactId = customGradle.artifactId + version = customGradle.version + } + } + } + } + + private void addCustomWrapperTask() { + Task wrapper = project.tasks.create('customWrapper', Wrapper) + wrapper.group = 'Utilities' + // TODO: add description + wrapper.distributionUrl = createDistributionUrl() + } + + private void createDistributionUrl() { + MavenRepositoryProperties repository = new MavenRepositoryProperties(project) + CustomGradleProperties customGradle = new CustomGradleProperties(project) + // TODO: will fail if customGradle.groupName is null, need test and need to figure out what to do in that case + "${repository.releaseUrl}/" + + "${customGradle.groupName.replaceAll('.', '/')}/" + + "${customGradle.artifactId}/${customGradle.version}/" + + "${customGradle.artifactId}-${customGradle.version}-bin.zip" + } +} diff --git a/src/main/groovy/com/bancvue/gradle/custom/CustomGradleProperties.groovy b/src/main/groovy/com/bancvue/gradle/custom/CustomGradleProperties.groovy new file mode 100644 index 0000000..663d80d --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/custom/CustomGradleProperties.groovy @@ -0,0 +1,35 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.custom + +import com.bancvue.gradle.DefaultProjectPropertyContainer +import org.gradle.api.Project + + +class CustomGradleProperties extends DefaultProjectPropertyContainer { + + private static final String NAME = "customGradle" + + String groupName + String artifactId + String version + String baseVersion + + CustomGradleProperties(Project project) { + super(project, NAME) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/custom/DownloadGradle.groovy b/src/main/groovy/com/bancvue/gradle/custom/DownloadGradle.groovy new file mode 100644 index 0000000..fc875a8 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/custom/DownloadGradle.groovy @@ -0,0 +1,55 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.custom + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + + +class DownloadGradle extends DefaultTask { + @Input + String gradleVersion + + @Input + File destinationDir + + @Input + String gradleDownloadBase = "http://services.gradle.org/distributions" + + @TaskAction + doDownloadGradle() { + destinationFile.bytes = new URL(downloadUrl).bytes + } + + String getDownloadUrl() { + "$gradleDownloadBase/$downloadFileName" + } + + String getDistributionNameBase() { + "gradle-$gradleVersion" + } + + String getDownloadFileName() { + "$distributionNameBase-bin.zip" + } + + @OutputFile + File getDestinationFile() { + new File(destinationDir, downloadFileName) + } +} \ No newline at end of file diff --git a/src/main/groovy/com/bancvue/gradle/maven/MavenPublishExtPlugin.groovy b/src/main/groovy/com/bancvue/gradle/maven/MavenPublishExtPlugin.groovy new file mode 100644 index 0000000..a73b3c5 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/maven/MavenPublishExtPlugin.groovy @@ -0,0 +1,188 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.maven + +import com.bancvue.gradle.GradlePluginMixin +import com.bancvue.gradle.test.TestExtPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.javadoc.Javadoc + +@Mixin(GradlePluginMixin) +class MavenPublishExtPlugin implements Plugin { + + static final String PLUGIN_NAME = 'maven-publish-ext' + + private Project project + private MavenRepositoryProperties repositoryProperties + + public void apply(Project project) { + this.project = project + this.repositoryProperties = new MavenRepositoryProperties(project) + project.apply(plugin: 'java') + addArtifactDependencyAndPublishingSupport() + } + + private void addArtifactDependencyAndPublishingSupport() { + project.apply(plugin: 'maven-publish') + renamePublishTasks() + addNexusDependencyRepository() + addNexusPublishingRepository() + addSourceJarTask() + addJavadocJarTask() + addProjectPublication() + } + + private void renamePublishTasks() { + renamePublishTaskToPublishRemote() + renamePublishToMavenLocalTaskToPublish() + } + + private void renamePublishTaskToPublishRemote() { + Task publish = project.tasks.findByName('publish') + project.tasks.remove(publish) + publish.description = 'Publishes all publications produced by this project.' + renameTask(publish, 'publishRemote') + } + + private void renamePublishToMavenLocalTaskToPublish() { + Task publishToMavenLocal = project.tasks.findByName('publishToMavenLocal') + publishToMavenLocal.description = 'Publishes all Maven publications produced by this project to the local Maven cache.' + renameTask(publishToMavenLocal, 'publish') + } + + private void addNexusDependencyRepository() { + project.repositories.mavenLocal() + project.repositories { + maven { + name repositoryProperties.name + url repositoryProperties.publicUrl + } + } + } + + private boolean isSnapshotProject() { + project.version =~ /SNAPSHOT$/ + } + + private String acquireNexusPublishUrl() { + if (isSnapshotProject()) { + repositoryProperties.snapshotUrl + } else { + repositoryProperties.releaseUrl + } + } + + private void addNexusPublishingRepository() { + project.publishing { + repositories { + maven { + name repositoryProperties.name + url acquireNexusPublishUrl() + if (repositoryProperties.hasCredentialsDefined()) { + credentials { + username repositoryProperties.username + password repositoryProperties.password + } + } + } + } + } + } + + private String getBaseNameForTask(Jar task) { + String baseName = getProjectArtifactId() + if (baseName == null) { + baseName = task.baseName + } + baseName + } + + private String getProjectArtifactId() { + project.hasProperty('artifactId') ? project.ext.artifactId : null + } + + private String getProjectName() { + String projectName = getProjectArtifactId() + if (projectName == null) { + projectName = project.name + } + projectName.replaceAll(/[-](\S)/) { it[1].toUpperCase() } + } + + private void addSourceJarTask() { + Jar sourceJarTask = project.tasks.create("sourceJar", Jar) + sourceJarTask.configure { + group = "Build" + baseName = getBaseNameForTask(sourceJarTask) + classifier = "sources" + description = "Assembles a jar archive containing the main sources." + from project.sourceSets.main.allSource + } + } + + private void addJavadocJarTask() { + Javadoc javadocTask = project.tasks.getByName('javadoc') + Jar javadocJarTask = project.tasks.create("javadocJar", Jar) + javadocJarTask.configure { + dependsOn javadocTask + group = "Build" + baseName = getBaseNameForTask(javadocJarTask) + classifier = "javadoc" + description = "Assembles a jar archive containing the main javadocs." + from javadocTask.destinationDir + } + } + + private void addProjectPublication() { + if (!project.hasProperty("customPublication")) { + project.publishing { + publications { + "${getProjectName()}"(MavenPublication) { + from project.components.java + if (getProjectArtifactId() != null) { + pom.projectIdentity.artifactId = getProjectArtifactId() + } + attachAdditionalArtifactsToMavenPublication(delegate) + } + } + } + } + } + + private void attachAdditionalArtifactsToMavenPublication(MavenPublication publication) { + attachArtifactToMavenPublication(publication, "sourceJar") +// attachArtifactToMavenPublication(publication, "javadocJar") + attachTestArtifactToMavenPublicationIfMainTestConfigurationDefined(publication) + } + + private void attachArtifactToMavenPublication(MavenPublication publication, String jarTaskName) { + Task sourceJarTask = project.tasks.getByName(jarTaskName) + publication.artifact(sourceJarTask) + } + + private void attachTestArtifactToMavenPublicationIfMainTestConfigurationDefined(MavenPublication publication) { + Jar mainTestJarTask = TestExtPlugin.getMainTestJarTaskOrNullIfMainTestConfigurationNotDefined(project) + if (mainTestJarTask != null) { + mainTestJarTask.baseName = getBaseNameForTask(mainTestJarTask) + publication.artifact(mainTestJarTask) + } + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/maven/MavenRepositoryProperties.groovy b/src/main/groovy/com/bancvue/gradle/maven/MavenRepositoryProperties.groovy new file mode 100644 index 0000000..0adaab1 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/maven/MavenRepositoryProperties.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.maven + +import com.bancvue.gradle.DefaultProjectPropertyContainer +import org.gradle.api.Project + +class MavenRepositoryProperties extends DefaultProjectPropertyContainer { + + public static final String NAME = "repository"; + + private static final String getDefaultUrlPropertyValue(String propertyName) { + "changeme:set-project-property-repository${propertyName.capitalize()}" + } + + String name = "repo" + String publicUrl = getDefaultUrlPropertyValue("publicUrl") + String snapshotUrl = getDefaultUrlPropertyValue("snapshotUrl") + String releaseUrl = getDefaultUrlPropertyValue("releaseUrl") + String username + String password + + MavenRepositoryProperties(Project project) { + super(project, NAME) + } + + boolean hasCredentialsDefined() { + // see http://groovy.329449.n5.nabble.com/How-invoke-getProperty-interceptor-from-this-td5712559.html + // for why the getProperty usage is necessary + getProperty("username") && getProperty("password") + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/pmd/Cpd.groovy b/src/main/groovy/com/bancvue/gradle/pmd/Cpd.groovy new file mode 100644 index 0000000..4534669 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/pmd/Cpd.groovy @@ -0,0 +1,101 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.pmd + +import groovy.util.slurpersupport.GPathResult +import org.gradle.api.GradleException +import org.gradle.api.file.FileCollection +import org.gradle.api.internal.project.IsolatedAntBuilder +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.SourceTask +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.VerificationTask + +import javax.inject.Inject + +class Cpd extends SourceTask implements VerificationTask { + + /** + * The class path containing the PMD library to be used. + */ + @InputFiles + FileCollection cpdClasspath + @Input + int minimumTokenCount + @Input + boolean ignoreLiterals + @Input + boolean ignoreIdentifiers + @Input + File reportDir + /** + * Whether or not to allow the build to continue if there are warnings. + * + * Example: ignoreFailures = true + */ + boolean ignoreFailures + private final IsolatedAntBuilder antBuilder + + @Inject + Cpd(IsolatedAntBuilder antBuilder) { + this.antBuilder = antBuilder + } + + @TaskAction + void run() { + File cpdOutputFile = new File(getReportDir(), 'cpd.xml') + cpdOutputFile.parentFile.mkdirs() + + executeCpdAndWriteResultsToXmlFile(cpdOutputFile) + failIfCpdViolationsExceedThresholdElseLog(cpdOutputFile) + } + + private void executeCpdAndWriteResultsToXmlFile(File cpdOutputFile) { + Map antCpdArgs = [ + ignoreLiterals: getIgnoreLiterals(), + ignoreIdentifiers: getIgnoreIdentifiers(), + minimumtokencount: getMinimumTokenCount(), + format: 'xml', + outputfile: cpdOutputFile.absolutePath + ] + + antBuilder.withClasspath(getCpdClasspath()).execute { + ant.taskdef(name: 'cpd', classname: 'net.sourceforge.pmd.cpd.CPDTask') + ant.cpd(antCpdArgs) { + getSource().addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet) + } + } + } + + private void failIfCpdViolationsExceedThresholdElseLog(File cpdOutputFile) { + if (isCpdViolationDetected(cpdOutputFile)) { + String message = "CPD violations found. See the report at: ${cpdOutputFile}" + + if (getIgnoreFailures()) { + logger.warn(message) + } else { + throw new GradleException(message) + } + } + } + + private boolean isCpdViolationDetected(File cpdOutputFile) { + GPathResult pmdCpd = new XmlSlurper().parseText(cpdOutputFile.text) + !pmdCpd.children().isEmpty() + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/pmd/CpdExtension.groovy b/src/main/groovy/com/bancvue/gradle/pmd/CpdExtension.groovy new file mode 100644 index 0000000..7fedbe8 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/pmd/CpdExtension.groovy @@ -0,0 +1,29 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.pmd + +import org.gradle.api.plugins.quality.CodeQualityExtension + +class CpdExtension extends CodeQualityExtension { + + int minimumTokenCount = 50 + + boolean ignoreLiterals = false + + boolean ignoreIdentifiers = false + +} + diff --git a/src/main/groovy/com/bancvue/gradle/pmd/PmdCpdPlugin.groovy b/src/main/groovy/com/bancvue/gradle/pmd/PmdCpdPlugin.groovy new file mode 100644 index 0000000..e7fe320 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/pmd/PmdCpdPlugin.groovy @@ -0,0 +1,74 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.pmd + +import org.gradle.api.plugins.quality.CodeQualityExtension +import org.gradle.api.plugins.quality.PmdExtension +import org.gradle.api.plugins.quality.internal.AbstractCodeQualityPlugin +import org.gradle.api.tasks.SourceSet + +class PmdCpdPlugin extends AbstractCodeQualityPlugin { + + static final String PLUGIN_NAME = 'pmdcpd' + + @Override + protected void beforeApply() { + project.apply(plugin: 'pmd') + } + + @Override + protected String getToolName() { + return "CPD" + } + + @Override + protected Class getTaskType() { + return Cpd + } + + @Override + protected CodeQualityExtension createExtension() { + PmdExtension pmdExtension = project.extensions.getByName('pmd') + extension = project.extensions.create("cpd", CpdExtension) + extension.with { + toolVersion = pmdExtension.toolVersion + } + extension + } + + @Override + protected void configureTaskDefaults(Cpd task, String baseName) { + task.conventionMapping.with { + cpdClasspath = { + project.configurations['pmd'] + } + minimumTokenCount = { extension.minimumTokenCount } + ignoreLiterals = { extension.ignoreLiterals } + ignoreIdentifiers = { extension.ignoreIdentifiers } + ignoreFailures = { extension.ignoreFailures } + reportDir = { extension.reportsDir } + } + } + + @Override + protected void configureForSourceSet(SourceSet sourceSet, Cpd task) { + task.with { + description = "Run CPD analysis for ${sourceSet.name} classes" + } + task.setSource(sourceSet.allJava) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/tasks/ClearArtifactCache.groovy b/src/main/groovy/com/bancvue/gradle/tasks/ClearArtifactCache.groovy new file mode 100644 index 0000000..664a9df --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/tasks/ClearArtifactCache.groovy @@ -0,0 +1,76 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.tasks.TaskAction + + +class ClearArtifactCache extends DefaultTask { + + { + group = 'Utilities' + } + + String groupName + + void setGroupName(String groupName) { + this.groupName = groupName + this.description = "Deletes any artifacts from the ${groupName} group in the Maven2 repository and Gradle cache directories." + } + + @TaskAction + void clearArtifactCache() { + assertGroupNameSet() + clearMavenCache() + clearGradleCache() + } + + private void assertGroupNameSet() { + if (!groupName) { + throw new GradleException("Required property 'groupName' not set") + } + } + + private void clearMavenCache() { + String cachePath = groupName.replaceAll(/\./, '/') + project.delete new File(getUserHome(), ".m2/repository/${cachePath}") + } + + private static File getUserHome() { + String userHome = System.getProperty('user.home') + new File(userHome) + } + + private void clearGradleCache() { + File gradleUserHomeDir = project.gradle.gradleUserHomeDir + List cacheDirs = collectGradleCacheDirsWithName(gradleUserHomeDir, groupName) + project.delete(cacheDirs.toArray()) + } + + private static List collectGradleCacheDirsWithName(File parentDir, String groupName) { + List dirs = [] + + parentDir.eachDirRecurse { File dir -> + if (dir.name == groupName) { + dirs << dir + } + } + dirs + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/tasks/PrintClasspath.groovy b/src/main/groovy/com/bancvue/gradle/tasks/PrintClasspath.groovy new file mode 100644 index 0000000..86474e2 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/tasks/PrintClasspath.groovy @@ -0,0 +1,66 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.tasks + +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.TaskAction + + +class PrintClasspath extends DefaultTask { + + { + description = 'Print classpaths of each source set to console (use -Pfullpath=1 to output complete directory paths)' + } + + @TaskAction + void printClasspathsForAllSourceSets() { + project.sourceSets.each { SourceSet sourceSet -> + printClasspathsForSourceSet(sourceSet) + } + } + + private void printClasspathsForSourceSet(SourceSet sourceSet) { + println "" + println "******************************* SourceSet ${sourceSet.name} *******************************" + printClasspathForSourceSet(sourceSet, 'compileClasspath') + printClasspathForSourceSet(sourceSet, 'runtimeClasspath') + } + + private void printClasspathForSourceSet(SourceSet sourceSet, String classpathName) { + List pathsToPrint = getPathsToPrintForSourceSet(sourceSet, classpathName) + + println "${sourceSet.name}.${classpathName}" + pathsToPrint.each { String pathToPrint -> + println " > ${pathToPrint}" + } + } + + private boolean shouldPrintFullPath() { + project.hasProperty('fullpath') + } + + private List getPathsToPrintForSourceSet(SourceSet sourceSet, String classpathName) { + boolean printFullPath = shouldPrintFullPath() + + sourceSet."${classpathName}".findAll { File file -> + file.exists() + }.collect { File file -> + (printFullPath || file.isDirectory()) ? file.absolutePath : file.name + } + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/test/ComponentTestPlugin.groovy b/src/main/groovy/com/bancvue/gradle/test/ComponentTestPlugin.groovy new file mode 100644 index 0000000..70edd58 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/test/ComponentTestPlugin.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import org.gradle.api.Task + +class ComponentTestPlugin extends NamedTestConfigurationPlugin { + + static final String PLUGIN_NAME = 'component-test' + + public ComponentTestPlugin() { + super('componentTest') + } + + @Override + protected void initializeNamedTestConfiguration() { + super.initializeNamedTestConfiguration() + addComponentTestAsDependencyOfCheck() + } + + private void addComponentTestAsDependencyOfCheck() { + Task componentTest = project.tasks.getByName('componentTest') + Task check = project.tasks.getByName('check') + + check.dependsOn(componentTest) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/test/IntegrationTestPlugin.groovy b/src/main/groovy/com/bancvue/gradle/test/IntegrationTestPlugin.groovy new file mode 100644 index 0000000..b0c4f8d --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/test/IntegrationTestPlugin.groovy @@ -0,0 +1,26 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +class IntegrationTestPlugin extends NamedTestConfigurationPlugin { + + static final String PLUGIN_NAME = 'integration-test' + + IntegrationTestPlugin() { + super('integrationTest') + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/test/NamedTestConfigurationPlugin.groovy b/src/main/groovy/com/bancvue/gradle/test/NamedTestConfigurationPlugin.groovy new file mode 100644 index 0000000..1fe8774 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/test/NamedTestConfigurationPlugin.groovy @@ -0,0 +1,93 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import com.bancvue.gradle.GradlePluginMixin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.testing.Test + + +@Mixin(GradlePluginMixin) +class NamedTestConfigurationPlugin implements Plugin { + + protected Project project + protected String configurationName + + NamedTestConfigurationPlugin(String configurationName) { + this.configurationName = configurationName + } + + public void apply(Project project) { + this.project = project + if (configurationExistsAsSrcDir()) { + initializeNamedTestConfiguration() + } + } + + private boolean configurationExistsAsSrcDir() { + project.file("src/${configurationName}").exists() + } + + protected void initializeNamedTestConfiguration() { + project.apply(plugin: 'java') + addTestConfiguration() + addTestSourceSet() + addNamedTestTask() + } + + private void addTestConfiguration() { + createNamedConfigurationExtendingFrom(configurationName, 'test') + } + + private void addTestSourceSet() { + project.sourceSets { + "${configurationName}" { + compileClasspath = main.output + test.compileClasspath - test.output + + project.configurations."${configurationName}Compile" + runtimeClasspath = project.sourceSets."${configurationName}".output + main.output + + test.runtimeClasspath - test.output + project.configurations."${configurationName}Runtime" + } + } + } + + private void addNamedTestTask() { + createAndConfigureNamedTestTask() + configureNamedTestToRunAfterUnitTest() + } + + private void createAndConfigureNamedTestTask() { + Task testTask = project.tasks.create(configurationName, Test) + testTask.configure { + description = "Runs the ${configurationName} tests." + group = 'Verification' + testClassesDir = project.sourceSets."${configurationName}".output.classesDir + classpath = project.sourceSets."${configurationName}".runtimeClasspath + testReportDir = new File(project.reporting.baseDir, "${configurationName}s") + testResultsDir = new File(project.buildDir, "${configurationName}-results") + } + testTask + } + + private void configureNamedTestToRunAfterUnitTest() { + Task namedTest = project.tasks.getByName(configurationName) + Task unitTest = project.tasks.getByName('test') + + namedTest.mustRunAfter(unitTest) + } + +} diff --git a/src/main/groovy/com/bancvue/gradle/test/StyledTestOutput.groovy b/src/main/groovy/com/bancvue/gradle/test/StyledTestOutput.groovy new file mode 100644 index 0000000..a156449 --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/test/StyledTestOutput.groovy @@ -0,0 +1,64 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import org.gradle.api.DefaultTask +import org.gradle.api.internal.tasks.testing.DecoratingTestDescriptor +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.testing.Test +import org.gradle.api.tasks.testing.TestDescriptor +import org.gradle.api.tasks.testing.TestResult +import org.gradle.logging.StyledTextOutput +import org.gradle.logging.StyledTextOutputFactory + +import static org.gradle.logging.StyledTextOutput.Style + +/** + * Adapted (copied) from https://github.com/brunodecarvalho/gradle-plugins/blob/master/colored-test-output.gradle + */ +class StyledTestOutput extends DefaultTask { + + @TaskAction + void addStyledOutputToTestTasks() { + StyledTextOutput out = project.services.get(StyledTextOutputFactory).create("styled-test-output") + out.style(Style.Normal) + + project.tasks.withType(Test) { Test test -> + test.beforeSuite { DecoratingTestDescriptor descriptor -> + if (descriptor.className) { + out.println() + out.println(descriptor.className) + } + } + + test.afterTest { TestDescriptor descriptor, TestResult result -> + StyledTextOutput.Style style = getStyleForResult(result) + out.withStyle(style).println(" ${descriptor.name}") + } + } + } + + private StyledTextOutput.Style getStyleForResult(TestResult result) { + StyledTextOutput.Style style = Style.Identifier + + if (result.failedTestCount > 0) { + style = Style.Failure + } else if (result.skippedTestCount > 0) { + style = Style.ProgressStatus + } + style + } +} diff --git a/src/main/groovy/com/bancvue/gradle/test/TestExtPlugin.groovy b/src/main/groovy/com/bancvue/gradle/test/TestExtPlugin.groovy new file mode 100644 index 0000000..4e48bed --- /dev/null +++ b/src/main/groovy/com/bancvue/gradle/test/TestExtPlugin.groovy @@ -0,0 +1,115 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import com.bancvue.gradle.GradlePluginMixin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.bundling.Jar +import org.gradle.api.tasks.testing.Test + +@Mixin(GradlePluginMixin) +class TestExtPlugin implements Plugin { + + static final String PLUGIN_NAME = "test-ext" + + static Jar getMainTestJarTaskOrNullIfMainTestConfigurationNotDefined(Project project) { + project.tasks.findByName("mainTestJar") + } + + + private Project project + + @Override + void apply(Project project) { + this.project = project + project.apply(plugin: "java") + addMainTestConfigurationIfMainTestDirDefined() + updateTestLoggersToWriteStackTracesOnTestFailure() + udpateTestLoggersToWriteSkippedTestEvents() + addStyledTestOutputTask() + } + + private void addMainTestConfigurationIfMainTestDirDefined() { + if (project.file("src/mainTest").exists()) { + addMainTestConfiguration() + addMainTestSourceSet() + addMainTestJarTask() + updateTestSourceSetToIncludeMainTestConfiguration() + } + } + + private void addMainTestConfiguration() { + createNamedConfigurationExtendingFrom("mainTest", "compile", "runtime") + } + + private void addMainTestSourceSet() { + project.sourceSets { + mainTest { + compileClasspath = main.output + project.configurations.mainTestCompile + runtimeClasspath = mainTest.output + main.output + project.configurations.mainTestRuntime + } + } + } + + private void addMainTestJarTask() { + Task mainTestJarTask = project.tasks.create("mainTestJar", Jar) + mainTestJarTask.configure { + group = "Build" + classifier = "test" + description = "Assembles a jar archive containing the test sources." + from project.sourceSets.mainTest.allSource + } + } + + private void updateTestSourceSetToIncludeMainTestConfiguration() { + project.sourceSets { + test { + compileClasspath = main.output + mainTest.output + compileClasspath + + project.configurations.mainTestCompile + runtimeClasspath = main.output + test.output + project.sourceSets.mainTest.output + runtimeClasspath + + project.configurations.mainTestRuntime + } + } + } + + private void updateTestLoggersToWriteStackTracesOnTestFailure() { + project.tasks.withType(Test) { Test test -> + test.testLogging.exceptionFormat = "full" + test.testLogging.stackTraceFilters("groovy") + } + } + + private void udpateTestLoggersToWriteSkippedTestEvents() { + project.tasks.withType(Test) { Test test -> + test.testLogging.events("skipped") + } + } + + private void addStyledTestOutputTask() { + StyledTestOutput stoTask = project.tasks.create("styledTestOutput", StyledTestOutput) + stoTask.configure { + group = "Verification" + description = "Modifies build to output test results incrementally" + } + + project.tasks.withType(Test) { Test test -> + test.mustRunAfter stoTask + } + } + +} diff --git a/src/main/resources/META-INF/gradle-plugins/bancvue.properties b/src/main/resources/META-INF/gradle-plugins/bancvue.properties new file mode 100644 index 0000000..2cfd0bd --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/bancvue.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.BancvueProjectPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/component-test.properties b/src/main/resources/META-INF/gradle-plugins/component-test.properties new file mode 100644 index 0000000..4421244 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/component-test.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.test.ComponentTestPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/custom-gradle.properties b/src/main/resources/META-INF/gradle-plugins/custom-gradle.properties new file mode 100644 index 0000000..19cc040 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/custom-gradle.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.custom.CustomGradlePlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/ide-ext.properties b/src/main/resources/META-INF/gradle-plugins/ide-ext.properties new file mode 100644 index 0000000..a69213a --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/ide-ext.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.IdeExtPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/integration-test.properties b/src/main/resources/META-INF/gradle-plugins/integration-test.properties new file mode 100644 index 0000000..353b437 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/integration-test.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.test.IntegrationTestPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/maven-publish-ext.properties b/src/main/resources/META-INF/gradle-plugins/maven-publish-ext.properties new file mode 100644 index 0000000..3dab0a9 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/maven-publish-ext.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.maven.MavenPublishExtPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/pmdcpd.properties b/src/main/resources/META-INF/gradle-plugins/pmdcpd.properties new file mode 100644 index 0000000..71ca1b2 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/pmdcpd.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.pmd.PmdCpdPlugin diff --git a/src/main/resources/META-INF/gradle-plugins/project-defaults.properties b/src/main/resources/META-INF/gradle-plugins/project-defaults.properties new file mode 100644 index 0000000..5090734 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/project-defaults.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.ProjectDefaultsPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/project-support.properties b/src/main/resources/META-INF/gradle-plugins/project-support.properties new file mode 100644 index 0000000..1ab79b3 --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/project-support.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.ProjectSupportPlugin \ No newline at end of file diff --git a/src/main/resources/META-INF/gradle-plugins/test-ext.properties b/src/main/resources/META-INF/gradle-plugins/test-ext.properties new file mode 100644 index 0000000..aa95aea --- /dev/null +++ b/src/main/resources/META-INF/gradle-plugins/test-ext.properties @@ -0,0 +1 @@ +implementation-class=com.bancvue.gradle.test.TestExtPlugin \ No newline at end of file diff --git a/src/mainTest/groovy/com/bancvue/gradle/test/AbstractPluginIntegrationTest.groovy b/src/mainTest/groovy/com/bancvue/gradle/test/AbstractPluginIntegrationTest.groovy new file mode 100644 index 0000000..46b1b52 --- /dev/null +++ b/src/mainTest/groovy/com/bancvue/gradle/test/AbstractPluginIntegrationTest.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import org.gradle.testkit.functional.ExecutionResult +import org.gradle.testkit.functional.GradleRunner +import org.gradle.testkit.functional.GradleRunnerFactory +import org.junit.Before +import org.junit.Rule +import org.junit.rules.TemporaryFolder + +class AbstractPluginIntegrationTest { + + @Rule + public TemporaryFolder projectDir = new TemporaryFolder() + protected GradleRunner runner + + @Before + void setUpRunner() { + runner = GradleRunnerFactory.create() + runner.directory = projectDir.root + } + + protected ExecutionResult run(String... args) { + runner.arguments.addAll(args) + + runner.run() + } + +} diff --git a/src/mainTest/groovy/com/bancvue/gradle/test/TaskExtensions.groovy b/src/mainTest/groovy/com/bancvue/gradle/test/TaskExtensions.groovy new file mode 100644 index 0000000..6b98421 --- /dev/null +++ b/src/mainTest/groovy/com/bancvue/gradle/test/TaskExtensions.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2013 BancVue, LTD + * + * 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 + * + * http://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 com.bancvue.gradle.test + +import org.gradle.api.Task + + +class TaskExtensions { + + static void assertMustRunAfter(Task self, String taskName) { + Task task = self.getProject().getTasks().getByName(taskName) + assertMustRunAfter(self, task) + } + + static void assertMustRunAfter(Task self, Task task) { + Set dependencies = self.getMustRunAfter().getDependencies(self) + assert dependencies.contains(task) + } + + static void assertMustRunBefore(Task self, String taskName) { + Task task = self.getProject().getTasks().getByName(taskName) + assertMustRunBefore(self, task) + } + + static void assertMustRunBefore(Task self, Task task) { + Set dependencies = task.getMustRunAfter().getDependencies(task) + assert dependencies.contains(self) + } + +} diff --git a/src/mainTest/groovy/com/bancvue/zip/ZipArchive.groovy b/src/mainTest/groovy/com/bancvue/zip/ZipArchive.groovy new file mode 100644 index 0000000..48b1e97 --- /dev/null +++ b/src/mainTest/groovy/com/bancvue/zip/ZipArchive.groovy @@ -0,0 +1,26 @@ +package com.bancvue.zip + +import java.util.zip.ZipEntry +import java.util.zip.ZipFile + + +class ZipArchive { + + private File file + private ZipFile zip + + ZipArchive(File file) { + this.file = file + this.zip = new ZipFile(file) + } + + String getContentForEntryWithNameLike(String name) { + ZipEntry entry = zip.entries().find { ZipEntry entry -> + entry.name =~ /${name}/ + } + if (entry == null) { + throw new RuntimeException("No entry with name like '${name}' in file=${file.absolutePath}") + } + zip.getInputStream(entry).text + } +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/ExecutionResult.java b/src/mainTest/java/org/gradle/testkit/functional/ExecutionResult.java new file mode 100644 index 0000000..02a6359 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/ExecutionResult.java @@ -0,0 +1,25 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional; + +public interface ExecutionResult { + + String getStandardOutput(); + + String getStandardError(); + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/GradleRunner.java b/src/mainTest/java/org/gradle/testkit/functional/GradleRunner.java new file mode 100644 index 0000000..bdca7ed --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/GradleRunner.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional; + +import java.io.File; +import java.util.List; + +public interface GradleRunner { + + File getDirectory(); + void setDirectory(File directory); + + List getArguments(); + void setArguments(List string); + + ExecutionResult run(); + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/GradleRunnerFactory.java b/src/mainTest/java/org/gradle/testkit/functional/GradleRunnerFactory.java new file mode 100644 index 0000000..6ba2979 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/GradleRunnerFactory.java @@ -0,0 +1,24 @@ +package org.gradle.testkit.functional; + +import org.gradle.testkit.functional.internal.DefaultGradleRunner; +import org.gradle.testkit.functional.internal.GradleHandleFactory; +import org.gradle.testkit.functional.internal.classpath.ClasspathInjectingGradleHandleFactory; +import org.gradle.testkit.functional.internal.toolingapi.ToolingApiGradleHandleFactory; +import org.gradle.util.ClassLoaderBackedClasspathSource; +import org.gradle.util.ClasspathSource; + +public class GradleRunnerFactory { + + public static GradleRunner create() { + GradleHandleFactory toolingApiHandleFactory = new ToolingApiGradleHandleFactory(); + + // TODO: Which class would be attached to the right classloader? Is using something from the test kit right? + Class sourceClass = GradleRunnerFactory.class; + + ClasspathSource classpathSource = new ClassLoaderBackedClasspathSource(sourceClass.getClassLoader()); + GradleHandleFactory classpathInjectingHandleFactory = new ClasspathInjectingGradleHandleFactory(classpathSource, toolingApiHandleFactory); + + return new DefaultGradleRunner(classpathInjectingHandleFactory); + } + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultExecutionResult.java b/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultExecutionResult.java new file mode 100644 index 0000000..23845c2 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultExecutionResult.java @@ -0,0 +1,38 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional.internal; + +import org.gradle.testkit.functional.ExecutionResult; + +public class DefaultExecutionResult implements ExecutionResult { + + private final String standardOutput; + private final String standardError; + + public DefaultExecutionResult(String standardOutput, String standardError) { + this.standardOutput = standardOutput; + this.standardError = standardError; + } + + public String getStandardOutput() { + return standardOutput; + } + + public String getStandardError() { + return standardError; + } +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultGradleRunner.java b/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultGradleRunner.java new file mode 100644 index 0000000..01801c4 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/DefaultGradleRunner.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional.internal; + +import org.gradle.testkit.functional.ExecutionResult; +import org.gradle.testkit.functional.GradleRunner; + +import java.io.File; +import java.util.LinkedList; +import java.util.List; + +public class DefaultGradleRunner implements GradleRunner { + + private File directory; + private List arguments = new LinkedList(); + + private final GradleHandleFactory handleFactory; + + public DefaultGradleRunner(GradleHandleFactory handleFactory) { + this.handleFactory = handleFactory; + } + + public File getDirectory() { + return directory; + } + + public void setDirectory(File directory) { + this.directory = directory; + } + + public List getArguments() { + return arguments; + } + + public void setArguments(List arguments) { + this.arguments = arguments; + } + + public ExecutionResult run() { + return start().waitForFinish(); + } + + private GradleHandle start() { + return handleFactory.start(directory, arguments); + } + + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandle.java b/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandle.java new file mode 100644 index 0000000..5e81a8b --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandle.java @@ -0,0 +1,31 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional.internal; + +import org.gradle.testkit.functional.ExecutionResult; + +public interface GradleHandle { + + String getStandardOutput(); + + String getStandardError(); + + ExecutionResult waitForFinish(); + + boolean isRunning(); + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandleFactory.java b/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandleFactory.java new file mode 100644 index 0000000..330e390 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/GradleHandleFactory.java @@ -0,0 +1,10 @@ +package org.gradle.testkit.functional.internal; + +import java.io.File; +import java.util.List; + +public interface GradleHandleFactory { + + GradleHandle start(File dir, List arguments); + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathAddingInitScriptBuilder.java b/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathAddingInitScriptBuilder.java new file mode 100644 index 0000000..bb9b142 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathAddingInitScriptBuilder.java @@ -0,0 +1,41 @@ +package org.gradle.testkit.functional.internal.classpath; + +import org.gradle.api.internal.ErroringAction; +import org.gradle.api.internal.IoActions; +import org.gradle.util.TextUtil; + +import java.io.File; +import java.io.Writer; +import java.util.List; + +public class ClasspathAddingInitScriptBuilder { + + public void build(File initScriptFile, final List classpath) { + System.out.println("FileList: " + classpath.size()); + for (File file : classpath) { + System.out.println(" ----- " + file.getAbsolutePath()); + } + + IoActions.writeTextFile(initScriptFile, new ErroringAction() { + @Override + protected void doExecute(Writer writer) throws Exception { + writer.write("allprojects {\n"); + writer.write(" buildscript {\n"); + writer.write(" dependencies {\n"); + writer.write(" classpath files(\n"); + int i = 0; + for (File file : classpath) { + writer.write(String.format(" '%s'", TextUtil.escapeString(file.getAbsolutePath()))); + if (++i != classpath.size()) { + writer.write(",\n"); + } + } + writer.write("\n"); + writer.write(" )\n"); + writer.write(" }\n"); + writer.write(" }\n"); + writer.write("}\n"); + } + }); + } +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathInjectingGradleHandleFactory.java b/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathInjectingGradleHandleFactory.java new file mode 100644 index 0000000..4e3a49b --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/classpath/ClasspathInjectingGradleHandleFactory.java @@ -0,0 +1,58 @@ +package org.gradle.testkit.functional.internal.classpath; + +import org.gradle.api.Transformer; +import org.gradle.internal.UncheckedException; +import org.gradle.testkit.functional.internal.GradleHandle; +import org.gradle.testkit.functional.internal.GradleHandleFactory; +import org.gradle.util.ClasspathSource; +import org.gradle.util.CollectionUtils; +import org.gradle.util.GFileUtils; + +import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class ClasspathInjectingGradleHandleFactory implements GradleHandleFactory { + + private final ClasspathSource classpathSource; + private final GradleHandleFactory delegateFactory; + + public ClasspathInjectingGradleHandleFactory(ClasspathSource classpathSource, GradleHandleFactory delegateFactory) { + this.classpathSource = classpathSource; + this.delegateFactory = delegateFactory; + } + + public GradleHandle start(File directory, List arguments) { + File testKitDir = new File(directory, ".gradle-test-kit"); + if (!testKitDir.exists()) { + GFileUtils.mkdirs(testKitDir); + } + + File initScript = new File(testKitDir, "init.gradle"); + new ClasspathAddingInitScriptBuilder().build(initScript, getClasspathAsFiles()); + + List ammendedArguments = new ArrayList(arguments.size() + 2); + ammendedArguments.add("-I"); + ammendedArguments.add(initScript.getAbsolutePath()); + ammendedArguments.addAll(arguments); + return delegateFactory.start(directory, ammendedArguments); + } + + private List getClasspathAsFiles() { + List classpathUrls = new LinkedList(); + classpathSource.collectClasspath(classpathUrls); + return CollectionUtils.collect(classpathUrls, new ArrayList(classpathUrls.size()), new Transformer() { + public File transform(URL url) { + try { + return new File(url.toURI()); + } catch (URISyntaxException e) { + throw UncheckedException.throwAsUncheckedException(e); + } + } + }); + } + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/BuildLauncherBackedGradleHandle.java b/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/BuildLauncherBackedGradleHandle.java new file mode 100644 index 0000000..a8a4185 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/BuildLauncherBackedGradleHandle.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gradle.testkit.functional.internal.toolingapi; + +import org.gradle.testkit.functional.ExecutionResult; +import org.gradle.testkit.functional.internal.DefaultExecutionResult; +import org.gradle.testkit.functional.internal.GradleHandle; +import org.gradle.tooling.BuildLauncher; +import org.gradle.tooling.GradleConnectionException; +import org.gradle.tooling.ResultHandler; + +import java.io.ByteArrayOutputStream; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; + +public class BuildLauncherBackedGradleHandle implements GradleHandle { + + final private ByteArrayOutputStream standardOutput = new ByteArrayOutputStream(); + final private ByteArrayOutputStream standardError = new ByteArrayOutputStream(); + + private final CountDownLatch runningLatch = new CountDownLatch(1); + private final AtomicBoolean running = new AtomicBoolean(true); + + private RuntimeException exception; + + public BuildLauncherBackedGradleHandle(BuildLauncher launcher) { + launcher.setStandardOutput(standardOutput); + launcher.setStandardError(standardError); + + launcher.run(new ResultHandler() { + public void onComplete(Void result) { + finish(); + } + + public void onFailure(GradleConnectionException failure) { + exception = failure; + finish(); + } + }); + } + + private void finish() { + running.set(false); + runningLatch.countDown(); + } + + public String getStandardOutput() { + return standardOutput.toString(); + } + + public String getStandardError() { + return standardError.toString(); + } + + public ExecutionResult waitForFinish() { + try { + runningLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + if (exception == null) { + return new DefaultExecutionResult(getStandardOutput(), getStandardError()); + } else { + throw exception; + } + } + + public boolean isRunning() { + return running.get(); + } + +} diff --git a/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/ToolingApiGradleHandleFactory.java b/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/ToolingApiGradleHandleFactory.java new file mode 100644 index 0000000..e113088 --- /dev/null +++ b/src/mainTest/java/org/gradle/testkit/functional/internal/toolingapi/ToolingApiGradleHandleFactory.java @@ -0,0 +1,24 @@ +package org.gradle.testkit.functional.internal.toolingapi; + +import org.gradle.testkit.functional.internal.GradleHandle; +import org.gradle.testkit.functional.internal.GradleHandleFactory; +import org.gradle.tooling.BuildLauncher; +import org.gradle.tooling.GradleConnector; +import org.gradle.tooling.ProjectConnection; + +import java.io.File; +import java.util.List; + +public class ToolingApiGradleHandleFactory implements GradleHandleFactory { + + public GradleHandle start(File directory, List arguments) { + GradleConnector connector = GradleConnector.newConnector(); + connector.forProjectDirectory(directory); + ProjectConnection connection = connector.connect(); + BuildLauncher launcher = connection.newBuild(); + String[] argumentArray = new String[arguments.size()]; + arguments.toArray(argumentArray); + launcher.withArguments(argumentArray); + return new BuildLauncherBackedGradleHandle(launcher); + } +} diff --git a/src/test/groovy/com/bancvue/gradle/AbstractPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/AbstractPluginTest.groovy new file mode 100644 index 0000000..8828323 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/AbstractPluginTest.groovy @@ -0,0 +1,45 @@ +package com.bancvue.gradle + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Before +import org.junit.Rule +import org.junit.rules.TemporaryFolder + + +abstract class AbstractPluginTest { + + @Rule + public TemporaryFolder projectDir = new TemporaryFolder() + protected Project project + protected String pluginName + + AbstractPluginTest(String pluginName) { + this.pluginName = pluginName + } + + @Before + void setUpProject() { + project = createProject() + } + + protected Project createProject() { + ProjectBuilder.builder() + .withName("${pluginName}-project") + .withProjectDir(projectDir.root) + .build() + } + + protected void applyPlugin() { + project.apply(plugin: pluginName) + } + + protected void assertNamedPluginApplied(String pluginName) { + assert project.plugins.getPlugin(pluginName) != null + } + + protected void setArtifactId(String artifactId) { + project.ext['artifactId'] = artifactId + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/BancvueProjectPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/BancvueProjectPluginTest.groovy new file mode 100644 index 0000000..61048a7 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/BancvueProjectPluginTest.groovy @@ -0,0 +1,94 @@ +package com.bancvue.gradle + +import com.bancvue.gradle.maven.MavenPublishExtPlugin +import com.bancvue.gradle.test.ComponentTestPlugin +import com.bancvue.gradle.test.TestExtPlugin +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.rules.ExpectedException + +class BancvueProjectPluginTest extends AbstractPluginTest { + + @Rule + public ExpectedException exception = ExpectedException.none() + + BancvueProjectPluginTest() { + super(BancvueProjectPlugin.PLUGIN_NAME) + } + + @Before + void setUp() { + project.version = '1.0' + setArtifactId('bancvue') + } + + @Test + void apply_ShouldApplyGroovyPlugin() { + applyPlugin() + + assertNamedPluginApplied('groovy') + } + + @Test + void apply_ShouldFail_IfVersionNotDefined() { + exception.expect(BancvueProjectPlugin.VersionNotDefinedException) + project = ProjectBuilder.builder().withName('project').build() + setArtifactId('bancvue') + + applyPlugin() + } + + @Test + void apply_ShouldFail_IfArtifactIdNotDefined() { + exception.expect(BancvueProjectPlugin.ArtifactIdNotDefinedException) + project = ProjectBuilder.builder().withName('project').build() + project.version = '1.0' + + applyPlugin() + } + + @Test + void apply_ShouldApplyBancvueIdePlugin() { + applyPlugin() + + assertNamedPluginApplied(IdeExtPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyBancvuePublishPlugin() { + applyPlugin() + + assertNamedPluginApplied(MavenPublishExtPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyTestExtPlugin() { + applyPlugin() + + assertNamedPluginApplied(TestExtPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyBancvueComponentTestPlugin() { + applyPlugin() + + assertNamedPluginApplied(ComponentTestPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyBancvueUtilitiesPlugin() { + applyPlugin() + + assertNamedPluginApplied(ProjectSupportPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyBancvueDefaultsPlugin() { + applyPlugin() + + assertNamedPluginApplied(ProjectDefaultsPlugin.PLUGIN_NAME) + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/DefaultProjectPropertyContainerTest.groovy b/src/test/groovy/com/bancvue/gradle/DefaultProjectPropertyContainerTest.groovy new file mode 100644 index 0000000..6413333 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/DefaultProjectPropertyContainerTest.groovy @@ -0,0 +1,52 @@ +package com.bancvue.gradle + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Before +import org.junit.Test + + +class DefaultProjectPropertyContainerTest { + + static class TestContainer extends DefaultProjectPropertyContainer { + + String value + + TestContainer(Project project) { + super(project, "test") + } + } + + + private Project project + private TestContainer container + + @Before + void setUp() { + project = ProjectBuilder.builder().build() + container = new TestContainer(project) + } + + @Test + void propertyAccess_ShouldUseProjectDefault_IfProjectDefaultValueProvided() { + project.ext["testValue"] = "projectDefaultValue" + + assert container.value == "projectDefaultValue" + } + + @Test + void propertyAccess_ShouldUseProjectDefault_IfProjectDefaultAndPropertyValueProvided() { + project.ext["testValue"] = "projectDefaultValue" + container.value = "propertyValue" + + assert container.value == "projectDefaultValue" + } + + @Test + void propertyAccess_ShouldUsePropertyValue_IfProjectDefaultNotProvided() { + container.value = "propertyValue" + + assert container.value == "propertyValue" + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/IdeExtPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/IdeExtPluginTest.groovy new file mode 100644 index 0000000..3e60c92 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/IdeExtPluginTest.groovy @@ -0,0 +1,25 @@ +package com.bancvue.gradle + +import org.junit.Test + +class IdeExtPluginTest extends AbstractPluginTest { + + IdeExtPluginTest() { + super(IdeExtPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldApplyIdeaPlugin() { + applyPlugin() + + assertNamedPluginApplied('idea') + } + + @Test + void apply_ShouldApplyEclipsePlugin() { + applyPlugin() + + assertNamedPluginApplied('eclipse') + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/ProjectDefaultsPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/ProjectDefaultsPluginTest.groovy new file mode 100644 index 0000000..317d75d --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/ProjectDefaultsPluginTest.groovy @@ -0,0 +1,112 @@ +package com.bancvue.gradle + +import org.gradle.api.tasks.TaskCollection +import org.gradle.api.tasks.compile.GroovyCompile +import org.gradle.api.tasks.compile.JavaCompile +import org.junit.Before +import org.junit.Test + +class ProjectDefaultsPluginTest extends AbstractPluginTest { + + ProjectDefaultsPluginTest() { + super(ProjectDefaultsPlugin.PLUGIN_NAME) + } + + @Before + void setUp() { + project.version = '1.0' + setArtifactId('bancvue') + } + + @Test + void apply_ShouldSetGroupNameToBancvue() { + applyPlugin() + + project.group == 'com.bancvue' + } + + @Test + void apply_ShouldSetJarBaseNameToArtifactId_IfArtifactIdSet() { + setArtifactId('some-artifact') + + applyPlugin() + + assert project.jar.baseName == 'some-artifact' + } + + @Test + void apply_ShouldApplyJavaPluginAndSetCompatibility() { + project.ext.defaultsJavaVersion = '1.8' + + applyPlugin() + + assertNamedPluginApplied('java') + assert "${project.sourceCompatibility}" == '1.8' + assert "${project.targetCompatibility}" == '1.8' + } + + @Test + void apply_ShouldSetCompilerEncodingToUtf8() { + applyPlugin() + + TaskCollection tasks = project.tasks.withType(JavaCompile) + assert tasks.size() > 0 + tasks.each { JavaCompile task -> + assert task.options.encoding == 'UTF-8' + } + } + + @Test + void apply_ShouldSetMemorySettingsForJavaAndGroovyCompileTasks() { + project.ext.defaultsMinHeapSize = '16m' + project.ext.defaultsMaxHeapSize = '24m' + project.ext.defaultsMaxPermSize = '8m' + + project.apply(plugin: 'groovy') + applyPlugin() + + TaskCollection javaTasks = project.tasks.withType(JavaCompile) + assert javaTasks.size() > 0 + javaTasks.each { JavaCompile compile -> + assert compile.options.forkOptions.memoryInitialSize == '16m' + assert compile.options.forkOptions.memoryMaximumSize == '24m' + assert compile.options.forkOptions.jvmArgs.contains('-XX:MaxPermSize=8m') + } + + TaskCollection groovyTasks = project.tasks.withType(GroovyCompile) + assert groovyTasks.size() > 0 + groovyTasks.each { GroovyCompile compile -> + assert compile.groovyOptions.forkOptions.memoryInitialSize == '16m' + assert compile.groovyOptions.forkOptions.memoryMaximumSize == '24m' + assert compile.groovyOptions.forkOptions.jvmArgs.contains('-XX:MaxPermSize=8m') + } + } + + @Test + void apply_ShouldSetHeapSizeForTestTasks() { + project.ext.defaultsMinTestHeapSize = '17m' + project.ext.defaultsMaxTestHeapSize = '23m' + project.ext.defaultsMaxTestPermSize = '5m' + + applyPlugin() + + TaskCollection tasks = project.tasks.withType(org.gradle.api.tasks.testing.Test) + assert tasks.size() > 0 + tasks.each { org.gradle.api.tasks.testing.Test test -> + assert test.minHeapSize == '17m' + assert test.maxHeapSize == '23m' + assert test.jvmArgs.contains('-XX:MaxPermSize=5m') + } + } + + @Test + void apply_ShouldAddBuildDateAndJdkToJarManifest() { + String expectedJavaVersion = System.getProperty('java.version') + + applyPlugin() + + assert project.jar.manifest.attributes['Built-Date'] != null + assert project.jar.manifest.attributes['Build-Jdk'] == expectedJavaVersion + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/ProjectSupportPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/ProjectSupportPluginTest.groovy new file mode 100644 index 0000000..3fb0ed6 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/ProjectSupportPluginTest.groovy @@ -0,0 +1,38 @@ +package com.bancvue.gradle + +import com.bancvue.gradle.tasks.ClearArtifactCache +import com.bancvue.gradle.tasks.PrintClasspath +import org.junit.Before +import org.junit.Test + +class ProjectSupportPluginTest extends AbstractPluginTest { + + + ProjectSupportPluginTest() { + super(ProjectSupportPlugin.PLUGIN_NAME) + } + + @Before + void setUp() { + setArtifactId('1.0') + } + + @Test + void apply_ShouldAddPrintClasspathTask() { + assert project.tasks.withType(PrintClasspath).isEmpty() + + applyPlugin() + + assert !project.tasks.withType(PrintClasspath).isEmpty() + } + + @Test + void apply_ShouldAddClearGroupCacheTask() { + assert project.tasks.findByName('clearGroupCache') == null + + applyPlugin() + + assert project.tasks.findByName('clearGroupCache') instanceof ClearArtifactCache + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/maven/MavenPublishExtPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/maven/MavenPublishExtPluginTest.groovy new file mode 100644 index 0000000..c77e87c --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/maven/MavenPublishExtPluginTest.groovy @@ -0,0 +1,136 @@ +package com.bancvue.gradle.maven + +import com.bancvue.gradle.AbstractPluginTest +import org.gradle.api.Task +import org.gradle.api.artifacts.ArtifactRepositoryContainer +import org.gradle.api.artifacts.repositories.MavenArtifactRepository +import org.gradle.api.publish.maven.tasks.PublishToMavenLocal +import org.gradle.api.publish.maven.tasks.PublishToMavenRepository +import org.gradle.api.tasks.bundling.Jar +import org.junit.Before +import org.junit.Test + +class MavenPublishExtPluginTest extends AbstractPluginTest { + + MavenPublishExtPluginTest() { + super(MavenPublishExtPlugin.PLUGIN_NAME) + } + + @Before + void setUp() { + setArtifactId('1.0') + } + + @Test + void apply_ShouldApplyMavenPlugins() { + applyPlugin() + + assertNamedPluginApplied('maven-publish') + } + + @Test + void apply_ShouldAddNexusDependencyRepository() { + project.ext.repositoryName = 'repo' + project.ext.repositoryPublicUrl = 'http://public-url' + + applyPlugin() + + MavenArtifactRepository nexusRepo = getMavenRepo('repo') + assert nexusRepo != null + assert nexusRepo.url.toString() == 'http://public-url' + } + + private MavenArtifactRepository getMavenRepo(String name) { + project.repositories.getByName(name) as MavenArtifactRepository + } + + @Test + void apply_ShouldAddMavenLocalDependencyRepository() { + applyPlugin() + + MavenArtifactRepository mavenLocal = getMavenRepo(ArtifactRepositoryContainer.DEFAULT_MAVEN_LOCAL_REPO_NAME) + assert mavenLocal != null + } + + private MavenArtifactRepository getMavenPublishingRepo(String name) { + project.publishing.repositories.getByName(name) + } + + @Test + void apply_ShouldAddNexusSnapshotPublishingRepository_IfVersionSnapshot() { + project.version = '1.0-SNAPSHOT' + project.ext.repositoryName = 'repo' + project.ext.repositorySnapshotUrl = 'http://snapshot-url' + + applyPlugin() + + MavenArtifactRepository nexusRepo = getMavenPublishingRepo('repo') + assert nexusRepo.url.toString() == 'http://snapshot-url' + } + + @Test + void apply_ShouldAddNexusReleasePublishingRepository_IfVersionNotSnapshot() { + project.version = '1.0' + project.ext.repositoryName = 'repo' + project.ext.repositoryReleaseUrl = 'http://release-url' + + applyPlugin() + + MavenArtifactRepository nexusRepo = getMavenPublishingRepo('repo') + assert nexusRepo.url.toString() == 'http://release-url' + } + + private Task acquireSingleDependencyForTask(String taskName) { + List dependencies = getDependenciesForTask(taskName) + assert dependencies.size() == 1 + dependencies[0] + } + + private List getDependenciesForTask(String taskName) { + Task task = project.tasks.findByName(taskName) + task.taskDependencies.getDependencies(task).toList() + } + + @Test + void apply_ShouldRemapPublishTaskToPublishRemote() { + applyPlugin() + project.evaluate() + + Task publishRemoteDependency = acquireSingleDependencyForTask('publishRemote') + assert publishRemoteDependency instanceof PublishToMavenRepository + assert !(publishRemoteDependency instanceof PublishToMavenLocal) + } + + @Test + void apply_ShouldRemapPublishToMavenLocalTaskToPublish() { + applyPlugin() + project.evaluate() + + Task publishRemoteDependency = acquireSingleDependencyForTask('publish') + assert publishRemoteDependency instanceof PublishToMavenLocal + } + + @Test + void apply_ShouldNotCreatePublishArtifactTasks_IfCustomPublicationDefined() { + project.ext.customPublication = true + applyPlugin() + project.evaluate() + + List dependencies = getDependenciesForTask('publish') + assert dependencies.size() == 0 + } + + @Test + void getBaseNameForTask_ShouldUseTaskBaseName_IfProjectArtifactIdNotDefined() { + project = createProject() // re-create project since artifactId is set as part of setUp + Jar jarTask = project.tasks.create('jarTask', Jar) + jarTask.baseName = 'someName' + MavenPublishExtPlugin plugin = new MavenPublishExtPlugin() + plugin.project = project + + String baseName = plugin.getBaseNameForTask(jarTask) + + assert baseName == 'someName' + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/maven/MavenRepositoryPropertiesTest.groovy b/src/test/groovy/com/bancvue/gradle/maven/MavenRepositoryPropertiesTest.groovy new file mode 100644 index 0000000..90d47ae --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/maven/MavenRepositoryPropertiesTest.groovy @@ -0,0 +1,54 @@ +package com.bancvue.gradle.maven + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Before +import org.junit.Test + + +class MavenRepositoryPropertiesTest { + + private Project project + private MavenRepositoryProperties properties + + @Before + void setUp() { + project = ProjectBuilder.builder().build() + properties = new MavenRepositoryProperties(project) + } + + @Test + void hasCredentialsDefined_ShouldReturnFalse_IfUsernameOnlyDefined() { + properties.username = "username" + + assert !properties.hasCredentialsDefined() + } + + @Test + void hasCredentialsDefined_ShouldReturnFalse_IfPasswordOnlyDefined() { + properties.password = "password" + + assert !properties.hasCredentialsDefined() + } + + @Test + void hasCredentialsDefined_ShouldReturnFalse_IfUsernameAndPasswordNotDefined() { + assert !properties.hasCredentialsDefined() + } + + @Test + void hasCredentialsDefined_ShouldReturnTrue_IfUsernameAndPasswordDefined() { + properties.username = "username" + properties.password = "password" + + assert properties.hasCredentialsDefined() + } + + @Test + void hasCredentialsDefined_ShouldReturnTrue_IfUsernameAndPasswordDefinedOnProject() { + project.ext["repositoryUsername"] = 'username' + project.ext["repositoryPassword"] = 'password' + + assert properties.hasCredentialsDefined() + } +} diff --git a/src/test/groovy/com/bancvue/gradle/pmd/PmdCpdPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/pmd/PmdCpdPluginTest.groovy new file mode 100644 index 0000000..473f565 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/pmd/PmdCpdPluginTest.groovy @@ -0,0 +1,67 @@ +package com.bancvue.gradle.pmd + +import com.bancvue.gradle.AbstractPluginTest +import com.google.common.io.Files +import org.junit.Before +import org.junit.Test + +class PmdCpdPluginTest extends AbstractPluginTest { + + PmdCpdPluginTest() { + super(PmdCpdPlugin.PLUGIN_NAME) + } + + @Before + void setup() { + project.apply(plugin: 'java') + project.apply(plugin: PmdCpdPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldConfigureTaskFromExtension() { + project.sourceSets { + main + } + + CpdExtension extension = new CpdExtension() + int expectedMinimumTokenCount = extension.minimumTokenCount + 10 + boolean expectedIgnoreLiterals = !extension.ignoreLiterals + boolean expectedIgnoreIdentifiers = !extension.ignoreIdentifiers + boolean expectedIgnoreFailures = !extension.ignoreFailures + File expectedReportsDir = Files.createTempDir() + project.cpd { + ignoreFailures = expectedIgnoreFailures + minimumTokenCount = expectedMinimumTokenCount + ignoreLiterals = expectedIgnoreLiterals + ignoreIdentifiers = expectedIgnoreIdentifiers + reportsDir = expectedReportsDir + } + + project.tasks.withType(Cpd) { Cpd task -> + assert task != null + assert task.ignoreFailures == expectedIgnoreFailures + assert task.ignoreLiterals == expectedIgnoreLiterals + assert task.ignoreIdentifiers == expectedIgnoreIdentifiers + assert task.minimumTokenCount == expectedMinimumTokenCount + assert task.reportDir == expectedReportsDir + } + } + + @Test + void apply_ShouldUseExtensionDefaults_IfValuesNotProvidedInTask() { + project.sourceSets { + main + } + + CpdExtension extension = new CpdExtension() + project.tasks.withType(Cpd) { Cpd task -> + assert task != null + assert task.ignoreFailures == extension.ignoreIdentifiers + assert task.ignoreLiterals == extension.ignoreLiterals + assert task.ignoreIdentifiers == extension.ignoreIdentifiers + assert task.minimumTokenCount == extension.minimumTokenCount + assert task.reportDir == new File(project.buildDir, 'reports/cpd') + } + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/tasks/ClearArtifactCacheTest.groovy b/src/test/groovy/com/bancvue/gradle/tasks/ClearArtifactCacheTest.groovy new file mode 100644 index 0000000..ccc96e3 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/tasks/ClearArtifactCacheTest.groovy @@ -0,0 +1,36 @@ +package com.bancvue.gradle.tasks + +import com.google.common.io.Files +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import org.junit.Before +import org.junit.Test + +class ClearArtifactCacheTest { + + private ClearArtifactCache task + + @Before + void setUp() { + Project project = ProjectBuilder.builder().build() + task = project.tasks.create('clearArtifactCache', ClearArtifactCache) + } + + @Test + void collectGradleCacheDirsWithName() { + task.groupName = 'com.bancvue' + File tempDir = Files.createTempDir() + createDirs(tempDir, ['com.bancvue', 'subdir/com.bancvue', 'nomatch', 'com.bancvue.nomatch']) + + List dirsWithName = task.collectGradleCacheDirsWithName(tempDir, 'com.bancvue') + + assert dirsWithName == [new File(tempDir, 'com.bancvue'), new File(tempDir, 'subdir/com.bancvue')] + } + + private void createDirs(File parent, List dirNames) { + dirNames.each { String dirName -> + new File(parent, dirName).mkdirs() + } + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/test/ComponentTestPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/test/ComponentTestPluginTest.groovy new file mode 100644 index 0000000..e74d433 --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/test/ComponentTestPluginTest.groovy @@ -0,0 +1,28 @@ +package com.bancvue.gradle.test + +import com.bancvue.gradle.AbstractPluginTest +import org.gradle.api.Task +import org.junit.Before +import org.junit.Test + +class ComponentTestPluginTest extends AbstractPluginTest { + + ComponentTestPluginTest() { + super(ComponentTestPlugin.PLUGIN_NAME) + } + + @Before + void setUp() { + project.file('src/componentTest').mkdirs() + } + + @Test + void apply_ShouldAddComponentTestAsCheckDependency() { + applyPlugin() + + Task checkTask = project.tasks.getByName('check') + Set checkDependencies = checkTask.getDependsOn() + assert checkDependencies.contains(project.tasks.getByName('componentTest')) + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/test/NamedTestConfigurationPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/test/NamedTestConfigurationPluginTest.groovy new file mode 100644 index 0000000..eed2b2d --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/test/NamedTestConfigurationPluginTest.groovy @@ -0,0 +1,82 @@ +package com.bancvue.gradle.test + +import com.bancvue.gradle.AbstractPluginTest +import org.gradle.api.Task +import org.junit.Before +import org.junit.Test + +class NamedTestConfigurationPluginTest extends AbstractPluginTest { + + static class FunctionalTestPlugin extends NamedTestConfigurationPlugin { + + FunctionalTestPlugin() { + super('functionalTest') + } + } + + NamedTestConfigurationPluginTest() { + super("functional-test") + } + + @Before + void setUp() { + project.file('src/functionalTest').mkdirs() + } + + @Override + protected void applyPlugin() { + new FunctionalTestPlugin().apply(project) + } + + @Test + void apply_ShouldAddFunctionalTestSourceSet() { + applyPlugin() + + assert project.sourceSets.functionalTest + } + + @Test + void apply_ShouldAddFunctionalTestConfigurations() { + applyPlugin() + + assert project.configurations.functionalTest + assert project.configurations.functionalTestCompile + assert project.configurations.functionalTestCompile.extendsFrom.contains(project.configurations.testCompile) + assert project.configurations.functionalTestRuntime + assert project.configurations.functionalTestRuntime.extendsFrom.contains(project.configurations.testRuntime) + } + + @Test + void apply_ShouldNotAddFunctionalTestConfiguration_IfSrcDirDoesNotExist() { + project.file('src/functionalTest').deleteDir() + + applyPlugin() + + assert !project.configurations.findByName('functionalTest') + assert !project.tasks.findByName('functionalTest') + } + + @Test + void apply_ShouldCreateFunctionalTestTask() { + applyPlugin() + + Task functionalTestTask = project.tasks.getByName('functionalTest') + assert functionalTestTask + assert functionalTestTask.group == 'Verification' + assert functionalTestTask.testClassesDir == project.sourceSets.functionalTest.output.classesDir + assert functionalTestTask.classpath == project.sourceSets.functionalTest.runtimeClasspath + assert functionalTestTask.testReportDir == new File(project.buildDir, 'reports/functionalTests') + assert functionalTestTask.testResultsDir == new File(project.buildDir, 'functionalTest-results') + } + + @Test + void apply_ShouldConfigureFunctionalTestToRunAfterUnitTest() { + applyPlugin() + + Task functionalTestTask = project.tasks.getByName('functionalTest') + use(TaskExtensions) { + functionalTestTask.assertMustRunAfter('test') + } + } + +} diff --git a/src/test/groovy/com/bancvue/gradle/test/TestExtPluginTest.groovy b/src/test/groovy/com/bancvue/gradle/test/TestExtPluginTest.groovy new file mode 100644 index 0000000..139d31f --- /dev/null +++ b/src/test/groovy/com/bancvue/gradle/test/TestExtPluginTest.groovy @@ -0,0 +1,44 @@ +package com.bancvue.gradle.test + +import com.bancvue.gradle.AbstractPluginTest +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.gradle.api.tasks.testing.logging.TestStackTraceFilter +import org.junit.Test + +class TestExtPluginTest extends AbstractPluginTest { + + TestExtPluginTest() { + super(TestExtPlugin.PLUGIN_NAME) + } + + @Test + void apply_ShouldWriteStackTraceOnTestFailure() { + applyPlugin() + + org.gradle.api.tasks.testing.Test test = project.tasks.getByName('test') + + assert test.testLogging.exceptionFormat == TestExceptionFormat.FULL + assert test.testLogging.stackTraceFilters.contains(TestStackTraceFilter.GROOVY) + } + + @Test + void apply_ShouldWriteSkippedEvents() { + applyPlugin() + + org.gradle.api.tasks.testing.Test test = project.tasks.getByName('test') + + assert test.testLogging.events.contains(TestLogEvent.SKIPPED) + } + + @Test + void apply_ShouldAddStyledTestOutputTaskAndConfigureToExecuteBeforeTestTasks() { + applyPlugin() + + StyledTestOutput styledOutputTask = project.tasks.getByName('styledTestOutput') + use(TaskExtensions) { + styledOutputTask.assertMustRunBefore('test') + } + } + +}