Tom Eyckmans wrote:
Thank you Adam for the info,

I agree that the same approach should be used for all these dependencies and that they should all be declared explicitly in the build file.

Some ideas that might make the dependency handling more consistent (without breaking the current way of working):

Allow the installed Java & Groovy JDK's to be defined in the gradle.properties file like so:

dependencies.java:<jdk-provider>:<jdk-alias>:<jdk version>=<path to jdk home> => dependencies.java:sun:default:1.5.0.16=/usr/lib/jvm/java-1.5.0-sun-1.5.0.16

I think a Gradle init script would be a better place for these declarations. This would be overloading the .properties file a little too much.

dependencies.groovy:<jdk-alias>:<jdk version>=<path to jdk home> => dependencies.groovy:default:1.5.6=/home/teyckmans/bin/groovy-1.5.6


We should try to treat groovy exactly the same way we treat any other library we integrate with. That is, we can go and find it in a repository. I don't see that we need to declare groovy versions anywhere other than the dependencies section of a project.

(included the jdk-alias for people who change the jdk itself and may have different setups of the same jdk-version - for none jdk development this is irrelevant I think)

and allow it to be used in the build like so:

java(':<jdk provider>:<jdk-alias>:<jdk-version>') => java(':sun:default:1.5.0.16')
groovy(':<jdk alias>:<jdk-version>') => groovy(':default:1.5.6')

We could add some additional smart features to these dependencies. For the Java dependency we could default the sourceCompatibility/ targetCompatibilty to that of the JDK. When no java dependency is declared we default to that of the runtime.


This is a good idea.

For the JUnit / TestNG dependencies we need to have some way to have finer control over the resolved dependencies, with this I mean we need to be able to get a list of all the files that represent the JUnit/TestNG dependency so we can use the file paths to create an Ant path so we can do a taskdef with the correct files ( currently I scan the classpath files for a file that starts with testng - not a very nice/safe way of doing it). (This sentence contained way to many 'so we can do's :P).


This also applies to our use of groovy. I think the approach is good (ie the library has already been declared in the compile/runtime configurations, so let's just use it from there). We can improve the implementation by, say, providing a way to resolve just a particular module (junit/testng/groovy) from a configuration.

With this I think of another dependency on Ant (currently we kinda force the version that ships with Gradle). We could do something similar like the Java/ Groovy JDKs => ant(':default:1.7.1'). But allowing the Ant version to be configured posses another difficulty. The Ant task to execute TestNG is included in the TestNG distribution but the Ant task to execute JUnit is not part of the JUnit distribution but can only be found in ant-junit. I've checked the maven repo and the versions of ant-junit (ends on 1.6.5) published are not the same as ant (ends on 1.7.0) so it is not a 1-1 relation ship. The only decent solution I can think of is, is natively supporting JUnit and not depend on Ant for the execution of the JUnit tests (I think we are planning along this line anyway so that shouldn't be a problem).


Strictly speaking ant is a transitive dependency of the application (that is, it is a dependency of the junit/testng/groovy tasks, not a direct dependency of the application). What we should do in our integrations is either assert that the version of ant we will use to run the task (ie the one distributed with Gradle) is compatible with the versions specified by the tasks, or run the task in another classloader with the correct version of ant (which we already do for the groovy compile task)

Servlet API I can't really folow how the servlet-api.jar finds its way onto the compile classpath?

You declare it in your compile configuration. The jetty plugin provides an implementation of that API at runtime.

If this is an issue with the Jetty plugin we might make the dependencies section in the gradle.properties file more generic and make it so that subsections (java, groovy) are handled by some kind of handler that reads the config and makes the java/groovy methods available in the dependencies block. This would make it also possible to add for example a jetty method available in the dependencies block (and by that make the servlet-api that gets on the classpath configurable). I think we should the dynamic java/groovy method stuff anyway would be nice :).

Gradle API I'm not sure how that would work but than again I don't know nearly as much about Gradle as you guys :). Not sure why you would want to be able to do that either could you provide a use case?

When you are writing plugins or tasks (as a library or in your buildSrc project) you need to include the Gradle API in your compile classpath, and you need an implementation in your runtime classpath.

In the Hudson Gradle plugin you can configure the available homes of gradle and choose that one that needs to be used by a specific build task (I'm sure you mean something different).

All of this configuration stuff should be easily available through our API because all of the java/groovy/ant home configuration is already done in CI-servers so when they intergrate with Gradle they should have a convenient way of transfering the configuration that is already available in the CI-server.


A good idea.

Tom

2009/1/1 Adam Murdoch <[email protected]>


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.

- groovy. API + runtime must be declared in a separate 'groovy' configuration.

- 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.

- 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.

- 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.

I don't see why we shouldn't be using the same approach for all of these.

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.

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.

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.


Adam

---------------------------------------------------------------------
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