Merge pull request #9 from rtyler/zero-two-zero

Zero two zero
This commit is contained in:
R. Tyler Croy 2015-08-14 13:00:59 -07:00
commit c02a5674d5
33 changed files with 1221 additions and 209 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@ build/
# Ignore Gradle GUI config
gradle-app.setting
*.sw*
.idea/
*.iml

24
.travis.yml Normal file
View File

@ -0,0 +1,24 @@
language: groovy
sudo: false
install:
- ./gradlew clean
script:
- ./gradlew -S -i
- ./gradlew -S -i gradleTest
jdk:
- oraclejdk7
- oraclejdk8
- openjdk7
os:
- linux
- osx
env: TERM=dumb
cache:
directories:
- $HOME/.gradle

View File

@ -1,31 +1,33 @@
jruby-gradle-storm-plugin
=========================
= JRuby/Gradle Storm Plugin
[![Build Status](https://buildhive.cloudbees.com/job/jruby-gradle/job/jruby-gradle-war-plugin/badge/icon)](https://buildhive.cloudbees.com/job/jruby-gradle/job/jruby-gradle-storm-plugin/) [![Gitter chat](https://badges.gitter.im/jruby-gradle/jruby-gradle-plugin.png)](https://gitter.im/jruby-gradle/jruby-gradle-plugin)
JRuby/Gradle plugin to manage creating Storm topology jars
JRuby Gradle plugin to manage creating Storm topology jars
## Usage
== Usage
**NOTE:** This plugin is stili in a very early stages.
Including the plugin:
```groovy
[source, groovy]
----
buildscript {
repositories { jcenter() }
dependencies {
classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:0.1.3+'
classpath "com.github.jruby-gradle:jruby-gradle-storm-plugin:0.2.0"
}
}
```
----
### Running a "local" topology
== Running a "local topology"
The `JRubyStormLocal` task provides the underlying machinery to run a
[redstorm](https://github.com/jruby-gradle/redstorm) topology in "local" mode:
link:https://github.com/jruby-gradle/redstorm[Redstorm] topology in "local"
mode:
```groovy
[source, groovy]
----
import com.github.jrubygradle.storm.JRubyStormLocal
task runLocalTopology(type: JRubyStormLocal) {
@ -33,14 +35,14 @@ task runLocalTopology(type: JRubyStormLocal) {
// the task is executed in
topology 'topologies/example_topology.rb'
}
```
----
Then you can run the local topology with: `./gradlew runLocalTopology`
**Note:** The Gradle script will block until the local topology is terminated
(Ctrl+C)
NOTE: The Gradle script will block until the local topology is terminated (Ctrl+C)
### Creating a topology .jar
== Creating a topolog .jar
Creating a topology `.jar` file is useflu when you plan on uploading your
topology to a running Storm cluster. *Currently* this plugin will only create

View File

@ -1,93 +1,70 @@
plugins {
id "com.github.jruby-gradle.jar" version "0.1.2"
// https://github.com/jruby-gradle/jruby-gradle-jar-plugin/issues/18
id "com.github.jruby-gradle.base" version "0.1.3"
id "com.github.johnrengelman.shadow" version "1.1.2"
id "com.jfrog.bintray" version "0.6"
}
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2"
classpath "org.ysb33r.gradle:gradletest:0.5.4"
}
}
apply plugin: 'codenarc'
apply plugin: 'groovy'
apply plugin: 'java'
apply plugin: 'maven'
apply from: 'gradle/integration-test.gradle'
apply from: 'gradle/releasing.gradle'
group = 'com.github.jruby-gradle'
version = '0.1.6'
if (System.env.RELEASE != '1') {
version = "${version}-SNAPSHOT"
}
sourceCompatibility = 1.7
version = '0.2.0'
defaultTasks 'check', 'assemble'
repositories {
jcenter()
mavenLocal()
}
dependencies {
compile gradleApi()
compile localGroovy()
compile new GradleDist(project, '2.0').asFileTree
compile group: 'com.github.jruby-gradle',
name: 'jruby-gradle-plugin',
version: '0.1.8+'
compile group: 'com.github.jruby-gradle',
name: 'jruby-gradle-jar-plugin',
version: '0.1.2+'
compile group: 'com.github.jengelman.gradle.plugins',
name: 'shadow',
version: '1.1.2+'
['jruby-gradle-plugin', 'jruby-gradle-jar-plugin'].each { String plugin ->
String pluginDependency = "com.github.jruby-gradle:${plugin}:${jrubyGradleMinVersion}"
compile pluginDependency
gradleTest pluginDependency
}
testCompile ("org.spockframework:spock-core:0.7-groovy-${gradle.gradleVersion.startsWith('1.')?'1.8':'2.0'}") {
exclude module : 'groovy-all'
}
}
plugins.withType(JavaPlugin) {
sourceCompatibility = 1.7
targetCompatibility = 1.7
project.tasks.withType(JavaCompile) { task ->
task.sourceCompatibility = project.sourceCompatibility
task.targetCompatibility = project.targetCompatibility
}
project.tasks.withType(GroovyCompile) { task ->
task.sourceCompatibility = project.sourceCompatibility
task.targetCompatibility = project.targetCompatibility
}
}
codenarc {
sourceSets = [sourceSets.main]
configFile = file('gradle/codenarc.xml')
}
test {
testLogging {
showStandardStreams = true
exceptionFormat "full"
events "passed", "skipped", "failed", "standardOut", "standardError"
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
// Ensure we don't fail in CI or on a system without these values set in
// ~/.gradle/gradle.properties
if (!hasProperty( 'bintrayUser' ))
ext.bintrayUser = ''
if (!hasProperty( 'bintrayKey' ))
ext.bintrayKey = ''
bintray {
user = project.bintrayUser
key = project.bintrayKey
publish = true
dryRun = false
configurations = ['archives']
pkg {
userOrg = 'jruby-gradle'
repo = 'plugins'
name = 'jruby-gradle-storm-plugin'
labels = ['jruby','storm','java']
version {
name = project.version
vcsTag = "v${project.version}"
attributes = ['gradle-plugin' : 'com.github.jruby-gradle.storm:com.github.jruby-gradle:jruby-gradle-storm-plugin']
desc = 'This plugin encapsulates Storm topology building functionality for JRuby Gradle projects'
}
}
}
bintrayUpload.dependsOn assemble
// vim: ft=groovy

2
buildSrc/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build/
*swp*

View File

@ -0,0 +1,44 @@
import org.gradle.api.Project
import org.gradle.api.file.FileTree
import org.gradle.wrapper.Download
import org.gradle.wrapper.Install
import org.gradle.wrapper.Logger
import org.gradle.wrapper.PathAssembler
import org.gradle.wrapper.WrapperConfiguration
/**
* Include this in your project's buildSrc, then add a dependency to your project:
* compile new GradleDist(project, '2.6').asFileTree
*
* Code courtesy of @ajoberstar
*/
class GradleDist {
private final Project project
final String version
GradleDist(Project project, String version) {
this.project = project
this.version = version
}
String getPath() {
return "https://services.gradle.org/distributions/gradle-${version}-bin.zip"
}
File getAsFile() {
return project.file(getPath())
}
URI getAsURI() {
return project.uri(getPath())
}
FileTree getAsFileTree() {
Logger logger = new Logger(true)
Install install = new Install(logger, new Download(logger, 'gradle', ''), new PathAssembler(project.gradle.gradleUserHomeDir))
WrapperConfiguration config = new WrapperConfiguration()
config.distribution = getAsURI()
File file = install.createDist(config)
return project.fileTree(dir:file, include:'**/*.jar')
}
}

2
examples/word-count/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.gradle/
build/

View File

@ -0,0 +1,45 @@
import java.util.zip.ZipFile
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jruby-gradle:jruby-gradle-jar-plugin:1.0.2'
/* Replace "%%VERSION%%" with the version of JRuby/Gradle Storm you wish to
* use if you want to use this build.gradle outside of gradleTest
*/
classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:%%VERSION%%'
//classpath 'com.github.jruby-gradle:jruby-gradle-storm-plugin:0.2.0'
}
}
apply plugin: 'com.github.jruby-gradle.storm'
jrubyStorm {
topology 'hello-topology.rb'
}
/*
* This task is only here for the execution of the gradleTest
*/
task runGradleTest {
dependsOn assembleJRubyStorm
doLast {
Task assemble = project.tasks.findByName('assembleJRubyStorm')
logger.info("${assemble.outputs.files.files}")
/* Verify we have some outputs, otherwise what's the point */
if (!assemble.outputs.files.files) {
throw new GradleException("The task ${assemble} doesn't declare outputs")
}
/* ensure our outputs contain a valid jar file (aka Zip) */
assemble.outputs.files.files.each { File jar ->
logger.info("Looking at ${jar}")
ZipFile f = new ZipFile(jar)
if ((new ZipFile(jar)).size() <= 0) {
throw new GradleException("The file ${jar} does not appear to be valid")
}
}
}
}

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Mon Jul 27 08:05:22 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip

164
examples/word-count/gradlew vendored Executable file
View File

@ -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 "$@"

90
examples/word-count/gradlew.bat vendored Normal file
View File

@ -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

View File

@ -0,0 +1,29 @@
require 'red_storm'
class HelloWorldSpout < RedStorm::DSL::Spout
on_init {@words = ["hello", "world"]}
on_send {@words.shift unless @words.empty?}
end
class HelloWorldBolt < RedStorm::DSL::Bolt
on_receive :emit => false do |tuple|
log.info(tuple[0]) # tuple[:word] or tuple["word"] are also valid
end
end
class HelloWorldTopology < RedStorm::DSL::Topology
spout HelloWorldSpout do
output_fields :word
end
bolt HelloWorldBolt do
source HelloWorldSpout, :global
end
configure do
debug false
max_task_parallelism 4
num_workers 1
max_spout_pending 1000
end
end

7
gradle.properties Normal file
View File

@ -0,0 +1,7 @@
org.gradle.daemon=true
bintrayUser=
bintrayKey=
sourceCompatibility=1.7
targetCompatibility=1.7
jrubyGradleMinVersion=1.0.2

23
gradle/codenarc.xml Normal file
View File

@ -0,0 +1,23 @@
<ruleset xmlns="http://codenarc.org/ruleset/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://codenarc.org/ruleset/1.0 http://codenarc.org/ruleset-schema.xsd"
xsi:noNamespaceSchemaLocation="http://codenarc.org/ruleset-schema.xsd">
<description>Sample rule set</description>
<ruleset-ref path='rulesets/imports.xml'>
<rule-config name='DuplicateImport'>
<property name='priority' value='1'/>
</rule-config>
</ruleset-ref>
<ruleset-ref path='rulesets/basic.xml'>
<exclude name='StringInstantiation'/>
</ruleset-ref>
<rule class='org.codenarc.rule.generic.IllegalRegexRule'>
<property name="name" value="AuthorTagNotAllowed"/>
<property name='regex' value='\@author'/>
</rule>
</ruleset>

View File

@ -0,0 +1,72 @@
import groovy.json.JsonOutput
apply plugin: 'org.ysb33r.gradletest'
configurations {
integrationTestCompile.extendsFrom testCompile, compile
integrationTestRuntime.extendsFrom testRuntime, integrationTestCompile
}
sourceSets {
integrationTest {
groovy {
srcDir file("${projectDir}/src/integTest/groovy")
}
compileClasspath = sourceSets.main.output + configurations.integrationTestCompile
runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime
}
}
task prepareGradleTestKitClasspath {
group 'Build Setup'
description 'Prepare the plugin classpath until TestKit supports it more natively'
File outputDir = file("$buildDir/$name")
inputs.files sourceSets.main.runtimeClasspath
outputs.dir outputDir
doLast {
outputDir.mkdirs()
List<String> files = sourceSets.main.runtimeClasspath.files.collect { File f -> f.absolutePath }
file("$outputDir/plugin-classpath.json").text = JsonOutput.toJson(files)
}
}
task integrationTest(type: Test) {
group 'Verification'
description 'Run the TestKit-based integration tests'
dependsOn prepareGradleTestKitClasspath, test, jar
classpath = sourceSets.integrationTest.runtimeClasspath
testClassesDir = sourceSets.integrationTest.output.classesDir
testLogging {
exceptionFormat "full"
events "passed", "skipped", "failed", "standardOut", "standardError"
}
}
check.dependsOn integrationTest
gradleTest {
versions '2.0', '2.2', '2.4', '2.6'
dependsOn test, integrationTest, jar
}
dependencies {
/* Without pruning the groovy-all dependency from this file list, we end up
* with two groovys running around and this exception at runtime:
* groovy.lang.GroovyRuntimeException: Conflicting module versions. Module [groovy-all is loaded in version 2.3.10 and you are trying to load version 2.3.3
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl$DefaultModuleListener.onModule(MetaClassRegistryImpl.java:509)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromProperties(ExtensionModuleScanner.java:77)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanExtensionModuleFromMetaInf(ExtensionModuleScanner.java:71)
at org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner.scanClasspathModules(ExtensionModuleScanner.java:53)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:110)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:71)
at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:33)
*/
integrationTestCompile files(gradleTestKit().resolve().findAll { File f ->
!f.name.matches(/groovy-all-(.*).jar/)
})
/* add our TestKit classpath to our test runtime so we can find it again */
integrationTestRuntime files(prepareGradleTestKitClasspath)
}

33
gradle/releasing.gradle Normal file
View File

@ -0,0 +1,33 @@
apply plugin: 'com.jfrog.bintray'
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives sourcesJar
}
bintray {
user = project.bintrayUser
key = project.bintrayKey
publish = true
dryRun = false
configurations = ['archives']
pkg {
userOrg = 'jruby-gradle'
repo = 'plugins'
name = 'jruby-gradle-storm-plugin'
labels = ['jruby','storm','java']
version {
name = project.version
vcsTag = "v${project.version}"
attributes = ['gradle-plugin' : 'com.github.jruby-gradle.storm:com.github.jruby-gradle:jruby-gradle-storm-plugin']
desc = 'This plugin encapsulates Storm topology building functionality for JRuby Gradle projects'
}
}
}
bintrayUpload.dependsOn assemble

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip

