Repository navigation
[7.0] Multi-project build with variants of same artifact #1058
Description
Activity
This was intentional from the start due to the ability to apply ForgeGradle 7 to
settings.gradleand adding the Minecraft Mavenizer repository todependencyResolutionManagement.repositories. At the time, needing to account for ATs not being artifact transformers wasn't an issue. What a pain in the ass.Yup thats what i figured your process was. Not sure the best way to address it without breaking the ability to set ths repo in settings.
In the worst case, another variant. In the best case, I can get all included projects from Settings, and have
minecraft.mavenizer(it)add repos for all of them.Honestly i would suggest the second point. Hell i may even suggest we turn this into a "magic" where the modder doesnt need to actuallt specify mavenizer in their repos at all. In favor of us doing it automatically for them when they call dependency.
Stupid idea because magic bad. But on the other hand, would solve this.
Just to be clear the intention of the settings variant of the plugin is to allow specifing the repo and mappings in one place? I assume the repo is because of gradle "best practices".
Would it be possible to move the dependency(maven instance) creation to the settings side. And then add a "detected multiple dependency variants with the same exact coordinates but different variants this isnt supported due to long standing gradle issues"
Hell i may even suggest we turn this into a "magic" where the modder doesnt need to actuallt specify mavenizer in their repos at all. In favor of us doing it automatically for them when they call dependency.
The problem with this is Settings's dependency resolution management enforces the usage of repositories in settings, and they cannot be additive to project repositories.
Just to be clear the intention of the settings variant of the plugin is to allow specifing the repo and mappings in one place?
Yes.
Would it be possible to move the dependency(maven instance) creation to the settings side.
No, Settings-side doesn't have access to ProviderFactory and is quite limited since it is still technically pre-warmup for Gradle.
Damn, if they cant be additive. What happens when both settings and project specify a repo?
What happens when multiple settings (root project and subprojects) specify a repo?
Is there a way to walk the stack ofsub/build.gradle->sub/settings.gradle->settings.gradleand use the first found repo as the mavenizer output.Assuming we can get the "this project" directory from settings plugin.
Damn, if they cant be additive. What happens when both settings and project specify a repo?
By default, the repositories mode is
PREFER_PROJECT. If repositories are added to the project, settings repositories are ignored. This is why you might've seen me set it toFAIL_ON_PROJECF_REPOSon some of our own projects (before needing to change it togradle.beforeProjectto account for IntelliJ IDEA bugs).What happens when multiple settings (root project and subprojects) specify a repo?
Each Gradle invocation can only ever have one Settings object, so this is impossible. This is also why composite builds are unaware of each other aside from the fact that they might exist and try to treat it as a maven artifact.
Is there a way to walk the stack of
sub/build.gradle->sub/settings.gradle->settings.gradleand use the first found repo as the mavenizer output.Again, multiple settings is impossible, but unfortunately only one order can really be defined from the
settings.gradlebefore the projects are loaded.This is why I even had the audacity to suggest making another variant to begin with, because it's possible that multiple sub-projects each using ForgeGradle could pose an issue, where all sub-projects just use one of the other project's repository as defined from
settings.gradle.Okay so if there can only be one settings file. Can we get that object from the peoject. And check if the settings has repos defined/the fg plugin applied?
If so share a gloabl folder. If not make it project specific like it ised to be.
The whole issue is trying to find out where the mavenizer repo isndefined and making sure we sync that to the project.
Honestly itd probably be easiest to disallow settings level repos and instead copy them over.
something has to be the thing in charge of the repo. And we need to add a "found multiple variants of the same artifact" error instead of letting the build fail.
To all of that: I'd rather add multiple variant detection instead of allowing any sort of magic.
I propose that instead of making
minecraft.mavenizer(it)insettings.gradleadd the local repository for all projects, we make it add it only for the root project. We can add an extra property (gradle.extensions.extraProperties) fromMinecraftExtensionImpl.ForSettingsto track if this was done. If it was, we instruct Mavenizer to output to that repository. We can also use extra properties to track a list of artifact strings built by Mavenizer. If there's ever a duplicate, fail the build with an error and instruct the user to use project repositories. This prevents the need to add redundant repositories, that may or may not exist, to settings dependency resolution management.That is a lot of words but if you break it down it can be very easily done, and mostly using the extra properties extension on the global Gradle object. I would greatly prefer this over neutering settings repositories and copying them over to project.
I should mention that doing this means we effectively deprecate the usage of
minecraft.getMavenizer(), especially insettings.gradle, but I'd rather do that then try and add extra background magic.That works for me, just need a better error message for this case. As it took me a little bit to figure out what was going on last night.
But we should specifically test this usecase. Because right now it just always picks the root project folder. It needs to be able to use the sub-project's folder if settings.gradle does NOT specify repos. Which is the case for our MDKExamplesSimple test case is literally just
gradlew buildin that project.Sounds good.
Little digging this messes with multi-project builds that use different variants of the same artifact version.
Specifically our MDKExamples repo, One project has a access transformer, and another doesn't.
I am not sure how to best address this, be it just changing the code to
getProjectinstead ofgetRootProjector changing how we aggregate the MDKExamples repos to test.