Loading...

Monday, January 26, 2015

Groovy Goodness: Take Or Drop Last Items From a Collection

We know Groovy has a lot of nice methods for working with collections. For example in previous blog posts we have seen how to take or drop elements from a list and even with a condition. Since Groovy 2.4 we can now also use the dropRight and takeRight methods to take or drop elements from the end of the list.

In the following example we have a simple list and we use the dropRight and takeRight methods to get elements from the list:

def list = ['Simple', 'list', 'with', 5, 'items']

assert list.takeRight(1) == ['items']
assert list.takeRight(2) == [5, 'items']
assert list.takeRight(0) == []
// Whole list, because we take more items then the size of list
assert list.takeRight(6) == ['Simple', 'list', 'with', 5, 'items']

assert list.dropRight(1) == ['Simple', 'list', 'with', 5]
assert list.dropRight(3) == ['Simple', 'list']
assert list.dropRight(5) == []
assert list.dropRight(0) == ['Simple', 'list', 'with', 5, 'items']
assert list == ['Simple', 'list', 'with', 5, 'items']

def array = ['Rock on!', 'Groovy baby!'] as String[]
assert array.takeRight(1) == ['Groovy baby!'] as String[]
assert array.dropRight(1) == ['Rock on!'] as String[]

def range = 0..10
assert range.takeRight(2) == [9,10]
assert range.takeRight(4) == 7..10
assert range.dropRight(5) == 0..5

Written with Groovy 2.4.

Wednesday, January 7, 2015

Gradle Goodness Notebook is Published

Today Gradle Goodness Notebook is published. This book is an electronic publication with all blog posts about Gradle Goodness bundled. The posts are slightly edited and categorized into sections.

The book is published at Leanpub and is available in three formats: PDF, MOBI (for Kindle) and EPUB (for iPad). Updates for the book are free. So new Gradle Goodness blog posts will be added to the book and you will get those free.

It is also possible to buy a Goodness Notebooks bundle. This bundle contains the Groovy and Gradle Goodness Notebook books.

I hope you will enjoy the book and I will keep it up-to-date with new content when I publish new Gradle Goodness blog posts.


Wednesday, December 24, 2014

Gradle Goodness: Rename Ant Task Names When Importing Ant Build File

Migrating from Ant to Gradle is very easy with the importBuild method from AntBuilder. We only have to add this single line and reference our existing Ant build XML file and all Ant tasks can now be executed as Gradle tasks. We can automatically rename the Ant tasks if we want to avoid task name collisions with Gradle task names. We use a closure argument with the importBuild method and return the new task names. The existing Ant task name is the first argument of the closure.

Let's first create a simple Ant build.xml file:

<project>

    <target name="showMessage"
        description="Show simple message">

        <echo message="Running Ant task 'showMessage'"/>

    </target>

    <target name="showAnotherMessage"
        depends="showMessage"
        description="Show another simple message">

        <echo message="Running Ant task 'showAnotherMessage'"/>

    </target>

</project>

The build file contains two targets: showMessage and showAnotherMessage with a task dependency. We have the next example Gradle build file to use these Ant tasks and prefix the original Ant task names with ant-:

// Import Ant build and 
// prefix all task names with
// 'ant-'.
ant.importBuild('build.xml') { antTaskName ->
    "ant-${antTaskName}".toString()
}

// Set group property for all 
// Ant tasks.
tasks.matching { task ->
    task.name.startsWith('ant-')
}*.group = 'Ant'

We can run the tasks task to see if the Ant tasks are imported and renamed:

$ gradle tasks --all
...
Ant tasks
---------
ant-showAnotherMessage - Show another simple message [ant-showMessage]
ant-showMessage - Show simple message
...
$

We can execute the ant-showAnotherMessage task and we get the following output:

$ gradle ant-showAnotherMessage
:ant-showMessage
[ant:echo] Running Ant task 'showMessage'
:ant-showAnotherMessage
[ant:echo] Running Ant task 'showAnotherMessage'

BUILD SUCCESSFUL

Total time: 3.953 secs
$

Written with Gradle 2.2.1

Thursday, December 11, 2014

Awesome Asciidoctor: Nested Delimited Blocks