0
src/gradleTest/.gitkeep Normal file
View File

1
src/gradleTest/word-count Symbolic link
View File

@ -0,0 +1 @@
../../examples/word-count

View File

@ -0,0 +1,59 @@
package com.github.jrubygradle.storm
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.gradle.testkit.runner.BuildResult
import org.gradle.api.artifacts.Dependency
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.*
/** Integration tests which actually execute Gradle via the GradleTestKit */
class JRubyStormTestKitSpec extends Specification {
@Rule
final TemporaryFolder testProjectDir = new TemporaryFolder()
File buildFile
String pluginDependencies
def setup() {
buildFile = testProjectDir.newFile('build.gradle')
def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.json")
if (pluginClasspathResource == null) {
throw new IllegalStateException("Did not find plugin classpath resource, run `testClasses` build task.")
}
pluginDependencies = pluginClasspathResource.text
}
def "executing the assemble task produces a jar artifact"() {
given:
buildFile << """
buildscript {
dependencies {
classpath files(${pluginDependencies})
}
}
apply plugin: 'com.github.jruby-gradle.storm'
jrubyStorm {
}
"""
when:
BuildResult result = GradleRunner.create()
.withProjectDir(testProjectDir.root)
.withArguments('assembleJRubyStorm')
.build()
then:
File[] artifacts = (new File(testProjectDir.root, ['build', 'libs'].join(File.separator))).listFiles()
artifacts && artifacts.size() == 1
and:
result.task(":assembleJRubyStorm").outcome == TaskOutcome.SUCCESS
}
}

