On 08/09/2011, at 1:54 AM, davide.cavestro wrote:
> Just got the ugliest workaround running. Having a multiproject that includes
> some projects, and every project having only external dependencies, it
> simply introduces before /compileJava/ a dependency on the maven install
> task for projects (within the multiproject) related to external
> dependencies.
>
> It's only a raw attempt to mimic a sort of /smarter dependency resolution/.
>
>
> This workaround is only for multi-project builds... and that's a pity, but
> if I check out only a single project, it continues to build downloading
> dependencies from the maven repo.
>
> Any remark/suggestion?
If you want to substitute in projects from within the same (multi-project)
build, as it sounds like you're doing above, another approach might be: Once
the build scripts for all projects have been executed, run through the set of
dependencies, and replace external dependencies that refer to projects in the
same build with actual project dependencies.
For example, in the root build.gradle:
gradle.projectsEvaluated {
allprojects {
configurations.each { config ->
config.dependencies.withType(ExternalDependency).each { dep ->
def targetProject = findTargetProject(dep)
if ( targetProject ) {
config.dependencies.remove(dep)
dependencies.add(config.name, targetProject)
}
}
}
}
}
def findTargetProject(ExternalDependency dep) {
// iterate over all projects, look for match on group+name, return if found
}
(this code probably needs a tweak based on which version of Gradle you are
using, but you get the idea)
What's nice about this approach is that you get all the goodness of Gradle
knowing about the dependencies between the projects: IDE support understands
this, you can use 'buildNeeded' and 'buildDependent', etc.
For projects outside the build, you'd need to use a different approach. One
option: Once all the projects have been evaluated, run through the set of
dependencies. For each one which refers to a project that can be built locally
(however it is you decide that), add an 'install<Project>' task of type
GradleBuild, which runs the install task for the project. Then, add a dummy
file dependency to the configuration which depends on this install task:
gradle.projectsEvaluated {
allprojects {
configurations.each { config ->
config.dependencies.withType(ExternalDependency).each { dep ->
def targetProjectDir = findTargetProject(dep)
if ( targetProjectDir ) {
def installTask = rootProject.task("install$dep.name",
type: GradleBuild) {
dir = targetProjectDir
tasks = ['install']
}
dependencies.add(config.name, files() { builtBy installTask
})
}
}
}
}
}
def findTargetProjectDir(ExternalDependency dep) {
// Figures out where to find the project on the local filesystem, if
available.
}
This is definitely a use case I want to tackle soon after Gradle 1.0 is
available. We'd start probably with a plugin that packages up the above logic.
You'd apply the plugin and provide us with some mapping from external
dependency to target project directory. We'd then improve the plugin over time:
* Add some support to the IDE plugins, so that locally available projects are
dragged into the IDE project with the appropriate
dependencies between them.
* Use the artifacts directly out of the external projects, as we do for project
dependencies, rather than routing through maven cache.
* Add a conventional location to look for local projects, and use them
automatically if found. For example, I might just check out a bunch of source
trees into, say, a '~/gradle' directory and Gradle will just wire them together
automatically.
* Make 'buildNeeded' work across build boundaries. Maybe make 'buildDependents'
work across build boundaries in the other direction, so that it builds all
local projects that depend on the project.
* Make external builds first-class citizens, so that you can refer to their
tasks and publications directly from the build and the command-line, see them
in the UI, and so on. By doing this, buildSrc can become a regular external,
stand-alone project which happens to live in a conventional location.
There's lot of interesting stuff we can do in this space.
--
Adam Murdoch
Gradle Co-founder
http://www.gradle.org
VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting
http://www.gradleware.com