[GRADLE-1014] project dependency with file instead of multiproject Created: 30/Jun/10 Updated: 08/Feb/17 Resolved: 08/Feb/17 |
|
Status: | Resolved |
Project: | Gradle |
Affects Version/s: | 0.9 |
Fix Version/s: | None |
Type: | Improvement | ||
Reporter: | Philip Crotwell | Assignee: | Unassigned |
Resolution: | Fixed | Votes: | 42 |
Description |
On Wed, Jun 30, 2010 at 12:48 AM, Adam Murdoch <adam@gradle.biz> wrote: Hi I have found several time that I wish I could tell gradle that one I think this is a pretty common problem, and Gradle should have a good solution for it. At some point soon, we want to split up Gradle itself into a bunch of separate pieces which can be built and released separately (for example, core and several plugin bundles). And we will hit exactly the same problem, where we want to work on the core and plugins at the same time. So we will need a solution to this problem in order to split up Gradle. The current way I do things is to have one So, what I would like to do is instead of: do and as long as there is a build.gradle in the ../myOtherDev/libA It would be good if the dependency declaration were independent of whether you're doing a composite or a standalone build, so that it doesn't have to change when you switch between the two. For example, I don't want to have to use something like this to do a local build: dependencies { and something like this to do a release or CI build: dependencies { One question is which of the above identifiers we should use for a dependency which is sometimes built locally, and sometimes fetched from a repository. One option is to use the (group, name, version) tuple for the dependency, and somewhere else, provide some way to tell Gradle how to build the dependency locally. For example, the following might declare a repository that uses the build script 'someUrl' , if it exists, to build the dependency 'mygroup:otherProject:1.2' locally. repositories { } Then, you would declare the dependency as a normal external dependency: dependencies { Another option is to use a Project object for each dependency which can be built locally or fetched from a repository. For example, the following might create such a Project: def libA = project { Then, you would declare the dependency as a normal project dependency: dependencies { There are advantages and disadvantages to both these options. Option 1 can be applied to any external dependency, whereas for option 2, you have to plan ahead and declare the dependency in a particular way. This means, for example, that option 1 would allow an init script, or a plugin, or another project, or Gradle itself, to inject the local build declaration into the project which contains the dependency. Option 1 also allows us to use a convention for where to find local dependencies. For example, Gradle might, for every dependency, look for $rootDir/../$group/$name/.gradle or ~/gradle/$group/$name/.gradle, and build the dependency locally instead of fetching it from a repository. Option 2 is interesting because it could potentially make other things from the target project available, such as tasks, configurations or properties. You could, for example, declare a task dependency on a task in the target project. This could be used for lots of interesting use cases. The Gradle website build, for example, could make use of this. Option 2 also appeals because it could also be applied within a multi-project build, not just between builds. You could have, for example, a large multi-project build where you have some or all of the artifacts already built by a CI build, and you want to reuse those artifacts and build only a handful of projects locally. Or perhaps you have a build pipeline, where some artifacts are built and tested by one CI build, and then those same artifacts are assembled into a distribution by a later build. This way, we introduce the concept that a build does not always need to build every artifact every time. Option 2 also gives us a way to express in the DSL the way that buildSrc project works. Then, the buildSrc project stops being some special case and becomes a reusable concept: def buildSrc = project { projectDir "$rootDir/buildDir }dependencies { classpath buildSrc } This might also be a way to get away from settings.gradle, as what is Absolutely. One down side is that if the source code is given to another One last idea would be to have a general URL instead of just a file, I think we should end up with something like this. At the very least, Gradle should understand that some dependencies need to be built before they are usable. That might mean building a JAR, compiling a shared lib, installing and starting some software, whatever. If this sounds like an idea worth considering, I'll open a jira issue. It's an excellent idea. Please open a JIRA issue. |
Comments |
Comment by Russ Rollins [ 09/Aug/10 ] |
I believe I echo the same core concept that Philip's communicated: a given environment with x number of Gradle projects, with some subset relying on artifacts generated by one or more in the superset--where these projects may exist in or out of the subproject convention. In my case I will potentially have multiple plugins that may be developed concurrently with projects that will depend on them independent of each build cycle. Thus, it makes sense to have an equivalent native task in Gradle that will install the artifact(s) into the Gradle cache very much akin to mvn install. |
Comment by Davide Cavestro [ 26/Aug/11 ] |
What if we had a way to resolve dependencies against usual libraries or projects using some sort of external mapping, letting different users configure that mapping for their runtime context/workspace. I gave a look at WorkspacePlugin, but maybe it's not the same thing.
Any chance to have it in roadmap for the near future? I guess people working on heavily structured projects could really benefit from this all the time. |
Comment by Marius Kotsbak [ 05/Sep/11 ] |
We also see this need. I hoped that Gradle would be better at this than Maven (which it looked like in the description of Gradle, but turned out to work only for multiprojects, which Maven does also support OK). For us, extracting common code in common modules used by different product modules has backfired because of the need to change code in multiple modules (common module+product module) to implement new features (requiring with maven a lot of "mvn install" of SNAPSHOT objects to local repo). |
Comment by Scott Stewart [ 13/Oct/11 ] |
Want to echo this as well. We have a set of about 35 projects that we're trying to make easier to build. A primary requirement is the ability to build some sub-project without needing the entire X GB project structure. If project A depends on B, depends on C you should only need these 3 project directories to build A, not all 35 projects. My first thought was like Philip's: Why not allow relative file paths to a dependent project's gradle file as an alternative to the virtual path relative to the base multiproject directory? dependencies { compile project('file:../myOtherDev/libA') } or |
Comment by Hendy Irawan [ 19/Mar/13 ] |
+1 for this! Especially coupled with generation of Eclipse project classpath settings. |
Comment by Davide Cavestro [ 19/Mar/13 ] |
We have some additional modules (custom reports) built to be hot deployed into the main application (a web application). A notation like dependencies { compile project('file:../theWarMultiprj/libA') } would be great for these modules, cause it could be easily integrated even in our scenario, where the war is produced merging contents from a gradle multiproject where in turn each project is backed by an eclipse project that somewhat mirrors the gradle dependencies (with some partial overrides just to reflect the war merging logic). |
Comment by Benjamin Muschko [ 15/Nov/16 ] |
As announced on the Gradle blog we are planning to completely migrate issues from JIRA to GitHub. We intend to prioritize issues that are actionable and impactful while working more closely with the community. Many of our JIRA issues are inactionable or irrelevant. We would like to request your help to ensure we can appropriately prioritize JIRA issues you’ve contributed to. Please confirm that you still advocate for your JIRA issue before December 10th, 2016 by:
We look forward to collaborating with you more closely on GitHub. Thank you for your contribution to Gradle! |
Comment by Benjamin Muschko [ 08/Feb/17 ] |
From what I understand from the the problem description we are talking about composite builds. Composite builds are not available in Gradle so I am going mark the issue as fixed. Some other aspects were raised. For those I'd like to ask you to raise a separate issue on GitHub. |