Stellar! Thanks for the effort and the writeup. I came across both the configurations copy() and the resolveAsReport() but didn't combine the approaches. Also the assignment of the dependency to a var didn't occur to me (ok, I'm coding in Groovy since 2 days or so ;) ).
I continued to search the web and finally found a lead as to how to solve it with Ivy (either I'm pretty blind, or no one is using that feature yet). Ivy has a PackagerResolver[1] that addresses the issue. It has a standard ivy file that resolves to a packager.xml, which in turn contains instructions for downloading postprocessing non-standard artifacts. Check the doc at [1] and the public IvyRoundup repository (Google Code) [2]. If I find out anything worthwhile about the issue, I'll let you know. Cheers, Daniel [1] http://ant.apache.org/ivy/history/trunk/settings/resolvers.html [2] http://code.google.com/p/ivyroundup/ On Wed, May 27, 2009 at 1:13 AM, Hans Dockter <[email protected]> wrote: > > On May 26, 2009, at 4:49 PM, Daniel wrote: > > Ok, I have been trying to confine all the nasty details of that Jython >> artifact handling thing. >> >> But I'm stuck in Gradle. Below is an annotated version of what I have been >> trying to get working. I tried to confine everything to one task to not have >> all the details spread through the build code. If I have to structure it >> differently, please tell me. Also, I'm pretty sure that I have a boatload of >> things that could be coded neater, but I lack the knowledge to make it >> smooth. Also the current problem is, even if I get past the Ivy cached >> resolutions, Ivy uses the sourceforge resolver, and can actually download >> something (an error page), which then fails to work, obviously). >> >> >> I also tried to solve the problem with a custom IvyResolver, but the >> resolver code is pretty involved, and I'm not sure where I have to plug in >> (on stackoverflow.com: >> http://stackoverflow.com/questions/908371/apache-ivy-resolving-dependencies-embedded-in-an-installer >> ) >> >> Thanks in advance for any help, it's deeply appreciated >> > > Here is one possible solution. > > configurations { > jythonInstaller > jython > } > > def jythonDep > > dependencies { > jythonDep = jython("jython:jython:2.5rc2") > jythonInstaller("jython:jython_installer:${jythonDep.version}") > } > > def pythonRepoDir = "$projectDir/jython" > > repositories { > flatDir(dirs: "$pythonRepoDir") > } > > task getJython << { > def resolveReport = configurations.jython.copy().resolveAsReport() > if (!resolveReport.hasError()) throw new StopExecutionException() > > repositories { > add(new org.apache.ivy.plugins.resolver.URLResolver()) { > name = "python_sf" // For non standard resolvers the name > is required > addArtifactPattern("http://downloads.sourceforge.net/ > [organisation]/[artifact]-[revision].[ext]") > } > } > > File installerFile = > configurations.jythonInstaller.resolve().iterator().next() > ant { > delete(dir: pythonRepoDir) > java(jar: installerFile.path, fork: true) { > arg(value: '--silent') > arg(value: '--directory') > arg(value: "$projectDir/jython") > arg(value: '--type') > arg(value: 'standalone') > //arg(value: '--verbose') // no effect when used called here. > } > move(file: "$projectDir/jython/jython.jar", tofile: > "$pythonRepoDir/jython-${jythonDep.version}.jar") > } > } > > task showJythonFile(dependsOn: getJython) << { > println configurations.jython.resolve() > } > > gradle showJythonFile should always produce the jython jar. > > A couple of remarks: > > - After a configuration is resolved it is immutable. Any attempt to change > to its state leads to an exception. What a configuration (resolved or > unresolved) does offer is a copy method, which creates a new unresolved > configuration with the same dependencies. > - The behavior of the Ivy URL resolver to return a html page as jar in case > the jar is not found is odd. Is this a known Ivy issue? > > In the above solution we have two configurations. The first is for the > actual jython jar, the second for the installer. We use a copy of the first > configuration to check if the jar can be found. To avoid the URL resolver > bug, we haven't added the sourceforge resolver to the repositories yet. We > also use the resolveAsReport method which returns an ivy resolve report and > does not throw an exception in case of a resolve error. This native Ivy > object has a method hasError. If the jython jar does not exist locally, we > add the sourceforge repository and download the installer. Then we create > the jython jar with in the directory of the flat dir repository. The flat > dir repository does not use the cache for retrieving the jar (as it is local > anyway). > > Conclusions: > - This solution is not flawless. If for example this project retrieves > additional dependencies and one of those dependencies are not available, the > sourceforge repository would hide and download a html page instead as the > jar. There are ways to deal with this situation. But it would be nice if > Gradle offered a way do have multiple repository contexts per project for > dependency retrieval. You could do this already with 0.6 by using the > internal API (as a last resort). > - Right now we use the native Ivy resolver classes as our repository > objects. The API does not always offer what we want (e.g. we would like to > ask the flat dir resolver for its root directories). We will provide our own > domain classes for repositories in a future (pre-1.0) release. > - Instead of the flat dir resolver you could use a default Ivy FileSystem > resolver. In this case the cache would be used for storing the jar and you > could work with temporary directories. > > Thanks for the interesting use case. > > <snip> > > > - Hans > > -- > Hans Dockter > Gradle Project Manager > http://www.gradle.org > > > > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > >
