On Jul 20, 2009, at 3:21 PM, Steve Appling wrote:
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.
Gradle should be able to provide such a functionality. But if we have
the build optimization implemented, would this still be an issue for
your use case?
- Hans
--
Hans Dockter
Gradle Project Manager
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email