View File

@ -1,9 +1,113 @@
package com.github.jrubygradle.storm
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jrubygradle.JRubyPlugin
import org.gradle.api.DefaultTask
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import com.github.jrubygradle.storm.internal.JRubyStorm as JRubyStormInternal
/**
* @author R. Tyler Croy
* Implement the custom behaviors needed to build a JRubyStorm topology
*/
class JRubyStorm extends ShadowJar {
class JRubyStorm extends DefaultTask {
static final String DEFAULT_CONFIGURATION_NAME = 'jrubyStorm'
/** Dynamically created dependent task for running the topology in local mode*/
private Task runTask
/** Dynamically created dependent task for building the topology jar */
private Task assembleTask
private static final String REDSTORM_MAIN = 'redstorm.TopologyLauncher'
private static final List<String> DEFAULT_EXCLUDES = ['*.sw*',
'*.gitkeep',
'*.md',
'META-INF/BCKEY*', ]
/** Default version of redstorm to use */
protected String customRedstormVersion
/** Default version of Storm supported included */
protected String customStormVersion
/** Configuration which has all of our dependencies */
protected Configuration configuration
/** Path (absolute or relative) to the Ruby file containing the topology */
@Input
String topology
void stormVersion(String version) {
this.customStormVersion = version
}
@Input
@Optional
String getStormVersion() {
return customStormVersion ?: project.storm.defaultVersion
}
void setRedstormVersion(String version) {
this.customRedstormVersion = version
}
@Input
@Optional
String getRedstormVersion() {
return customRedstormVersion ?: project.storm.defaultRedstormVersion
}
void setConfiguration(Configuration newConfiguration) {
this.configuration = newConfiguration
}
@Input
@Optional
Configuration getConfiguration() {
return configuration ?: project.configurations.findByName(DEFAULT_CONFIGURATION_NAME)
}
JRubyStorm() {
super()
configuration = project.configurations.maybeCreate(DEFAULT_CONFIGURATION_NAME)
this.group JRubyPlugin.TASK_GROUP_NAME
this.runTask = JRubyStormInternal.createRunTask(this.project, this.name, this)
this.assembleTask = JRubyStormInternal.createAssembleTask(this.project, this.name)
project.afterEvaluate { this.updateDependencies() }
}
Configuration getLocalConfiguration() {
project.configurations.maybeCreate("${configuration.name}Local")
}
void updateDependencies() {
// Excluding storm-core for the configuration where we create the
// topology jar. This is because the running storm cluster will provide
// the classes from this dependency. If we attempt to includ ethis, the
// skorm classes will not initialize properly and you'll get exceptions
// like: "cannot load or initialize class backtype.storm.LocalCluster
project.dependencies.add(configuration.name, "com.github.jruby-gradle:redstorm:${redstormVersion}") {
exclude module: 'storm-core'
}
project.dependencies.add(localConfiguration.name, "org.apache.storm:storm-core:${stormVersion}")
localConfiguration.extendsFrom configuration
}
/**
* Set the group of this task and delegate that Group assignment to child tasks
*
* @param newGroup group name
*/
@Override
void setGroup(String newGroup) {
super.setGroup(newGroup)
/* delegate group configuration */
this.runTask?.group newGroup
this.assembleTask?.group newGroup
}
}

View File

@ -0,0 +1,23 @@
package com.github.jrubygradle.storm
/**
*
*/
class JRubyStormExtension {
/** Default version of Storm supported and included */
String defaultVersion = '0.9.2-incubating'
/** Default version of redstorm to use */
String defaultRedstormVersion = '0.7.1'
/** Set the Storm dependency version */
void defaultVersion(Object stormVersion) {
this.defaultVersion = stormVersion
}
/** Set the version of the Redstorm library to use */
void defaultRedstormVersion(Object newVersion) {
this.defaultRedstormVersion = newVersion
}
}

View File

@ -1,36 +1,50 @@
package com.github.jrubygradle.storm
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.Input
import org.gradle.api.Project
import org.gradle.api.tasks.JavaExec
import com.github.jrubygradle.internal.JRubyExecTraits
/**
* @author R. Tyler Croy
* JRubyStormLocal is a task for invoking the redstorm local topology mode for
* a given codebase
*/
class JRubyStormLocal extends JavaExec {
class JRubyStormLocal extends JavaExec implements JRubyExecTraits {
/** parent from which this task will inherit some configuration */
JRubyStorm parentTask
static void updateDependencies(Project project) {
project.tasks.withType(JRubyStormLocal) { JRubyStormLocal t ->
t.classpath project.configurations.jrubyStormLocal
/** Set a custom path (relative or absolute) to the file defining a Redstorm topology
*
* If this is not set, the parentTask's topology will be used
*/
protected String customTopology
/** Path (relative or absolute) to the .rb file defining a Redstorm topology */
@Input
String getTopology() {
return customTopology ?: parentTask?.topology
}
}
@Input
String topology
void setTopology(String topology) {
this.customTopology = topology
}
JRubyStormLocal() {
super()
super.dependsOn project.tasks.jrubyPrepare
super.setMain 'redstorm.TopologyLauncher'
}
JRubyStormLocal() {
super()
super.setMain 'redstorm.TopologyLauncher'
}
@Override
void exec() {
super.setArgs(['local', topology])
super.setEnvironment 'GEM_HOME' : project.jruby.gemInstallDir,
'GEM_PATH' : project.jruby.gemInstallDir,
'HOME' : System.env.HOME
super.exec()
}
@Override
void exec() {
logger.info("JRubyStormLocal parentTask: ${parentTask} (${parentTask.topology})")
super.setArgs(['local', topology])
super.setEnvironment getPreparedEnvironment(environment)
if (parentTask) {
super.classpath parentTask.localConfiguration.asPath
}
prepareDependencies(project)
super.exec()
}
}

View File

@ -1,65 +1,21 @@
package com.github.jrubygradle.storm
import com.github.jrubygradle.JRubyPlugin
import groovy.transform.PackageScope
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
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
/**
* @author R. Tyler Croy
*/
class JRubyStormPlugin implements Plugin<Project> {
void apply(Project project) {
project.apply plugin : 'com.github.jruby-gradle.base'
project.apply plugin : 'com.github.jruby-gradle.jar'
project.apply plugin : 'com.github.johnrengelman.shadow'
project.configurations.maybeCreate('jrubyStorm')
project.configurations.maybeCreate('jrubyStormLocal')
project.configurations {
jrubyStormLocal.extendsFrom jrubyStorm
}
project.task('jrubyStorm', type: ShadowJar) {
group JRubyPlugin.TASK_GROUP_NAME
description 'Create a JRuby-based Storm topology'
dependsOn project.tasks.jrubyPrepare
exclude '*.sw*', '*.gitkeep', '*.md', 'META-INF/BCKEY*'
into('topologies') {
from 'topologies'
}
into('bolts') {
from 'bolts'
}
jruby {
// Use the default GEM installation directory
defaultGems()
mainClass 'redstorm.TopologyLauncher'
}
}
project.extensions.create('storm', JRubyStormExtension)
project.task('jrubyStorm', type: JRubyStorm)
updateRepositories(project)
updateDependencies(project)
project.afterEvaluate {
JRubyStormLocal.updateDependencies(project)
// Add the jrubyStorm configuration to the jrubyStorm task to make
// sure ShadowJar will unzip/incorporate the right data unpacked into
// the artifact
project.tasks.jrubyStorm.configurations.add(project.configurations.getByName('jrubyStorm'))
}
}
@PackageScope
@ -68,35 +24,8 @@ class JRubyStormPlugin implements Plugin<Project> {
// jcenter contains the redstorm and gradle dependencies
jcenter()
// Repositories for Storm dependencies
mavenCentral()
maven { url 'http://clojars.org/repo/' }
maven { url 'http://conjars.org/repo/' }
}
}
@PackageScope
void updateDependencies(Project project) {
project.dependencies {
// Excluding storm-core for the configuration where we create the
// topology jar. This is because the running storm cluster will provide
// the classes from this dependency. If we attempt to includ ethis, the
// storm classes will not initialize properly and you'll get exceptions
// like: "cannot load or initialize class backtype.storm.LocalCluster
jrubyStorm (group: 'com.github.jruby-gradle',
name: 'redstorm',
version: '0.7.1+') {
exclude module: 'storm-core'
}
// We must pull in bouncycastle since it's not included as a proper
// dependency for the jruby-complete.jar that gets bundled into the
// topology jar. Similar code exists in the base plugin for the
// JRubyExec task
jrubyStorm "org.bouncycastle:bcprov-jdk15on:${project.jruby.bouncycastleVersion}"
jrubyStormLocal group: 'org.apache.storm',
name: 'storm-core',
version: '0.9.2-incubating'
}
}
}

View File

@ -0,0 +1,31 @@
package com.github.jrubygradle.storm.internal
import com.github.jrubygradle.storm.JRubyStormLocal
import org.gradle.api.Project
import org.gradle.api.Task
class JRubyStorm {
static Task createAssembleTask(Project project, String baseName) {
return project.task("assemble${prepareNameForSuffix(baseName)}", type: JRubyStormJar)
}
/**
* Prepare a name for suffixing to a task name, i.e. with a baseName of
* "foo" if I need a task to prepare foo, this will return 'Foo' so I can
* make a "prepareFoo" task and it cases properly
*
* This method has a special handling for the string 'jruby' where it will
* case it properly like "JRuby" instead of "Jruby"
*/
static String prepareNameForSuffix(String baseName) {
return baseName.replaceAll("(?i)jruby", 'JRuby').capitalize()
}
static Task createRunTask(Project project, String baseName, Task parent) {
JRubyStormLocal runTask = project.task("run${prepareNameForSuffix(baseName)}",
type: JRubyStormLocal)
runTask.parentTask = parent
return runTask
}
}

View File

@ -0,0 +1,8 @@
package com.github.jrubygradle.storm.internal
import com.github.jrubygradle.jar.JRubyJar
import groovy.transform.InheritConstructors
@InheritConstructors
class JRubyStormJar extends JRubyJar {
}

View File

@ -0,0 +1,40 @@
package com.github.jrubygradle.storm
import spock.lang.*
class JRubyStormExtensionSpec extends Specification {
protected JRubyStormExtension ext = new JRubyStormExtension()
def "defaultVersion should give me a Storm version"() {
expect:
ext.defaultVersion
}
def "versionshould set the version"() {
given:
String version = '0.1.1'
when:
ext.defaultVersion version
then:
ext.defaultVersion == version
}
def "redstormVersion should give me a Redstorm version"() {
expect:
ext.defaultRedstormVersion
}
def "redstormVersion should set the redstorm version"() {
given:
String version = '0.1'
when:
ext.defaultRedstormVersion version
then:
ext.defaultRedstormVersion == version
}
}

View File

@ -1,19 +1,52 @@
package com.github.jrubygradle.storm
import com.github.jrubygradle.JRubyPlugin
import org.gradle.api.tasks.JavaExec
import org.junit.Test
import org.gradle.api.Task
import spock.lang.*
import static org.gradle.api.logging.LogLevel.LIFECYCLE
import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
/**
* @author R. Tyler Croy
*
*/
class JRubyStormLocalSpec extends Specification {
protected Project project
void setup() {
project = ProjectBuilder.builder().build()
project.apply plugin: 'com.github.jruby-gradle.storm'
}
def "jrubyStormLocal task should be a proper instance"() {
when:
project.task('jrubyStormLocal', type: JRubyStormLocal)
then:
project.tasks.jrubyStormLocal instanceof JRubyStormLocal
}
def "the task should inherit the topology configured on the parent"() {
given:
JRubyStorm parent = project.task('spock-parent', type: JRubyStorm)
parent.topology = 'foo.rb'
JRubyStormLocal task = project.task('spock', type: JRubyStormLocal)
when:
task.parentTask = parent
then:
task.topology == parent.topology
}
def "I should be able to set a topology to run without a parent task"() {
given:
JRubyStormLocal task = project.task('spock', type: JRubyStormLocal)
String topologyFile = 'topology.rb'
when:
task.topology = topologyFile
then:
task.topology == topologyFile
}
}

View File

@ -2,6 +2,7 @@ package com.github.jrubygradle.storm
import com.github.jrubygradle.JRubyPlugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.*
import org.gradle.api.tasks.bundling.Jar
@ -15,44 +16,77 @@ import static org.gradle.api.logging.LogLevel.LIFECYCLE
import static org.junit.Assert.assertTrue
/**
* @author R. Tyler Croy
*
*/
class JRubyStormPluginSpec extends Specification {
def project
protected Project project
void setup() {
project = ProjectBuilder.builder().build()
project.apply plugin: 'com.github.jruby-gradle.storm'
}
def "Basic sanity check"() {
expect:
project.tasks.jrubyStorm instanceof Task
project.tasks.jrubyStorm.group == JRubyPlugin.TASK_GROUP_NAME
}
def "Check configurations exist"() {
given:
def configs = project.configurations
expect:
configs.getByName('jrubyStorm')
configs.getByName('jrubyStormLocal')
expect:
project.configurations.findByName('jrubyStorm')
}
@Ignore
def "Check jrubyStorm dependencies are correct"() {
given:
given:
def deps = project.configurations.getByName('jrubyStorm').dependencies
expect:
when:
project.evaluate()
then:
deps.matching { Dependency d -> d.name == 'redstorm' }
}
@Ignore
def "Check jrubyStormLocal dependencies are correct"() {
given:
given:
def deps = project.configurations.getByName('jrubyStormLocal').dependencies
expect:
when:
project.evaluate()
then:
deps.matching { Dependency d -> d.name == 'storm-core' }
}
@Ignore
def "setting storm.version should add the right jrubyStormLocal dependency"() {
given:
String version = '0.1.1'
def dependencies = project.configurations.findByName('jrubyStormLocal').dependencies
when:
project.storm.defaultVersion version
project.evaluate()
then:
project.storm.defaultVersion == version
dependencies.matching { Dependency d ->
d.name == 'storm-core' && d.version == version
}
}
@Ignore
def "setting storm.redstormVersion should add the right jrubyStorm dependnecy"() {
given:
String version = '0.1.1'
def dependencies = project.configurations.findByName('jrubyStorm').dependencies
when:
project.storm.defaultRedstormVersion version
project.evaluate()
then:
project.storm.defaultRedstormVersion == version
dependencies.matching { Dependency d ->
d.name == 'redstorm' && d.version == version
}
}
}

View File

@ -0,0 +1,167 @@
package com.github.jrubygradle.storm
import org.gradle.api.artifacts.Dependency
import spock.lang.*
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.testfixtures.ProjectBuilder
import static org.gradle.api.logging.LogLevel.*
class JRubyStormSpec extends Specification {
protected Project project
void setup() {
project = ProjectBuilder.builder().build()
project.apply plugin: 'com.github.jruby-gradle.storm'
}
def "instantiation should create a run{Name} task"() {
when:
project.task('tapa', type: JRubyStorm)
then:
project.tasks.findByName('runTapa')
}
def "instantiation should create an assemble{Name} task"() {
when:
project.task('tapa', type: JRubyStorm)
then:
project.tasks.findByName('assembleTapa')
}
def "creating a task with JRuby in the name should capitalize nicely"() {
when:
project.task('jrubyTapa', type: JRubyStorm)
then: "JRuby should be cased properly so it doesn't annoy rtyler"
project.tasks.findByName('assembleJRubyTapa')
}
def "creating a task with a jRuby string should also capitalize nicely"() {
when:
project.task('jRUBYTapa', type: JRubyStorm)
then: "JRuby should be cased properly so it doesn't annoy rtyler"
project.tasks.findByName('assembleJRubyTapa')
}
def "runTask should be a type of JRubyStormLocal"() {
given:
Task spock = project.task('spock', type: JRubyStorm) {
topology 'spock.rb'
}
Task runTask = project.tasks.findByName('runSpock')
expect:
runTask instanceof JRubyStormLocal
runTask.topology == 'spock.rb'
}
def "getStormVersion() should return the storm.defaultStormVersion by default"() {
given:
JRubyStorm task = project.task('spock', type: JRubyStorm)
expect:
task.stormVersion == project.storm.defaultVersion
}
def "if I've set a custom storm version, getStormVersion() should return that"() {
given:
JRubyStorm task = project.task('spock', type: JRubyStorm)
String version = '0.1'
when:
task.stormVersion version
then:
task.stormVersion == version
}
def "getRedstormVersion() should return the storm.defaultRedstormVersion by default"() {
given:
JRubyStorm task = project.task('spock', type: JRubyStorm)
expect:
task.redstormVersion == project.storm.defaultRedstormVersion
}
def "if I've set a custom redstorm version, getRedstormVersion() should return that"() {
given:
JRubyStorm task = project.task('spock', type: JRubyStorm)
String version = '0.1.'
when:
task.redstormVersion version
then:
task.redstormVersion == version
}
def "by default a configuration should be made for dependencies"() {
when:
project.task('spock', type: JRubyStorm)
then:
project.configurations.findByName(JRubyStorm.DEFAULT_CONFIGURATION_NAME)
}
}
@Ignore("For some reason these are running with DEBUG log level and it won't turn off")
class JRubyStormProjectSpec extends Specification {
Project project
def setup() {
project = ProjectBuilder.builder().build()
project.with {
apply plugin: 'com.github.jruby-gradle.storm'
}
}
def "evaluation of the project should result in an assemble and run task"() {
when:
project.evaluate()
then:
project.tasks.findByName('assembleJRubyStorm')
project.tasks.findByName('runJRubyStorm')
}
@Ignore
def "evaluation of the project should result in dependencies being added to the configuration"() {
given:
Project project = ProjectBuilder.builder().build()
project.with {
apply plugin: 'com.github.jruby-gradle.storm'
}
JRubyStorm task = project.task('spock', type: JRubyStorm)
def deps = task.configuration.dependencies
when:
project.evaluate()
then:
deps.matching { Dependency d -> d.name == 'redstorm' }
}
@Ignore
def "evaluation of the project should result in local mode dependencies"() {
given:
project.with {
logging.level = INFO
apply plugin: 'com.github.jruby-gradle.storm'
}
JRubyStorm task = project.task('spock', type: JRubyStorm)
when:
project.evaluate()
then:
project.configurations.findByName('jrubyStormLocal')?.dependencies?.matching {
it.name == 'storm-core'
}
}
}

View File

@ -0,0 +1,18 @@
package com.github.jrubygradle.storm.internal
import com.github.jrubygradle.jar.JRubyJar
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.*
class JRubyStormJarSpec extends Specification {
def "when constructing the task"() {
given:
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'com.github.jruby-gradle.storm'
expect: "the task to be a JRubyJar"
project.task('spock', type: JRubyStormJar) instanceof JRubyJar
}
}

View File

@ -0,0 +1,29 @@
package com.github.jrubygradle.storm.internal
import com.github.jrubygradle.storm.JRubyStormLocal
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.bundling.Jar
import org.gradle.testfixtures.ProjectBuilder
import spock.lang.*
class JRubyStormSpec extends Specification {
Project project
def setup() {
project = ProjectBuilder.builder().build()
project.apply plugin: 'com.github.jruby-gradle.storm'
}
def "createAssembleTask() should return a Jar type task"() {
expect:
JRubyStorm.createAssembleTask(project, 'spock') instanceof Jar
}
def "createRunTask() should return a JRubyStormLocal type task"() {
given:
Task task = project.task('spockParent', type: com.github.jrubygradle.storm.JRubyStorm)
expect:
JRubyStorm.createRunTask(project, 'spock', task) instanceof JRubyStormLocal
}
}