Hans Dockter wrote:
On Jan 1, 2009, at 10:02 PM, Adam Murdoch wrote:
Tom Eyckmans wrote:
Hi,
I've got a dilema...
As you know I'm working on the TestNG framework support. Currently
the dependency on TestNG is added when the TestFramework
implementation class is configured (doFirst on the test compile
task). I'm not sure if this is the most transparent way. Perhaps it
is better not do add the dependency in code an have the dependency
stated in the dependency block so all dependencies are stated in one
place.
Shouldn't TestNG already be included in the testCompile
configuration? The test code has a direct compile-time dependency on
TestNG, so it really should be included.
I can think of a few similar cases, where a plugin provides some kind
of integration with a library with an API that the application code
uses directly. In each case, we use a different approach for finding
the library, which I don't think is very good. I think it's important
to have a consistent approach to this problem. I don't really care
which one we choose.
Current integrations for libraries used by application code
(excluding the build file):
- java. API + runtime provided by the jvm the build is running in,
and we assume the version is the appropriate one for the project. No
way to declare which version to use.
Right now you have three switches:
JAVA_HOME for the JDK Gradle is using
Compile: executable options to choose the JDK for compiling
Test: jvm option to choose the JRE for running the tests.
We might come up with a nicer way to define the project JDK/JRE.
It would be nice if this we could make this explicit in the build file,
and use the specified value to set the above switches where appropriate
(eg JAVA_HOME when forking stuff, sourceCompatibility when compiling,
etc). We should probably default the version to that which Gradle is
using to execute.
It feels like something you would add to the compile or runtime
configurations.
- groovy. API + runtime must be declared in a separate 'groovy'
configuration.
Theoretically it is a similar scenario to Java. But there are
important practical difference.
- Groovy code is much more sensitive to the Groovy version than Java
code. Java's compatibility is extremely reliable, in contrast to
Groovy. If Gradle would pick up the Groovy which is installed on the
machine, we would have many issues due to that (e.g. we get an NPE if
we run Gradle with Groovy 1.5.8). So bundling Groovy makes Gradle more
reliable.
I think this just means it's less likely that you want to use the
default version that we provide. I don't see it as a real difference.
- Our target group are Java developers. We can expect that Java is
installed on there machines. We can't expect the same for Groovy. So
bundling Groovy s convenient for many of our users.
- Groovy is a library on top of Java. Dealing with Java as a library
would probably not work out.
I'm not suggesting we treat the JDK or Groovy as just a library - I
think we should 1) treat all these things consistently as dependencies,
and 2) that dependencies are polymorphic in how they are resolved and
made available. For some types of dependencies we might just search for
installed versions on the local machine (eg JDKs). For other types we
might just make the version currently being used by Gradle available (eg
Gradle API). And for other types we might download and 'install' the
dependency from a repository (eg Groovy, junit, testng, servlet api,
etc). In all cases, if we can't make the specified version available, we
would blow up with a 'version not available' error message.
Given this, groovy feels like something you would add to your compile or
runtime configurations.
So I think it is OK to have different approaches if there are reasons
for this.
- junit. API must be declared in 'testCompile' configuration. Runtime
is provided by Gradle's lib directory. No way to declare which
version to use for runtime.
Right. We have to improve this.
- testng. API must be declared in 'testCompile' configuration.
Runtime provided by an implicit dependency added by one of the tasks.
- servlet. API must be declared in 'compile' configuration. Runtime
is provided by Gradle's lib directory. No way to declare which
version to use for runtime.
Right. I'm looking forward to our future plugin system.
- gradle. API + runtime provided by version of Gradle the build is
running in. The build file has to use ClassPathUtils and perform some
unmanaged compile classpath magic. No way to declare which version to
use.
The only way right now we use the Gradle classpath is when building
the build sources.
It's also used when you are building a library which provides some
plugins or tasks for use in other builds.
I'm looking forward to our OSGi kernel to make this nicer. But why
would we want to declare the usage of the different Gradle version
within Gradle?
To build the project, you probably wouldn't. However, this dependency
declaration is not used only for building the project. It is also an
output which declares what the project will need at runtime. You are
specifying which versions of the API your plugins or tasks work with,
and it would be up to the consuming instance of Gradle, rather than the
producing instance of Gradle, to either provide an implementation of
that API or blow up with a reasonable error message.
I don't see why we shouldn't be using the same approach for all of
these.
I agree for groovy, junit, testng and servlet. I'm not sure about Java.
Personally, I prefer that the dependency is explicit in the build
file. For some kinds of dependencies (java + gradle) the best we can
do for starters is to simply assert that the current JVM or Gradle
version is compatible with the desired versions. In fact, for all our
integrations, we should assert that the desired runtime version is
one that works with the integration.
Right.
A potential convenience would be to add an implicit dependency with a
reasonable default version, when we can determine the dependency
exists from the context, such as adding junit or testng when tests
are present, or groovy when using the groovy plugin, or gradle when
using the plugin plugin.
We should think about this.
It would be nice if we just reached into the runtime/testRuntime
configurations and found the runtime there, rather than adding
special configuration for each integration.
Good point.
- Hans
--
Hans Dockter
Gradle Project lead
http://www.gradle.org
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email