In our Asciidoc markup we can include delimited blocks, like sidebars, examples, listings and admonitions. A delimited block is indicated by a balanced pair of delimiter characters. For example a sidebar starts and ends with four asterisk characters (****). If we want to nest another delimited block of the same type we must add an extra delimiter character at the start and end of the nested block. So when we want to nest another sidebar block inside an existing sidebar block we must use five asterisk characters (*****).

In the following example Asciidoc source we have several blocks with nested blocks:

== Nested sidebar

[sidebar]
.Sidebar
****
This is just an example of how
// Start nested block with extra *
*****
a nested delimited block
*****
can be defined.
****


== Nested example block

.Nested example
====
Also the example delimited block
// Start nested block
=====
allows nested blocks
======
and nested blocks
======
=====
to be defined.
====

== Nested admonition block

[NOTE]
====
We can nest
[TIP]
=====
adminition blocks
=====
as well.
====

== Mixing delimited blocks

[NOTE]
====
Of course we can also define 
****
another delimited block
*****
with nested block
*****
****
inside delimited blocks.
====

If we transform this to HTML we get the following result:






Written with Asciidoctor 1.5.2.

Tuesday, December 9, 2014

Gradle Goodness: Continue Build Even with Failed Tasks

If we run a Gradle build and one of the tasks fails, the whole build stops immediately. So we have fast feedback of our build status. If we don't want to this and want Gradle to execute all tasks, even though some might have failed, we use the command line option --continue. When we use the --continue command line option Gradle will execute every task where the dependent tasks are not failing. This is also useful in a multi-module project where we might want to build all projects even though some may have failing tests, so we get a complete overview of failed tests for all modules.

In the following Gradle build file we have two tasks. The task failTask throws a TaskExecutionException to purposely fail the task. The successTask will not fail:

task failTask << { task ->
    println "Running ${task.name}"

    throw new TaskExecutionException(
            task, 
            new Exception('Fail task on purpose')) 
}

task successTask << {
    println "Running ${it.name}"
}

Let's run both tasks from the command line and see the output:

$ gradle failTask successTask
:failTask
Running failTask
:failTask FAILED

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/mrhaki/samples/gradle/continue/build.gradle' line: 4

* What went wrong:
Execution failed for task ':failTask'.
> Fail task on purpose

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 4.148 secs
$

We see the build has failed and only the task failTask is executed. Now we run the same two tasks, but we use the command line option --continue:

$ gradle --continue failTask successTask
:failTask
Running failTask
:failTask FAILED
:successTask
Running successTask

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/mrhaki/samples/gradle/continue/build.gradle' line: 4

* What went wrong:
Execution failed for task ':failTask'.
> Fail task on purpose

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 6.918 secs
$

This time the successTask is executed even though the failTask has failed again. Gradle will keep track of all tasks that have failed and displays a summary with all the tasks that have failed.

Written with Gradle 2.2.1

Friday, December 5, 2014

Gradle Goodness: Skip Building Project Dependencies

If we use Gradle in a multi-module project we can define project dependencies between modules. Gradle uses the information from the project dependencies to determine which tasks need to be run. For example if module B depends on module A and we want to build module B, Gradle will also build module A for us, because module B depends on it. But if we know for sure that module A is up to date and has not changed, we can also instruct Gradle to skip building module A, when we build module B.

Let's start with the following module structure, where each module depends on the module above it. So module services depends on common and module web depends on services:

.
├── common
├── services
└── web

When we want to build the service module we go to the services directory and execute the build task and we get the following output:

$ gradle build
:common:compileJava 
:common:processResources 
:common:classes 
:common:jar 
:services:compileJava 
:services:processResources 
:services:classes 
:services:jar 
:services:assemble 
:services:compileTestJava 
:services:processTestResources 
:services:testClasses 
:services:test 
:services:check 
:services:build 

BUILD SUCCESSFUL

Total time: 8.013 secs

