Posts Tagged ‘build’

A New Gradle Grails Plugin

5 Comments »

My team wanted to use Gradle to build our Grails project.  We had some trouble with version compatibility problems between Grails and the Grails build plugin, though.  Instead of using the plugin, we tried writing some code that called the ‘grails’ command directly, but that caused problems with the CI server because it required that the correct version of Grails be preinstalled on all build servers and exist in a known location.  I decided to try my hand at writing a simpler Grails build plugin and this is what I came up with.  It doesn’t require Grails to be pre-installed on the machine and, since it just executes the ‘grails’ command, it works with any version.

Fork it!  Or just use it 🙂

Gradle Grails Wrapper


Functional Test and Integration Test Targets in Gradle

3 Comments »

* Update February 13th, 2012: Thanks to Ben Ripkens for updates to match the new Gradle API.

While searching online, I found many suggestions for how to add a new test target to a Gradle script. Most of them were wrong and others didn’t properly separate the integration test target from standard targets. After not finding a solution, I came up with one on my own.

This example sets up integration tests for Groovy .

Create a source set

This will separate the integration test code from other code, allowing it to be built separately.

  • The classpath in the example gives integration tests access to all application and test classes
  • The source location will be src/integrationTest/groovy
sourceSets {
  integrationTest {
    compileClasspath = sourceSets.main.output + configurations.testRuntime
    runtimeClasspath = output + sourceSets.main.output + configurations.testRuntime
    groovy {
      srcDir 'src/integrationTest/groovy'
    }
  }
}

Add the target

 

task integrationTest(type: Test) {
  testClassesDir = sourceSets.integrationTest.output.classesDir
  classpath = sourceSets.integrationTest.runtimeClasspath
}

 


Antcall vs Depends

4 Comments »

Occasionally, I see issues pop up on Java projects about builds not working properly.  They usually look like, “The build worked yesterday, but it doesn’t work today.  I was working on it, but I didn’t change anything related to the part that is failing.” or “I can’t figure out why, when I run this by itself, it passes.  When I run it as a part of a full build, it fails.”  Build errors are almost always caused by a misunderstanding of the function of “depends”.

How Not to Use Depends

This probably works, but only by chance.

<target name="test" depends="clean,compile,compile-test,test,service-test" />

Depends is not a list of tasks to be executed.  It’s a list of dependencies that must be satisfied before a target can be completed.  Execution is not guaranteed and side effects are common.  Take a close look at what each of the tasks in the following script is doing.

<target name="functional-test" depends="start-server,run-tests,stop-server" />
<target name="service-test" depends="start-server,run-service-tests,stop-server" />
<target name="test" depends="clean,compile,compile-test,functional-test,service-test" />

To a human, the intent is obvious.

  1. Clean and compile
  2. Start server
  3. Run functional tests
  4. Stop server
  5. Start server
  6. Run service tests
  7. Stop server

But Ant will not execute those tasks.  Since they were declared as dependencies, Ant evaluates them as such.  The functional tests will run as you would expect.  When it runs the service-test target, though, it will see the start and stop server tasks again.  As far as it’s concerned, those dependencies have already been satisfied, so it will skip start-server and stop-server.  Ant is evaluating the script correctly, but the script is wrong.

Dependencies are not tasks to be executed.  They are dependencies.  Once a dependency has been satisfied, it will not be executed again.

Antcall Is Not Evil

It exists for a reason.  Use it when it is useful.  Dependencies are dependencies, not task lists.  In this case, it would be impractical to try to write the script to use depends attributes to cause events to happen correctly.  It can be fixed very easily by using antcall.  Each antcall is evaluated separately, so you don’t have to worry about side effects like the script above.  It’s also easier to read.  You can see what’s intended to happen before this target and you can see what this target is intended to do.

<target name="functional-test" depends="start-server,run-tests,stop-server" />
<target name="service-test" depends="start-server,run-service-tests,stop-server" />
<target name="test" depends="clean,compile,compile-test">
  <antcall target="functional-test" />
  <antcall target="service-test" />
</target>

Use Your Own Judgement

Obviously, antcall should not be used instead of depends.  Depends is far more useful.  But don’t throw a tool like antcall away just because it doesn’t seem as cool or concise or elegant.