John Murph wrote:
If an external tool (such as an IDE or CI server) wishes to integrate
with Gradle, they will need some way to add listeners and perhaps
customize other aspects of Gradle. The approach that Ant uses for
this is to pass a command line option (-listener <classname>) followed
by a fully qualified class name. Ant then uses reflection to
instantiate this class and registers it as a build listener. This
approach is simple, but very limited. I wish to propose a more
complicated, but also more powerful, approach for Gradle.
I think Gradle should provide a new command line option (--init-script
<path-to-script>). Prior to even finding/loading the settings.gradle
file, this script (if specified) would be executed.
Should we default the init script to something under ~/.gradle, maybe
~/.gradle/init.gradle or similar?
The script would allow tools to run Gradle and point it to a custom
init script that allows for customized behavior. This script would be
run with a "delegate" (similar to how the Project class is a delegate
for the build script) that provides some access to Gradle as well as
support for a convenience DSL.
I'd be tempted to delegate to the Build class. Then, an init script
configures a Build instance just like a build script configures a
Project instance. The Build interface would probably need some tweaks
for this to work. I like that in both cases, the script simply
configures a domain object.
This class (InitScript.groovy?) would provide access to the
startParameters (including allowing them to be modified), and support
a simple DSL for instantiating classes using a custom class loader.
For this, I would use exactly the exact same mechanism(s) we use in the
build script to do this. That is, provide the equivalent of the
buildscript {} closure, something like:
initscript {
repositories { mavenCentral() }
classpath name: 'some-dependency'
}
I would also make Repository and Configuration containers available, so
that the script can do whatever custom dependency management and
classloading it wants.
This latter would make it easy to register a custom build listener,
which is the main intended use. However, as other uses arise, more
functionality could be exposed. For instance, the script might wish
to examine the environment to determine that it is running in a CI
server, and enable/disable specific tasks. To do this, I would assume
the script would set system properties that would then be examined in
the build scripts when the tasks are defined.
Another option is if the script can register code to execute at various
times during the lifecycle of the build:
afterProjectsConfigured {
def isCI = ...
if ( isCI ) {
allprojects {
build.dependsOn uploadArchives
}
}
}
We would allow the init script to receive pretty much any of the events
on BuildListener in the same way.
I would like to hear of any real use cases of which you currently are
aware.
Some other potential uses for an init script:
- Information about the user, such as repository/app server/database
authentication information.
- Personal customisations, such as custom task aliases, logging
configuration, additional plugins to apply.
- Information about the environment, such as where JDKs are installed,
dependency cache configuration, overrides to repository configuration.
It would be nice to have a slightly more "complete" implementation
initially, but I expect new uses to appear over time. The main
problem is that because this script would execute so early in the life
of the execution, many objects will not be created yet (such as the
tasks in my earlier example).
We can deal with this by registering code to execute later in the build.
For example, we do this in the build script when you add an action to a
task.
Some of these cases can be handled more easily than others.
Does anyone have any problems or concerns with this proposal?
I think its a good idea. I think there's heaps of potential uses for an
init script.
Adam
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email