I have been trying to make use of the new onlyIf method to optimize our large
build. OnlyIf seemed liked a very useful approach in the abstract, but is
proving to be more of a challenge in a real project. It was useful for a few
tasks (like jar.onlyIf { compile.didWork || processResources.didWork }), but not
for some of the more expensive ones. The Test task, in particular, has been
frustrating.
I tried the somewhat too simple:
test.onlyIf { compile.didWork || testCompile.didWork ||
processTestResources.didWork }
This does exactly what it says, it only runs the tests if new code was compiled
or the test resources changed and this seemed great at first glance. When I
tried this on our real project, however, I was disappointed. What this will do
is to cause the test task for a module to be run only once. If it fails and the
developer does not correct it, then the next time the build is run the test will
be skipped. This gives the false impression that everything is correct when it
is not. To be useful, I think this also needs some type of state information
about whether the tests passed last time, but this is getting more complicated
than I originally envisioned.
I find that I am fighting hard to stop running the test task before making the
jar. While the current dependency chain may seem fine for a single project
build, it becomes frustratingly slow for a really big system. With older
versions of Gradle, I always had to run gradle twice:
gradle -Dskip.test :currentProject:libs
gradle :currentProject:test
The addition of the "-a" option was very helpful with this, so that in normal
daily development we just do:
gradle -a :currentProject:test
This works pretty well. There are some types of dependencies that -a doesn't
skip, so there are some cases where a little more work is done than needed, but
in general this works good. For our continuous build server, though, we still
have a problem. We want to have build configurations for each project that make
a clean build, but only run the tests for their project. This is back to my
original problem where I need to invoke gradle twice. This is not cleanly
handled and we find that we have to make a custom gradle runner :(.
Thanks for sticking with my rant so far - I'll get to the point.
Why must jar depend on test? This seems like an attempt by the build tool to
enforce test driven development. The "do it my way" mentality is one thing that
many people did not like about Maven. At the very least, this should be an
easily configured option - prehaps parameters to the Java plugin?. I think that
I suggested before that the usePlugin method might also take a map so you could do:
usePlugin('java', testJars:true)
While I understand the ideal or testing a jar every time, in practice it often
makes it hard to work with in a multi-project system. I don't want the building
of the jars I depend on to be coupled to the testing of other projects. I want
to be able to run "gradle clean :currentProject:test" to only run the test for
the project that I specified, but still build all the dependencies. This
accomplishes many of the desires I specified earlier for command line syntax
changes, but in a much more straightforward way.
--
Steve Appling
Automated Logic Research Team
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email