On Sep 15, 2008, at 11:02 PM, Adam Murdoch wrote:
Hans Dockter wrote:
On Sep 14, 2008, at 1:01 PM, Adam Murdoch wrote:
Hans Dockter wrote:
On Sep 13, 2008, at 8:51 AM, Adam Murdoch wrote:
It might be interesting to add some DAG mutation methods at
some point. For example, I'd like to be able to request the
execution of a task from another task.
Do you see this as a solution for the doFinally?
Not really, I hadn't really considered that (though it is an
interesting idea). I just wanted it for putting together canned
builds coded up as tasks, eg run 'clean', then 'assemble' with
'test' disabled.
This is really the 'build type' concept which I described (vaguely)
in another email. I'm not sure of the semantics yet, but basically
I want to code up canned builds which are variations of the build
as declared in the build file.
The DAG is currently passed as a method to TaskAction.execute()
and is also reachable from Task. Should we remove it from
TaskAction.execute()? If we do the above, should we remove it
from Task as well? If not, should we add it to Project and
ProjectAction for consistency?
I was thinking about making the DAG accessible from the project.
But I thought this might be not such a good idea, as the hasTask
and getAllTasks methods only have a meaning at execution time.
The fact that the DAG is a member of the BaseTask is an internal
implementation detail. So the only public way of accessing the
DAG right now is via the argument we pass to the TaskAction. If
we introduce listeners we have to make them of course accessible
from the project (in a way you described above). The question is
whether we should expose 'execution time only' methods via this
interface.
I did wonder about this. Even though some information makes sense
only at execution time, it doesn't really make sense to me that
you get at this information via a parameter on a TaskAction. It's
not really something particular to a Task. It's information about
the build as a whole, so it feels to me like something that
should hang off an object that represents the build.
I was thinking of having the methods visible from Project, but
have them throw an exception of some kind when used before the
graph had been assembled.
I don't feel strong about this. An exception would definitely make
sense. We should also throw an exception if dependsOn is called
during execution time.
Or handle it. It's only a problem if the task has already executed
or is currently executing (or introduces a cycle).
One limitation of the current solution is that you can only
access the dag in a task. For example in the Gradle build we
access the DAG in the init task to decide if we attach a
timestamp to the version or nor. Every task now has to depends
on init if it wants to use the version (e.g. userguide
creation). This is not nice. See http://jira.codehaus.org/browse/
GRADLE-163. A method for the taskGraph like beforeGraphExecution
would solve this I think.
I think those listeners are great stuff and with a little bit of
work towards embaddibility they will make it very easy to write
a Gradle IDE plugin. Jayson Minard had already a look into
writing an IDE plugin in 0.2. But our design wasn't ready then.
What we would additionally need in the Build class is:
- a method that returns the task map.
- some filtering of the task map based on projectDir and project.
- exposing the taskGraph object to add listeners.
I was thinking of adding an accessor to Build to get at the
GradleInstance interface (or whatever it is called), so that the
same stuff is available to the thing embedding Gradle as to the
build files. Which I think also includes all the stuff above. We
should perhaps split Build.run() into an initialisation method
and an execution method, so that a plugin could load up the
settings once, do stuff with the GradleInstance, then run tasks a
bunch of times.
This kind of embedded usage is already of interest. For example we
could provide a Gradle UI console then. By using this console you
would avoid the constant startup time penalty of Groovy. An
interesting question is whether you can reuse a evaluated project
tree. It is possible to modify this tree at execution time
(although probably rather unlikely). If this happens the tree
can't be reused.
Hmm, good point. Strictly speaking we can't even reuse the settings
object.
Why?
We can certainly have the scripts compiled up and classes loaded
ready to evaluate.
We have them already compiled in the cache on disk. But keeping them
in memory would be another optimization.
I'm not sure if the actual evaluation time is that big a deal,
relative to the total build time.
In most cases not. In particular as I'm pretty sure that we could
still do significant performance tuning for this evaluation. The only
big performance issue I would like to resolve soon is that the build
source jar is not cached.
I'm more interested in gradle not building things that haven't
changed since last time I ran the build, and for robustly detecting
things that have changed, so that I don't have to do a clean before
I build.
This would definitely be a real time saver.
What do you think about this issue in this context? http://
jira.codehaus.org/browse/GRADLE-66
- Hans
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email