I don't know if I totally got the concept wrong, but I want to create several projects with dependencies to other projects which are not part of the directory structure of a parent project. I know that the normal way of doing this would be to use an external dependency which fetches from some external repository. But in this case, where let's say in project called 'F' a framework is developed, which is used in project 'P'., then P uses F, but F should IMO not necessarily be a sub-project of P as P is only used to test-drive the development of F (but it's not only a unit test). Later in the process, when F is stable, F is separated and can be consumed by other projects via a repository. But during development of F with P as it's test case, it would be nice if that round-trip through the repository could be omitted.
To make matters worse, for the initial development there is more than one test-driving consumer project, which all need to have a dependency to F, but not via an external repository.
My idea is to develop F in some place on the disk with it's own git reposity. The other P like projects reside somewhere else on the disk and have a local file system based dependency to F. Would such a construct be possible in Gradle? If so, where do I start? I scanned the Java examples but couldn't find an appropriate example.
Any ideas?
The Gradle project hierarchy is fully virtual. It just has the default that the physical location corresponds to the virtual hierarchy. But you have complete control over this. See: http://gradle.org/0.9-rc-1/docs/userguide/build_lifecycle.html#sec:settings_file
Regarding your other ideas have a look at the following Jira: http://jira.codehaus.org/browse/GRADLE-1014
You could consider a folder hierarchy like this one:
Main folder
|- F folder
| |- .git
| |- sources
| |- build.gradle (with parts specific to F)
|- P folder
| |- sources
| |- build.gradle (with part specific to P)
|- build.gradle (with common parts)
|- settings.gradle
So you can always decide to run gradle on either the F project, the P project or the two alltoegether. It will also allows you to promote you F project alone without the P or any other side projects.
For more up-to-date information, check the Multi Project Builds chapter of the Gradle documentation.
Related
I have two projects A,B with their own build chains defined in their local .teamcity folders. In addition, A contains a dependency on B which I want to test. How do I set up a build chain that incorporates both of these individual builds such that, when B changes I test integration with A's master branch? I imagine I would first set up a second VCS root in B directed at the master branch of A such that the project structure on the agent looks as follows:
root
|-- A
| `-- .teamcity
| |-- settings.kts
| `-- /kotlin_code
`-- B
`-- .teamcity
|-- settings.kts
`-- /kotlin_code
But I have no idea how to automatically combine project settings from A into the B build chain. I perhaps could jerry-rig some checkout rule +:A/.teamcity/kotlin_code => B/.teamcity/kotlin_code_A and pick this up in B but this seems rather inelegant. I could also place all teamcity configuration in a separate repo, but then I lose revision control between A's codebase and its teamcity configuration. Is there a better solution? Many thanks!
https://teamcity-support.jetbrains.com/hc/en-us/community/posts/360004237439-Re-use-build-configuration-in-multiple-build-chains
The answer here recommends creating a template under root that encapsulates most of the functionality of B and from this generating separate build chains in A,B. I am not sure this is the most elegant solution, however, so I will leave the question open.
The best answer I have found is to define a finish build trigger that starts when the previous build completes and send a reverse dependency back through the build chain to allowing builds to be customized.
I want to use a project in my project as a git submodule, ideally without changing the upstream project (or if it makes sense, changing it in a way that will get merged there).
The problem is that the project consists of modules, 2 of which I want to directly use, with the one also depending on the other.
myProject
├ submodule
| ├ first
| | ├ build.gradle: implementation project(":second") <---- this fails if I don't change it to :submodule:second
| ├ second
| ├ settings.gradle: include ':first', ':second'
├ app
| ├ build.gradle: implementation project(":submodule:first"), implementation project(":submodule:second")
| ├ settings.gradle: include ':submodule:first', ':submodule:second', ':app'
As my project's settings.gradle replaces the submodule's settings.gradle, the submodule's absolute paths suddenly change. Can I somehow `include ':submodule:second as :second'?
I know I can use implementation project(somePrefix + ":second") and define this somePrefix accordingly but that would involve touching the submodule.
Gradle project paths (e.g. ':submodule:second')
actually represent project hierarchies. This means that using include ':submodule:second' in your settings.gradle will implicitly create a project called submodule, even if not relevant for the build at all.
do not need to match the directory structure (this is just a convention). You may set the project directory independent from the project path (and the project name).
Check out the following example from the documentation:
// include two projects, 'foo' and 'foo:bar'
// directories are inferred by replacing ':' with '/'
include 'foo:bar'
// include one project whose project dir does not match the logical project path
include 'baz'
project(':baz').projectDir = file('foo/baz')
However, I would recommend to not use include at all. Instead use includeBuild and setup a composite build. Composite builds differ from classical multi-project builds in their coupling. Since your Git submodule indicates a build that may be used as a standalone project (with its own settings.gradle), the strong coupling of a multi-project builds seems inappropriate. Multiple settings.gradle files may also cause problems in a multi-project build, but are fine for composite builds.
I am trying to migrate an existing Go project to use modules but having difficulties working out the correct directory structure. The repo contains two regular packages (p1, p2) along with example programs to demonstrate how to use the packages. I am using Go 1.13.
The current layout is
<reponame>
|
+--- p1
| |
| +-- p1a.go
| +-- p1b.go
|
+--- p2
| |
| +-- p2a.go
| +-- p2b.go
|
+-- examples
|
+-- e1.go (which refers to packages p1 and p2)
The github repository is already public with a version tag > 1. I know I need a new major number, v5, so it looks like I need to move to having v5 somewhere in the path to the packages.
But should it be <repo>/v5/p1 or <repo>/p1/v5? Where do go.mod files go? I suspect I need one to cover the two packages, and one for the example programs.
All the examples I can find for version > 1 seem to only have a single package in the module.
And importantly, how do I get the examples to compile and run? I've tried all kinds of permutations of a go.mod file for the examples but they all keep failing with an error like "no matching versions for query 'v5'" even with the "replace" directive to try to point at the local directories.
It looks like it is expecting a v5 version of code to be already published to github before I've done local testing.
Modules are about versioning. If p1, p2 and example are versioned together then put the go.mod at the repo level. This is probably the what you want.
Make sure the module declares itself properly, i.e. module <repo>/v5 in the go.mod file.
You do not need the v5 in the file system path. There are basically three ways: A v5 folder containing the v5 stuff, a v5 branch containing the v5 stuff or none of the two in which case your repo will be v5 only.
Make sure the import paths are correct. E.g. in package examples you must import p1 via import "<repo>/v5/p1". (Same for p2 or even p1 importing p2, etc.)
Thats all.
cd into the example folder and go build: Go will look up the filesystem tree for a go.mod and will find it at the repo root. It thus knows that this package belongs to module <repo>/v5 and thus where to find all packages from the module <repo>/v5 and can import <repo>/v5/p1 without the need for any replace directive. Like this you can work locally on the v5 without need to push to a remote repo.
(A common mistake is to not declare the module as v5: In the go.mod file you must have a line module github.com/<user>/<repo>/v5. If you falsely just write module github.com/<user>/<repo> then when compiling e.g. examples the compiler thinks "well, the examples package belongs to module github.com/<user>/<repo> and I should import github.com/<user>/<repo>/v5/p1 so let's peek at github.com// to see what we find there..." and wont find anything and complain.)
I have a maven multi module project like so
modA
modB
modC
modD
custom-pom.xml
And here the pom
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xx.xx.correspondence</groupId>
<artifactId>xxHudsonTP</artifactId>
<version>1</version>
<packaging>pom</packaging>
<modules>
<module>modA</module>
<module>modB</module>
</modules>
</project>
Now, when I invoke release:branch with the intent of creating a branch on custom-pom.xml like so
mvn release:branch -DbranchName=new-branch -f custom-pom.xml
It ends up creating a branch with all 4 modules.
Is there any way using release plugin to make sure only selected modules are branched without resorting to branching each module separately.?
Any other maven plugins..?
Edited
The background of this questions stems from the fact that the svn repo that I am working with has about 20 different modules with 4 different artifacts that they need to generate. I could have easily gone with grouping the modules into sub folders, but since a few modules are common between
the artifacts, I didn't think too much into splitting them up.
I understand that branching all modules is trivial and probably simple to manage, but the other developers in the team have this feeling of dealing with too much for accomplishing simple tasks like a one line bug fix. Hope that helps.
As far as I know, there is no solution to answer what you asked.
You have to keep in mind that multimodule projects (aggregation) means that every submodule share the same application lifecycle. This is really what modules and aggregation are intended to.
I see 2 differents workarounds.
You have 2 real differents lifecycles
There is indeed 2 groups in your 4 submodules, lets say group1 : A and B, group 2, C and D.
Split them into 2 new projects :
Group1
|-- Project A
| `-- pom.xml
|-- Project B
| `-- pom.xml
`-- pom.xml
Group2
|-- Project C
| `-- pom.xml
|-- Project D
| `-- pom.xml
`-- pom.xml
Pro : You may be able to branch group 1 and 2 separately.
Cons : You won't be able anymore to perform simultaneaous action (in one command) on every project (like realeasing or builind them)
You really have 1 single lifecycle
This is probably the case. You may want to branch only 1 or 2 submodules because of your very good understanding of the underlying architecture of the project. An so, you don't want to deal with too many conf / artifacts / time building ... Indeed, all those reasons may have indirects impacts that you won't see. Always build the whole project !
If this is for space saving (however most of SCM allow you to branch with few space, like Yorkw said), because your SCM allow you to get only submodules (and maybe both, like for Clearcase) ... sorry, there is no solution. This is the maven way, and I think this is the good one. (ok it's a little bit demagogic, but I really believe what I said)
Don't hesitate to explain us why you really want to branch only a subset of your modules. If there is another reason, you may have more accurate(s) solution(s).
I have a monolith Gradle project that contains multiple subprojects, each with its own subprojects, like so:
project
|
|-- subprojectA
| |-- models
|
|-- subprojectB
| |-- models
This compiles fine but the issue is when I try to add a dependency on :subprojectB:models to :subprojectA:models, Gradle thinks :subprojectA:models is trying to add a dependency on itself and complains of a circular dependency, even though I specify the fully qualified path like so (in subprojectA's build.gradle):
compile project(':subprojectB:models')
How can I avoid this? Can subprojects not have the same name even if their paths are unique?
Project identity for dependency resolution is based on the group:name:version or GAV coordinates, as explained in the linked Gradle issue.
So you need to make sure your different models project have different GAVs.
One way to make this happen is to make the subprojectA (or B) part of the group.
Another way is to assign names that are not based on the containing folder.
That's currently a known Gradle issue as Gradle by default uses the parent directory name as the project name. You can work around the issue as described here by assigning unique subproject names in the root project's settings.gradle like so:
include ':subprojectA:models', ':subprojectB:models'
project(':subprojectA:models-a').projectDir = file('subprojectA/models')
project(':subprojectB:models-b').projectDir = file('subprojectA/models')