Added CAUTION note about case sensitive queries

= Grails Url Shortener

image::https://drone.io/github.com/lmivan/grails-url-shortener/status.png[alt="Build Status", link="https://drone.io/github.com/lmivan/grails-url-shortener/latest"]
image::http://stillmaintained.com/lmivan/grails-url-shortener.png[alt="Still maintained", link="http://stillmaintained.com/lmivan/grails-url-shortener"]

This is a grails plugin that integrates a url shortener inside your Grails application.

== Installation

In `BuildConfig` add the following dependency:

[source, groovy]
----
compile ":url-shortener:<version>"
----

== Configuration

After installing the plugin you have to add the following configuration to your `Config.groovy` file:

[source, groovy]
----
// Grails-url-shortener
shortener {
    characters = ('0'..'9') + ('a'..'h') + ('j'..'k') + ('m'..'z') + ('A'..'H') + ('J'..'K') + ('M'..'Z')
    minLength = 5
    shortDomain = http://YOUR-SHORT-DOMAIN.COM
}
----

* `characters` the list of the valid characters for the shorted urls. In this example, the letters `i`, `l`, `I`, `L`
are removed because they can be mix up with some typographies. You can create your custom list, for example,
removing the vowels.
* `minLength` is the minimum number of characters for the shorted url.
* `shortDomain` the short domain for your url shortener.

CAUTION: If you include both lowercase and uppercase characters in the `characters` list you must make sure your
database/table is configured to do **case sensitive** queries. Otherwise you could get the wrong URL back when
querying the database.

Next you have to provide a unique number generator. The plugin provides an in-memory dummy implementation using
AtomicLong available in the file https://github.com/lmivan/grails-url-shortener/blob/master/src/groovy/net/kaleidos/shortener/generator/DummySequenceGenerator.groovy[DummySequenceGenerator].

CAUTION: Please do not use this default implementation for production because the counter is reset every time
you start the app. You should only use this default implementation for develop o test environment.

To implement your custom unique number generator you have to create a simple Groovy or Java class that implements
the `net.kaleidos.shortener.SequenceGenerator` interface. For example you can use a database sequence for this number
generator. The following class use a Postgresql sequence for this:

[source, groovy]
./src/groovy/com/example/shortener/PostgresSequenceGenerator.groovy
----
package com.example.shortener

import net.kaleidos.shortener.SequenceGenerator
import groovy.sql.Sql

class PostgresSequenceGenerator implements SequenceGenerator {
    def dataSource

    Long getNextNumber() {
        def db = new Sql(dataSource)
        return db.rows("SELECT nextval('seq_shorten_url_generator')")[0]['nextval']
    }
}
----

Finally, when you have created you custom generator you have to define the `sequenceGenerator` bean in your
`resources.groovy` file:

[source, groovy]
----
beans = {
    ...
    sequenceGenerator(com.example.shortener.PostgresSequenceGenerator) {
        dataSource = ref("dataSource")
    }
    ...
}
----

=== Sequence Generator Plugin

You can also use the http://grails.org/plugin/sequence-generator[sequence-generator] plugin to generate sequence numbers
for short urls. Version 1.1+ of `sequence-generator` is compatible with version 0.2+ of `url-shortener`.
Just add the `sequence-generator` plugin to your BuildConfig.groovy and you are ready to go.

You don't have to create a custom generator or configure a sequenceGenerator bean (section above),
it done by the `sequence-generator` plugin.

== Usage

The plugin provides a service `urlShortenerService` that you can inject into your grails artefacts with the following
public methods:

* `shortUrl(String targetUrl)`: Returns a short url for the target url passed as param. If the url has already been
shortened, the same short url is returned. Be careful because this method only returns the shortened characters for
the target url but not the url with the configured short domain.
* `shortUrlFullDomain(String targetUrl)`: Returns the short url with the full domain.
*  `getTargetUrl(String shortUrl)`: Returns the target url (original url) from the short url passed as param.
The method also increase a counter with the number of times this url has been hit. If the short url does not exist
the method return null.

Examples:

[source, groovy]
----
String shortUrl = urlShortenerService.shortUrl("http://kaleidos.net")
assert shortUrl.length() == 5

String shortUrlWithDomain = urlShortenerService.shortUrlFullDomain("http://kaleidos.net")
assert shortUrlWithDomain.length() > 5
assert shortUrlWithDomain.contains("http://") == true

String shortUrl = urlShortenerService.shortUrl("http://kaleidos.net")
assert urlShortenerService.getTargetUrl(shortUrl) == "http://kaleidos.net"
----

The plugin also provides a controller that can be used to redirect to the target url.
It is available here
https://github.com/lmivan/grails-url-shortener/blob/master/grails-app/controllers/net/kaleidos/shortener/ShortenerController.groovy[ShortenerController]
or you can implement your own custom controller.

