Dan Hyun
Dan Hyun
Software Engineer Mindspark
~1 year personally/professionally
Groovy
Gradle
Spock
How to…
Contribute to Groovy
Contribute to Grails
Contribute to Gr8 Technologies
Wanted to use Gradle
I had no idea where to start
Decided I needed to learn Groovy
Started with Grails In Action 2nd Ed.
Led me to Peter Ledbrook → GroovyPodcast → GR8Conf
Continued with Groovy In Action 2nd Ed.
and watching talks from GR8Conf youtube Channel
Follow Guillaume’s Groovy Weekly Update
Participation on twitter #groovylang
From
To
utilization → reading docs → executing sample code → encountering bugs (Groovy Puzzlers??)
Usage comes from exposure
Exposure comes from community
Participate at any of these levels
you eventually find your way to source code
Groovy/Grails development no longer
financially supported by Pivotal
Groovy 2.4 (Groovy on Android!!!!)
Grails 3.0 (Complete rewrite on Spring Boot)
Friendly
Positive
Lots of Gr8 OSS projects
and HORSEGROOVY
F.U.B.U == For Us By Us
Community
Usage
Source Code
Good OSS Projects tell you how you can contribute.
Groovy is a Good OSS Project.
So don’t hesitate to help us improve it, fix typos, broken language, clarify complicated sections, add new material, etc.
The "Hello, World!" of contributions
Discover typos by usage
Expert Groovy OSS Documentation Contributor
Learn and download git
git clone git://github.com/apache/incubator-groovy.git
Push finished code to your own fork
Create PR with relevant info
While reading some Javadoc…
/**
* Iterates through an List,
* passing each item and the item's index (a counter starting at
* zero) to the given closure.
*
* @param self an List
* @param closure a Closure to operate on each item
* @return the self List
* @since 2.4.0
*/
public static <T> List<T> eachWithIndex(...) {...}
an List
Bingo!
Time to contribute!
$ grep -ir "\([^a-zA-Z]\)an \(list\)" .
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * Iterates through an List,
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * Iterates through an List, passing each item to the given closure.
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java: * @param self an List
./src/main/org/codehaus/groovy/runtime/InvokerHelper.java: // value is an list.
./src/main/org/codehaus/groovy/runtime/InvokerHelper.java: // value is an list.
./subprojects/groovy-jmx/src/main/groovy/groovy/jmx/builder/JmxListenerFactory.groovy: * This factory class is used to create an listener() node for JmxBuilder. Listener nodes are used
$ grep -ir "\([^a-zA-Z]\)an \(list\)" . | cut -d":" -f1 \
| sort -u | xargs sed -i 's/\([^a-zA-Z]\)an \(list\)/\1a \2/ig'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
modified: src/main/org/codehaus/groovy/runtime/InvokerHelper.java
modified: subprojects/groovy-jmx/src/main/groovy/groovy/jmx/builder/JmxListenerFactory.groovy
$ git diff -b
Don’t want to waste anyone’s time
Make sure it compiles locally
Run tests
Etc
Provide some relevant information
about the work you’ve done.
Reference ticket numbers, etc…
Learn about Asciidoctor
Browse issue tracker for good first contribution tickets
We can use this singleton class in some script code as follows:
[source,groovy]
----
include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_vote_collector_usage,indent=0]
----
// tag::singleton_vote_collector_usage[]
def collector = VoteCollector.instance
collector.display()
collector.votes++
collector = null
Thread.start{
def collector2 = VoteCollector.instance
collector2.display()
collector2.votes++
collector2 = null
}.join()
def collector3 = VoteCollector.instance
collector3.display()
// end::singleton_vote_collector_usage[]
Grails is also a Good OSS Project.
Regardless of preference
indentation should be consistent
Confusing for the uninitiated
What is Spock or Geb?
Do I need to indent for this to work?
Why is it different?
New users may believe:
Unit tests == no indents
Functional tests == indentation
Participate on StackOverflow
Subscribe to the mailing-list
and indicate that you would like to do so.
There are a lot of
projects that use Groovy.
Feel free to explore and make
similar contributions.
Say hello with #groovylang
Contribute some typo corrections
Get involved on Stack Overflow