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


Reply via email to