We see in the output that first the common module is build, because the services module depends on it. But if we work on this project and we know for sure the common module is up to date and has not changed since the last build (for example we didn't checkout new sources from version control or changed sources in the common module ourselves), then we can skip building the common module. We use the command line option -a or --no-rebuild to tell Gradle to skip project dependencies.

When we run the build task from the services directory using the command line option -a we get the following output:

$ gradle -a build
:services:compileJava 
:services:processResources 
:services:classes 
:services:jar 
:services:assemble 
:services:compileTestJava 
:services:processTestResources 
:services:testClasses 
:services:test 
:services:check 
:services:build 

BUILD SUCCESSFUL

Total time: 5.626 secs

This time only the services module is build, which also speeds up the build proces. Still this should only be used if we know ourselves the project dependencies are up to date.

Written with Gradle 2.2.1.

Thursday, December 4, 2014

Awesome Asciidoctor: Span Cell over Rows and Columns

When we define a table in Asciidoctor we might want to span a cell over multiple columns or rows, instead of just a single column or row. We can do this using a cell specifier with the following format: column-span.row-span+. The values for column-span and row-span define the number of columns and rows the cell must span. We put the cell specifier before the pipe symbol (|) in our table definition.

In the following example Asciidoctor markup we have three tables. In the first table we span a cell over 2 columns, the second table spans a cell over 2 rows and in the final table we span a cell over both 2 columns and rows.

== Table cell span

.Cell spans columns
|===
| Name | Description

| Asciidoctor
| Awesome way to write documentation

// This cell spans 2 columns, indicated
// by the number before the + sign.
// The + sign 
// tells Asciidoctor to span this
// cell over multiple columns.
2+| The statements above say it all

|=== 


.Cell spans rows
|===
| Name | Description

// This cell spans 2 rows,
// because the number after 
// the dot (.) specifies the number
// of rows to span. The + sign 
// tells Asciidoctor to span this
// cell over multiple rows.
.2+| Asciidoctor
| Awesome way to write documentation

| Works on the JVM

|=== 


.Cell spans both rows and columns
|===
| Col1 | Col2 | Col 3

// We can combine the numbers for
// row and column span within one
// cell specifier. 
// The number before the dot (.)
// is the number of columns to span,
// the number after the dot (.)
// is the number of rows to span. 
2.2+| Cell spans 2 cols, 2 rows
| Row 1, Col 3

| Row 2, Col 3

|===

If we transform our source to HTML we get the following tables:

Written with Asciidoctor 1.5.1.

Tuesday, December 2, 2014

Awesome Asciidoctor: Repeating Cell Contents

With Asciidoctor we can repeat cell contents if we prefix the cell separator pipe symbol (|) with the number of times we want to repeat the cell followed by an asterisk (*).

In the following example Asciidoctor source file we define two tables and add 2* to cells that we want to repeat two times:

// 3-column table, where the first column
// cell value is not repeated, and the
// cell value for columns 2 and 3 is 
// repeated.
|===
| Column | Value | Value

| Name 
2*| Asciidoctor

| Description 
2*| Awesome way to write documentation

|=== 


// One column table. So the repeated
// cells are each on their own row.
|===
| Column

2*| Asciidoctor

2*| Awesome way to write documentation

|=== 

When we generate a HTML document from this source we see the following result:

Written with Asciidoctor 1.5.1.

Wednesday, November 26, 2014

Awesome Asciidoctor: Disable Last Updated Text in Footer

When we transform our Asciidoc source files to HTML Asciidoctor will print the date and time the document was last updated in the footer. If we want to disable the Last updated text we disable the document attribute last-update-label.

In the following example Asciidoc file we disable the Last update label in the footer:

:last-update-label!:

= Change footer

To disable the _Last updated_ text
in the footer we disable the document
attribute `last-update-label`.

----
// Disable last updated text.
:last-update-label!:
----

When we transform this to HTML we get the following output:

Written with Asciidoctor 1.5.1.

Tuesday, November 25, 2014

Grails Goodness: Create New Application without Wrapper

Since the latest Grails versions a Grails wrapper is automatically created when we execute the create-app command. If we don't want the wrapper to be created we can use the command argument --skip-wrapper. If later we changed our mind and want the Grails wrapper we can simply run the wrapper command from our Grails application directory.

Let's run the create-app command with the --skip-wrapper argument. If we check the contents of the created directory we see that the wrapper files are not created:

$ grails create-app --skip-wrapper sample 
$ cd sample
$ ls
application.properties lib   src   web-app
grails-app  scripts   test
$

Written with Grails 2.4.4.