Adam wrote:
> Mike wrote:
> > We're working on both an Idea and a TeamCity plugin
> for running gradle. One of the complexities we're having is
> getting runtime information back from gradle while
> executing. While we can get the information we need, it
> requires doing some work that could be simplified. Adding a
> single 'Execution Listener' (similar in spirit to the
> AntBuilderListener) that provides the following would not
> only aid our development, but help future gradle plugins. I
> propose a single Execution Listener interface made up of the
> following:
> >
> > - All the information provided by BuildListener.
> > - All the information provided by
> TaskExecutionListener
> > - Easy access to the logged information (with the
> order of callbacks easily associated with the above
> callbacks).
> >
>
> Are you proposing that ExecutionListener extends
> BuildListener, TaskExecutionListener, etc? Or that we
> replace them?
>
> What would we do with new types of events that embedding
> applications might want to receive, such as test execution,
> file upload and download, compile problems, web app
> deployment, etc? Do we add them to ExecutionListener? What
> about such events that are already available, such as
> project evaluation? Shouldn't these be on ExecutionListener
> as well?
>
> I don't think having a single mega interface scales very
> well as the interaction between Gradle and the embedding
> application gets richer (particularly once we need to
> consider backwards compatibility).
>
> Another, more flexible approach, is to simply make it
> easier to add different types of listeners, at any time
> during the lifecycle, combined with fine-grained listener
> interfaces (ie with a small number of methods). Then you can
> choose which combination of events you are interested in by
> implementing the appropriate interfaces. For example,
> something like this:
>
> Gradle gradle = ....
> MyBuildListener listener = new MyBuildListener()
> gradle.addTaskExecutionListener(listener)
> gradle.addStdoutListener(listener)
> gradle.addStderrListener(listener)
> gradle.run()
>
> Perhaps we could have a generic Gradle.addListener() which
> registers the listener based on which listener interfaces it
> implements:
>
> MyBuildListener listener = new MyBuildListener()
> gradle.addListener(listener)
> gradle.run()
>
> > Currently, getting this information requires adding
> multiple listeners at different times. For example, you have
> to wait for BuildListener.taskGraphPopulated to add a
> TaskExecutionListener. And hooking into Log4J can be error
> prone if you don't setup things just right.
>
> We definitely want to make this easier. I think the way to
> do this is add a small, focused listener interface which you
> can register with the Gradle class, something like:
>
> LoggingListener {
> void messageLogged(...)
> }
>
> And:
>
> Gradle.addStdoutListener(LoggingListener l)
> Gradle.addStderrListener(LoggingListener l)
>
>
> Adam
>
>
I absolutely agree!
It was never the intention of turning this listener into a monolithic listener
that does everything, but rather these specific things seem to make sense going
together. I should have mentioned that there are other listeners that I need
that I felt should be completely separate, such as a compiling and testing.
However, I totally concede that if you could add listeners at any time, then
keeping the finer grained listeners would be a much better solution. With that
in mind, here's a first pass of at a list of listeners you should be able to
register at any time.
BuildListener (works fine as is)
TaskExecutionListener
standard output listener
standard error listener
test execution/results listener
compile listener
Mike
Automated Logic Research Team
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email