=== Tag Library

The plugin provides two GSP tags that generate short urls, `link` and `createLink`. They work as the standard Grails `link` and `createLink` but generates short urls.

[source, javascript]
----
function copyShortLinkToClipboard() {
    var url = "${shorter.createLink(controller: 'person', action: 'show', id: person.id, absolute: true)}";
    window.prompt("${message(code: 'copy.to.clipboard.label', 'Copy to clipboard: Ctrl+C, Enter')}", url);
}
----

== Author

You can send any questions to:

Iván López: lopez.ivan@gmail.com (https://twitter.com/ilopmar[@ilopmar])

Collaborations are appreciated :-)

== Release Notes

* 0.2.1 - 18/Jan/2015 - Fix regresion in 0.2 (See https://github.com/lmivan/grails-url-shortener/issues/6[#6])
* 0.2 - 21/Nov/2014 - Added GSP tags `shorter:link` and `shorter:createLink`.
* 0.1 - 17/Oct/2013 - Initial version of the plugin.

= Grails Url Shortener

image::https://drone.io/github.com/lmivan/grails-url-shortener/status.png[alt="Build Status", link="https://drone.io/github.com/lmivan/grails-url-shortener/latest"]
image::http://stillmaintained.com/lmivan/grails-url-shortener.png[alt="Still maintained", link="http://stillmaintained.com/lmivan/grails-url-shortener"]

This is a grails plugin that integrates a url shortener inside your Grails application.

== Installation

In `BuildConfig` add the following dependency:

[source, groovy]
----
compile ":url-shortener:<version>"
----

== Configuration

After installing the plugin you have to add the following configuration to your `Config.groovy` file:

[source, groovy]
----
// Grails-url-shortener
shortener {
    characters = ('0'..'9') + ('a'..'h') + ('j'..'k') + ('m'..'z') + ('A'..'H') + ('J'..'K') + ('M'..'Z')
    minLength = 5
    shortDomain = http://YOUR-SHORT-DOMAIN.COM
}
----

* `characters` the list of the valid characters for the shorted urls. In this example, the letters `i`, `l`, `I`, `L`
are removed because they can be mix up with some typographies. You can create your custom list, for example,
removing the vowels.
* `minLength` is the minimum number of characters for the shorted url.
* `shortDomain` the short domain for your url shortener.

Next you have to provide a unique number generator. The plugin provides an in-memory dummy implementation using
AtomicLong available in the file https://github.com/lmivan/grails-url-shortener/blob/master/src/groovy/net/kaleidos/shortener/generator/DummySequenceGenerator.groovy[DummySequenceGenerator].

CAUTION: Please do not use this default implementation for production because the counter is reset every time
you start the app. You should only use this default implementation for develop o test environment.

To implement your custom unique number generator you have to create a simple Groovy or Java class that implements
the `net.kaleidos.shortener.SequenceGenerator` interface. For example you can use a database sequence for this number
generator. The following class use a Postgresql sequence for this:

[source, groovy]
./src/groovy/com/example/shortener/PostgresSequenceGenerator.groovy
----
package com.example.shortener

import net.kaleidos.shortener.SequenceGenerator
import groovy.sql.Sql

class PostgresSequenceGenerator implements SequenceGenerator {
    def dataSource

    Long getNextNumber() {
        def db = new Sql(dataSource)
        return db.rows("SELECT nextval('seq_shorten_url_generator')")[0]['nextval']
    }
}
----

Finally, when you have created you custom generator you have to define the `sequenceGenerator` bean in your
`resources.groovy` file:

[source, groovy]
----
beans = {
    ...
    sequenceGenerator(com.example.shortener.PostgresSequenceGenerator) {
        dataSource = ref("dataSource")
    }
    ...
}
----

=== Sequence Generator Plugin

You can also use the http://grails.org/plugin/sequence-generator[sequence-generator] plugin to generate sequence numbers
for short urls. Version 1.1+ of `sequence-generator` is compatible with version 0.2+ of `url-shortener`.
Just add the `sequence-generator` plugin to your BuildConfig.groovy and you are ready to go.

You don't have to create a custom generator or configure a sequenceGenerator bean (section above),
it done by the `sequence-generator` plugin.

== Usage

The plugin provides a service `urlShortenerService` that you can inject into your grails artefacts with the following
public methods:

* `shortUrl(String targetUrl)`: Returns a short url for the target url passed as param. If the url has already been
shortened, the same short url is returned. Be careful because this method only returns the shortened characters for
the target url but not the url with the configured short domain.
* `shortUrlFullDomain(String targetUrl)`: Returns the short url with the full domain.
*  `getTargetUrl(String shortUrl)`: Returns the target url (original url) from the short url passed as param.
The method also increase a counter with the number of times this url has been hit. If the short url does not exist
the method return null.

Examples:

[source, groovy]
----
String shortUrl = urlShortenerService.shortUrl("http://kaleidos.net")
assert shortUrl.length() == 5

String shortUrlWithDomain = urlShortenerService.shortUrlFullDomain("http://kaleidos.net")
assert shortUrlWithDomain.length() > 5
assert shortUrlWithDomain.contains("http://") == true

String shortUrl = urlShortenerService.shortUrl("http://kaleidos.net")
assert urlShortenerService.getTargetUrl(shortUrl) == "http://kaleidos.net"
----

The plugin also provides a controller that can be used to redirect to the target url.
It is available here
https://github.com/lmivan/grails-url-shortener/blob/master/grails-app/controllers/net/kaleidos/shortener/ShortenerController.groovy[ShortenerController]
or you can implement your own custom controller.

=== Tag Library

The plugin provides two GSP tags that generate short urls, `link` and `createLink`. They work as the standard Grails `link` and `createLink` but generates short urls.

[source, javascript]
----
function copyShortLinkToClipboard() {
    var url = "${shorter.createLink(controller: 'person', action: 'show', id: person.id, absolute: true)}";
    window.prompt("${message(code: 'copy.to.clipboard.label', 'Copy to clipboard: Ctrl+C, Enter')}", url);
}
----

== Author

You can send any questions to:

Iván López: lopez.ivan@gmail.com (https://twitter.com/ilopmar[@ilopmar])

Collaborations are appreciated :-)

== Release Notes

* 0.2.1 - 18/Jan/2015 - Fix regresion in 0.2 (See https://github.com/lmivan/grails-url-shortener/issues/6[#6])
* 0.2 - 21/Nov/2014 - Added GSP tags `shorter:link` and `shorter:createLink`.
* 0.1 - 17/Oct/2013 - Initial version of the plugin.


Update

Update

= TodoAndroid

This will someday be the TodoMore Android client.

== Unfinished Warning

As of today it certainly is not fully working - don't try to use it unless you can code the parts that are missing.
The next bit push is that the SyncAdapter starts but isn't fully coded yet, so don't run it against
a database of real TODOs.

Next up in this area will be a delete feature; it's harder because you have to atomically commit in two
places, and you can't.

== Security Warning

This version caches your password, unencrypted, in the shared preferences.
Somebody who finds your phone AND knows what they're doing could modify
or corrupt your TODO listings.

Please fix this and send a pull request!

= TodoAndroid

This will someday be the TodoMore Android client.
As of today it certainly is not fully working - don't try to use it unless you can recode the parts that are missing.

== Security Warning

This version caches your password, unencrypted, in the shared preferences.
Somebody who finds your phone AND knows what they're doing could modify
or corrupt your TODO listings.

Please fix this and send a pull request!


fix(readme): change readme to trigger a release

= Fabric8 Recommender

image:https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic%20release-b4d455.svg[Semantic Release, link="https://github.com/semantic-release/semantic-release"]

**Fabric8 Recommender is a stack analysis feature.**

== Running the app

=== Set NODE_ENV
If you're just trying to test the application, please use inmemory mode which
will load the app with mock data for you. If you, however, want to contribute
to the codebase, unset it back or to "development" (default) mode and rebuild.

[source,shell]
```
$ export NODE_ENV=inmemory # <1>
$ export NODE_ENV=development # <2>
$ export NODE_ENV=production # <3>

<1> In-memory mode for trying-out the app
<2> Development mode for contributing to the source
<2> Production mode for deploying the application
```

Once you're done setting the environment, you can proceed with the next step(s)

NOTE: If you're directly trying to run the app in dev mode, you can skip this
step, as *`NODE_ENV`* is treated as `"development"` by default.

=== First run

If you're trying to run the app for the first time:

 $ npm install

Then, start the app with:

 $ npm start

=== Fresh run

If you trying to refresh your installation, you need to run:

 $ npm run reinstall

Then, start the app with:

 $ npm start

=== Testcase run

To run the linter, unit tests, and functional test use:

 $ npm test

== Other useful scripts

The *`package.json`* file's `scripts:` section lists _all the tasks_ we run.

Here are some of the most useful/frequently used scripts you may need to run:

[cols="1,2,4", options="header"]
|===
|Scipt
|Command
|Description

|Lint
|`$ npm run lint`
|Runs the TypeScript and Angular 2 linter

|Validation
|`$ npm run validate`
|Validates the webpack build

|Unit Tests
|`$ npm run test:unit`
|Runs the unit tests

|Functional Tests
|`$ npm run test:func`
|Runs the functional tests

|Continuous Tests
|`$ npm run watch:test`
|Looks for changes in source code and runs unit tests
|===

== Building the app

=== Production build

To generate production build, set API URL and run build script as follows:

----
$ npm run build:prod
----

The build output will be under `dist` directory.

*To create a docker image,* run this command immediately after the production
build completion:

=== Library Build

==== For production:

To build the fabric8-stack-analysis-ui as an npm library, use:

----
$ npm run build
----

The created library will be placed in `dist`.

IMPORTANT: *You shouldn't ever publish the build manually,* instead you should
let the CD pipeline do a semantic release.

==== For development:

To build fabric8-stack-analysis-ui as an npm library and embed it into a webapp such as
fabric8-ui, you should:

Step 1: Run `npm run watch:library` in the source directory::
This will build fabric8-stack-analysis-ui as a library and then set up a watch task to
rebuild any ts, html and scss files you change.

Step 2: Run `npm link <path to fabric8-stack-analysis-ui>/dist-watch`::
In the webapp into which you are embedding. This will create a symlink from
`node_modules/fabric8-stack-analysis-ui` to the `dist-watch` directory and install that
symlinked node module into your webapp.

Step 3: Run your webapp in development mode::
Make sure you have a watch on `node_modules/fabric8-stack-analysis-ui` enabled. You will
have access to both JS and SASS sourcemaps if your webapp is properly setup.

NOTE: `fabric8-ui` is setup to do reloading and sourcemaps automatically when you
run `npm start`.

**To hit stack analysis api in standalone mode**
Put a token in the environment variable with key as 'STACK_API_TOKEN'.

== CSS and SASS

fabric8-stack-analysis-ui uses SASS for it's stylesheets. It also uses the Angular emulation
of the shadow dom, so you will normally want to place your styles in the
`.component.scss` file next to the html and the typescript.

We use mixins to avoid polluting components with uncessary style classes, and to avoid
an explosion of shared files.

The `src/assets/stylesheets/` directory includes a `shared` directory. These are
shared global styles that we will refactor out in to a shared library at some point.
Only update these styles if you are making a truly global style, and are going to
synchronise your changes across all the various UI projects.

== Contributing to the app

The development guide is part of the link:./CONTRIBUTING.adoc[contributors'
instructions]. Please check it out in order to contribute to this project.

= Fabric8 Recommender

image:https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic%20release-b4d455.svg[Semantic Release, link="https://github.com/semantic-release/semantic-release"]

**Fabric8 Recommender is a stack analysis feature.**

== Running the app

=== Set NODE_ENV
If you're just trying to test the application, please use inmemory mode which
will load the app with mock data for you. If you, however, want to contribute
to the codebase, unset it back or to "development" (default) mode and rebuild.

[source,shell]
```
$ export NODE_ENV=inmemory # <1>
$ export NODE_ENV=development # <2>
$ export NODE_ENV=production # <3>

<1> In-memory mode for trying-out the app
<2> Development mode for contributing to the source
<2> Production mode for deploying the application
```

Once you're done setting the environment, you can proceed with the next step(s)

NOTE: If you're directly trying to run the app in dev mode, you can skip this
step, as *`NODE_ENV`* is treated as `"development"` by default.

=== First run

If you're trying to run the app for the first time:

 $ npm install

Then, start the app with:

 $ npm start

=== Fresh run

If you trying to refresh your installation, you need to run:

 $ npm run reinstall

Then, start the app with:

 $ npm start

=== Testcase run

To run the linter, unit tests, and functional test use:

 $ npm test

== Other useful scripts

The *`package.json`* file's `scripts:` section lists _all the tasks_ we run.

Here are some of the most useful/frequently used scripts you may need to run:

[cols="1,2,4", options="header"]
|===
|Scipt
|Command
|Description

|Lint
|`$ npm run lint`
|Runs the TypeScript and Angular 2 linter

|Validation
|`$ npm run validate`
|Validates the webpack build

|Unit Tests
|`$ npm run test:unit`
|Runs the unit tests

|Functional Tests
|`$ npm run test:func`
|Runs the functional tests

|Continuous Tests
|`$ npm run watch:test`
|Looks for changes in source code and runs unit tests
|===

== Building the app

=== Production build

To generate production build, set API URL and run build script as follows:

----
$ npm run build:prod
----

The build output will be under `dist` directory.

*To create a docker image,* run this command immediately after the production
build completion:

=== Library Build

==== For production:

To build the fabric8-stack-analysis-ui as an npm library, use:

----
$ npm run build
----

The created library will be placed in `dist`.

IMPORTANT: *You shouldn't ever publish the build manually,* instead you should
let the CD pipeline do a semantic release.

==== For development:

To build fabric8-stack-analysis-ui as an npm library and embed it into a webapp such as
fabric8-ui, you should:

Step 1: Run `npm run watch:library` in the source directory::
This will build fabric8-stack-analysis-ui as a library and then set up a watch task to
rebuild any ts, html and scss files you change.

Step 2: Run `npm link <path to fabric8-stack-analysis-ui>/dist-watch`::
In the webapp into which you are embedding. This will create a symlink from
`node_modules/fabric8-stack-analysis-ui` to the `dist-watch` directory and install that
symlinked node module into your webapp.

Step 3: Run your webapp in development mode::
Make sure you have a watch on `node_modules/fabric8-stack-analysis-ui` enabled. You will
have access to both JS and SASS sourcemaps if your webapp is properly setup.

NOTE: `fabric8-ui` is setup to do reloading and sourcemaps automatically when you
run `npm start`.

**To hit stack analysis api in standalone mode**
Put a token in the environment variable with key as 'STACK_API_TOKEN'

== CSS and SASS

fabric8-stack-analysis-ui uses SASS for it's stylesheets. It also uses the Angular emulation
of the shadow dom, so you will normally want to place your styles in the
`.component.scss` file next to the html and the typescript.

We use mixins to avoid polluting components with uncessary style classes, and to avoid
an explosion of shared files.

The `src/assets/stylesheets/` directory includes a `shared` directory. These are
shared global styles that we will refactor out in to a shared library at some point.
Only update these styles if you are making a truly global style, and are going to
synchronise your changes across all the various UI projects.

== Contributing to the app

The development guide is part of the link:./CONTRIBUTING.adoc[contributors'
instructions]. Please check it out in order to contribute to this project.


Fix IDE integration instructions in README. (closes #26)

The README stated that you should run

    gradlew jarAll idea

before loading the project into IntelliJ IDEA. It seems, though, that the `jarAll`
task breaks the IDE integration and you can't run tests. Running

    gradlew jar idea

seems to work fine, so I've updated the README to reflect this.

= Groovy
The Groovy development team
:revdate: 24-02-2014
:build-icon: http://ci.groovy-lang.org:8111/app/rest/builds/buildType:(id:Groovy_Jdk7Build)/statusIcon
:noheader:
:groovy-www: http://groovy-lang.org/
:groovy-ci: http://ci.groovy-lang.org?guest=1
:jdk: http://www.oracle.com/technetwork/java/javase/downloads
:bintray-latest-version-image: https://api.bintray.com/packages/groovy/maven/groovy/images/download.png
:bintray-latest-version-link: https://bintray.com/groovy/maven/groovy/_latestVersion
:bintray-watch-image: https://www.bintray.com/docs/images/bintray_badge_color.png
:bintray-watch-link: https://bintray.com/groovy/maven/groovy/view?source=watch

[.left.text-left]
image::http://groovy.codehaus.org/img/groovy-logo.png[]
{groovy-www}[Groovy] is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at multiplying developers’ productivity thanks to a concise, familiar and easy to learn syntax.

It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.

== Downloading

Latest Groovy version is available on Bintray image:{bintray-latest-version-image}[Bintray latest version, link={bintray-latest-version-link}]

Binary distribution links are on the package page.

Maven, Gradle and Ivy dependency declaration snippets are available on specific files of a particular module.

image:{bintray-watch-image}[Get automatic notifications about new "groovy" versions link={bintray-watch-link}]

== Obtaining the Source

You don't need the source code to use Groovy but if you wish to explore its inner workings or build it for yourself there are two ways to obtain the source files.

=== Checking out from Version Control

Apache Groovy uses Git. The official Git repository is at:

    http://git-wip-us.apache.org/repos/asf/incubator-groovy.git

And a mirror is hosted on Github:

    https://github.com/apache/incubator-groovy

The Github mirror is read-only and provides convenience to users and developers to explore the code and for the community to accept contributions via Github pull requests.

Simply `git clone` the repo (or the repo you forked via the github website) and you will have the complete source.

=== Unpacking the src distribution

Alternatively, you can download the source distribution and unpack it.

If obtaining the source from this distribution and you intend to build from source,
you also need to https://gradle.org/downloads/[download] and install http://gradle.org/[Gradle] and execute one bootstrap step.
At the top directory of your unpacked source, you need to run the command:

    gradle

This sets up the Gradle wrapper and from then on you just need the `gradlew` command instead of `gradle`.

== Building from Source

Build is image:{build-icon}[build status, link={groovy-ci}].

To build you will need:

* {jdk}[JDK 1.7+]

To build everything using Gradle:

    gradlew clean dist

Note: The gradlew command automatically downloads the correct Gradle version if needed, you do not need to download it first.

This will generate a distribution similar to the zip you can download on the Groovy download page.

To build everything and launch unit tests, use:

    gradlew test

If you want to launch one unit test, use this. <TestClassName> is like `groovy.GroovyMethodsTest`.

    gradlew :test --tests <TestClassName>

To build from IntelliJ IDEA:

    gradlew jar idea

Then open the generated project in IDEA.

To build from Eclipse:

    gradlew jar eclipse

Then open the generated project and the generated subprojects in Eclipse. But be aware that Eclipse tends to be more limited in its ability to reproduce a Gradle build structure. The generated project files may contain a circular dependency which may or may not prevent Eclipse from using them. It depends on the Eclipse version, if this is an issue or not.

To build the documentation (Groovy Language Documentation):

    gradlew assembleAsciidoc

All code samples of the documentation guide are pulled from actual test cases.  To run a single documentation test case, take for example `src/spec/test/semantics/PowerAssertTest.groovy`

    gradlew testSinglePowerAssertTest

(Note the omission of package name: class is `semantics.PowerAssertTest` but only `PowerAssertTest` is added to `testSingle`.)

== InvokeDynamic support

The Groovy build supports the new Java 7 JVM instruction `invokedynamic`. If you want to build Groovy with invokedynamic, you can use the project property `indy`:

    gradlew -Pindy=true clean test

Please note that the following Gradle tasks generate both indy and non indy variants of the jars, so you don't need to use the system property:

* dist
* install
* uploadArchives

== Continuous Integration Server

The official CI server runs {groovy-ci}[here] (login as user guest and leave the password blank) and is sponsored by http://www.jetbrains.com[JetBrains].

== License

Groovy is licensed under the terms of the http://www.apache.org/licenses/LICENSE-2.0.html[Apache License, Version 2.0]

= Groovy
The Groovy development team
:revdate: 24-02-2014
:build-icon: http://ci.groovy-lang.org:8111/app/rest/builds/buildType:(id:Groovy_Jdk7Build)/statusIcon
:noheader:
:groovy-www: http://groovy-lang.org/
:groovy-ci: http://ci.groovy-lang.org?guest=1
:jdk: http://www.oracle.com/technetwork/java/javase/downloads
:bintray-latest-version-image: https://api.bintray.com/packages/groovy/maven/groovy/images/download.png
:bintray-latest-version-link: https://bintray.com/groovy/maven/groovy/_latestVersion
:bintray-watch-image: https://www.bintray.com/docs/images/bintray_badge_color.png
:bintray-watch-link: https://bintray.com/groovy/maven/groovy/view?source=watch

[.left.text-left]
image::http://groovy.codehaus.org/img/groovy-logo.png[]
{groovy-www}[Groovy] is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at multiplying developers’ productivity thanks to a concise, familiar and easy to learn syntax.

It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.

== Downloading

Latest Groovy version is available on Bintray image:{bintray-latest-version-image}[Bintray latest version, link={bintray-latest-version-link}]

Binary distribution links are on the package page.

Maven, Gradle and Ivy dependency declaration snippets are available on specific files of a particular module.

image:{bintray-watch-image}[Get automatic notifications about new "groovy" versions link={bintray-watch-link}]

== Obtaining the Source

You don't need the source code to use Groovy but if you wish to explore its inner workings or build it for yourself there are two ways to obtain the source files.

=== Checking out from Version Control

Apache Groovy uses Git. The official Git repository is at:

    http://git-wip-us.apache.org/repos/asf/incubator-groovy.git

And a mirror is hosted on Github:

    https://github.com/apache/incubator-groovy

The Github mirror is read-only and provides convenience to users and developers to explore the code and for the community to accept contributions via Github pull requests.

Simply `git clone` the repo (or the repo you forked via the github website) and you will have the complete source.

=== Unpacking the src distribution

Alternatively, you can download the source distribution and unpack it.

If obtaining the source from this distribution and you intend to build from source,
you also need to https://gradle.org/downloads/[download] and install http://gradle.org/[Gradle] and execute one bootstrap step.
At the top directory of your unpacked source, you need to run the command:

    gradle

This sets up the Gradle wrapper and from then on you just need the `gradlew` command instead of `gradle`.

== Building from Source

Build is image:{build-icon}[build status, link={groovy-ci}].

To build you will need:

* {jdk}[JDK 1.7+]

To build everything using Gradle:

    gradlew clean dist

Note: The gradlew command automatically downloads the correct Gradle version if needed, you do not need to download it first.

This will generate a distribution similar to the zip you can download on the Groovy download page.

To build everything and launch unit tests, use:

    gradlew test

If you want to launch one unit test, use this. <TestClassName> is like `groovy.GroovyMethodsTest`.

    gradlew :test --tests <TestClassName>

To build from IntelliJ IDEA:

    gradlew jarAll idea

Then open the generated project in IDEA.

To build from Eclipse:

    gradlew jarAll eclipse

Then open the generated project and the generated subprojects in Eclipse. But be aware that Eclipse tends to be more limited in its ability to reproduce a Gradle build structure. The generated project files may contain a circular dependency which may or may not prevent Eclipse from using them. It depends on the Eclipse version, if this is an issue or not.

To build the documentation (Groovy Language Documentation):

    gradlew assembleAsciidoc

All code samples of the documentation guide are pulled from actual test cases.  To run a single documentation test case, take for example `src/spec/test/semantics/PowerAssertTest.groovy`

    gradlew testSinglePowerAssertTest

(Note the omission of package name: class is `semantics.PowerAssertTest` but only `PowerAssertTest` is added to `testSingle`.)

== InvokeDynamic support

The Groovy build supports the new Java 7 JVM instruction `invokedynamic`. If you want to build Groovy with invokedynamic, you can use the project property `indy`:

    gradlew -Pindy=true clean test

Please note that the following Gradle tasks generate both indy and non indy variants of the jars, so you don't need to use the system property:

* dist
* install
* uploadArchives

== Continuous Integration Server

The official CI server runs {groovy-ci}[here] (login as user guest and leave the password blank) and is sponsored by http://www.jetbrains.com[JetBrains].

== License

Groovy is licensed under the terms of the http://www.apache.org/licenses/LICENSE-2.0.html[Apache License, Version 2.0]


Update README for v0.3

Update README for v0.3

= google-java-format-gradle-plugin
:release-version: 0.3
:default-google-java-format-version: 1.0
:snapshot-version: 0.4-SNAPSHOT

A https://github.com/gradle/gradle[Gradle] plugin that utilizes
https://github.com/google/google-java-format[google-java-format] to
format the Java source files in your Gradle project.

image:https://travis-ci.org/sherter/google-java-format-gradle-plugin.svg?branch=master["Build
Status",
link="https://travis-ci.org/sherter/google-java-format-gradle-plugin"]

== Quick Start
* Apply the plugin in your build script (follow https://plugins.gradle.org/plugin/com.github.sherter.google-java-format[these instructions]
for Gradle versions below `2.1`)
+
[source,groovy]
[subs="attributes"]
----
plugins {
  id 'com.github.sherter.google-java-format' version '{release-version}'
}
----
+

* Make sure you have defined a repository that contains version `{default-google-java-format-version}` of `google-java-format`
+
[source,groovy]
----
repositories {
  jcenter()  // or mavenCentral()
}
----

* Execute the task `googleJavaFormat` to format all `*.java` files in the project
+
[source,shell]
----
$ ./gradlew goJF
----
+
* Execute the task `verifyGoogleJavaFormat` to verify that all `*.java` files are formatted properly
+
[source,shell]
----
$ ./gradlew verGJF
----

== Extended Usage
* The plugin adds the extension `googleJavaFormat` to your project. Adjust the variable `toolVersion` to use a specific version of `google-java-format`. You can even define `SNAPSHOT` versions, but make sure that you have added a repository to the project that contains this version (e.g. `mavenLocal()`). For plugin version `{release-version}` this value defaults to `{default-google-java-format-version}`. On every new release the default value will be updated to the latest version of `google-java-format`.
+
[source,groovy]
[subs="attributes"]
----
googleJavaFormat {
  toolVersion '1.1-SNAPSHOT'
}
----

* Choose betweeen `'GOOGLE'` (default) and `'AOSP'` style by setting the style option (not supported in conjunction with `toolVersion` `v0.1-alpha`):
+
[source,groovy]
----
googleJavaFormat {
  options style: 'AOSP'
}
----

* The predefined tasks `googleJavaFormat` and `verifyGoogleJavaFormat` by default process all `*.java` files found in the project or any subproject (except for files in a `buildDir`). They are of type `https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/SourceTask.html[SourceTask]` and can be configured accordingly. For example, if you want to exclude specific files from a predefined task you can use https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/util/PatternFilterable.html[Ant-style exclude patterns].
+
[source,groovy]
[subs="attributes"]
----
tasks.googleJavaFormat {
  exclude '**/*Template.java'
  exclude 'src/test/template_*'
}
----
+
You can also overwrite the default inputs and use your own rules (see `https://docs.gradle.org/current/userguide/working_with_files.html[Working With Files]`)
+
[source,groovy]
[subs="attributes"]
----
tasks.verifyGoogleJavaFormat {
  setSource fileTree('subprojects')
  include '**/*.java'
}
----

* Define your own format or verification tasks, if you need more than the predefined ones. The task type `VerifyGoogleJavaFormat` also implements the interface `https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/VerificationTask.html[VerificationTask]`.
+
[source,groovy]
----
import com.github.sherter.googlejavaformatgradleplugin.GoogleJavaFormat
import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat

task format(type: GoogleJavaFormat) {
  source 'src/main'
  source 'src/test'
  include '**/*.java'
  exclude '**/*Template.java'
}

task verifyFormatting(type: VerifyGoogleJavaFormat) {
  source 'src/main'
  include '**/*.java'
  ignoreFailures true
}
----

== Snapshots
On every push to the master branch https://travis-ci.org/[Travis] runs
the tests and, if all tests pass, publishes the built artifact to
https://oss.sonatype.org/content/repositories/snapshots/[Sonatype's
`snapshots` repository]. Use the following build script snippet for
the current snapshot version:

[source,groovy]
[subs="attributes"]
----
buildscript {
  repositories {
    maven {
      url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
  }
  dependencies {
    classpath 'com.github.sherter.googlejavaformatgradleplugin:google-java-format-gradle-plugin:{snapshot-version}'
  }
}

apply plugin: 'com.github.sherter.google-java-format'

= google-java-format-gradle-plugin
:release-version: 0.2
:default-google-java-format-version: 0.1-alpha
:snapshot-version: 0.3-SNAPSHOT

A https://github.com/gradle/gradle[Gradle] plugin that utilizes
https://github.com/google/google-java-format[google-java-format] to
format the Java source files in your Gradle project.

image:https://travis-ci.org/sherter/google-java-format-gradle-plugin.svg?branch=master["Build
Status",
link="https://travis-ci.org/sherter/google-java-format-gradle-plugin"]

== Quick Start
* Apply the plugin in your build script (follow https://plugins.gradle.org/plugin/com.github.sherter.google-java-format[these instructions]
for Gradle versions below `2.1`)
+
[source,groovy]
[subs="attributes"]
----
plugins {
  id 'com.github.sherter.google-java-format' version '{release-version}'
}
----
+

* Make sure you have defined a repository that contains version `{default-google-java-format-version}` of `google-java-format`
+
[source,groovy]
----
repositories {
  jcenter()  // or mavenCentral()
}
----

* Execute the task `googleJavaFormat` to format all `*.java` files in the project
+
[source,shell]
----
$ ./gradlew goJF
----
+
* Execute the task `verifyGoogleJavaFormat` to verify that all `*.java` files are formatted properly
+
[source,shell]
----
$ ./gradlew verGJF
----

== Extended Usage
* The plugin adds the extension `googleJavaFormat` to your project. Adjust the variable `toolVersion` to use a specific version of `google-java-format`. You can even define `SNAPSHOT` versions, but make sure that you have added a repository to the project that contains this version (e.g. `mavenLocal()`). For plugin version `{release-version}` this value defaults to `{default-google-java-format-version}`. On every new release the default value will be updated to the latest version of `google-java-format`.
+
[source,groovy]
[subs="attributes"]
----
googleJavaFormat {
  toolVersion '0.1-SNAPSHOT'
}
----

* The predefined tasks `googleJavaFormat` and `verifyGoogleJavaFormat` by default process all `*.java` files found in the project or any subproject (except for files in a `buildDir`). If you want to exclude specific files from a predefined task you can use https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/util/PatternFilterable.html[Ant-style exclude patterns].
+
[source,groovy]
[subs="attributes"]
----
tasks.googleJavaFormat {
  exclude '**/*Template.java'
  exclude 'src/test/template_*'
}
----

* Define your own format or verification tasks, if the predefined ones don't suite you needs. Both task types `GoogleJavaFormat` and `VerifyGoogleJavaFormat` are subtypes of `https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/SourceTask.html[SourceTask]` and can be configured accordingly. The task type `VerifyGoogleJavaFormat` also implements the interface `https://docs.gradle.org/2.0/javadoc/org/gradle/api/tasks/VerificationTask.html[VerificationTask]`.
+
[source,groovy]
----
import com.github.sherter.googlejavaformatgradleplugin.GoogleJavaFormat
import com.github.sherter.googlejavaformatgradleplugin.VerifyGoogleJavaFormat

task format(type: GoogleJavaFormat) {
  source 'src/main'
  source 'src/test'
  include '**/*.java'
  exclude '**/*Template.java'
}

task verifyFormatting(type: VerifyGoogleJavaFormat) {
  source 'src/main'
  include '**/*.java'
  ignoreFailures true
}
----

== Snapshots
On every push to the master branch https://travis-ci.org/[Travis] runs
the tests and, if all tests pass, publishes the built artifact to
https://oss.sonatype.org/content/repositories/snapshots/[Sonatype's
`snapshots` repository]. Use the following build script snippet for
the current snapshot version:

[source,groovy]
[subs="attributes"]
----
buildscript {
  repositories {
    maven {
      url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
  }
  dependencies {
    classpath 'com.github.sherter.googlejavaformatgradleplugin:google-java-format-gradle-plugin:{snapshot-version}'
  }
}

apply plugin: 'com.github.sherter.google-java-format'
----

=== New Features
* Support for options:
+
[source,groovy]
----
googleJavaFormat {
  options <type>: <value>, <type>: <value>, ... // e.g. options style: 'AOSP'
}
----
|===
|option | possible values

|style
|'GOOGLE', 'AOSP'
|===