On Sep 2, 2009, at 1:57 AM, Adam Murdoch wrote:
Hi,
I've made a few changes to how you implement tasks over the last
month or so. Here's a bit of a summary, with some questions at the
end.
1. You don't need to provide a constructor any more.
We now inject the project and name around the side directly into
AbstractTask. This means we can also inject other things, such as
the OutputHandler, without exposing this to the task implementations.
2. You can mark the 'main' method of a task with the @TaskAction
annotation. It automatically gets added as a task action.
3. There's some documentation:
http://gradle.org/latest/docs/userguide/custom_tasks.html
4. You can mark the input and output properties of a task using
annotations:
@InputFile
public File getConfigFile()
@InputDirectory
public File getTestClassesDir()
@InputFiles
public Iterable<File> getSourceDirs()
@OutputFile
public File getReportFile()
@OutputDirectory
public File getDestinationDir()
Currently, we use these annotations to apply some validation to the
task properties. The validation is added as a task action, so it is
performed just before the task is executed:
@InputFile/@InputDirectory: Check the property is not null, and the
specified file exists and is a file/directory
@InputFiles: Check the property is not null.
@OutputFile/@OutputDirectory: Check the property is not null, and
that the specified file can be created as a file/directory. Also
create the parent dir if it does not exist.
There's also an @Optional annotation, which switches off the not-
null check, and a @SkipWhenEmpty, which skips the task if the
associated @InputFiles property is an empty FileCollection.
I'd like to use these annotations to also:
- Wire up dependencies. For example, we know that build/classes/main
is an output file of both the compileTest and processTestResources
tasks, and an input file of the test task, so we could automatically
add the these as dependencies of the test task. We also know that
the classpath of the test task is actually the testRuntime
configuration, so we could automatically add its buildDependencies
to the test task.
That would be very cool.
That is,
task intTests(type: Test) {
testClassesDir = source.intTests.classesDir // auto add
compileIntTest and processIntTestResources
classpath = configurations.testRuntime // auto add
testRuntime.buildDependencies
}
- Apply optimisation. For example, we know that build/classes/main
and testRuntime are input files of the test task, and that build/
reports/test is an output dir of the test task. We can skip test if
its input files have not changed since it last executed successfully
and if its output dir exists and is not empty. We can decide whether
its input files have changed by hashing them, or using their
timestamps, or the last successful execution time of the tasks which
produce those files.
One question I have is how to apply this to task actions which are
added to the task as closures:
task intTests(type: Test)
intTests.doFirst {
.. some setup ..
}
or
task explodedDistBase << {
.. copy some stuff ..
}
One option is to allow you to declare the input and output files of
a task:
task explodedDistBase(inputDirs: source.main.groovySrcDirs,
outputDir: distDir) << {
copy { from inputDirs; into outputDir }
}
where 'inputFile', 'inputDirs', 'inputFiles', 'outputDir', etc
correspond to the @InputFile annotation, etc, and are added as
properties of the task.
Could you explain a bit more the problem?
- Hans
--
Hans Dockter
Gradle Project Manager
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email