Skip to content

[7.0] Multi-project build with variants of same artifact #1058

Description

@LexManos

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 getProject instead of getRootProject or changing how we aggregate the MDKExamples repos to test.

Activity

  1. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    This was intentional from the start due to the ability to apply ForgeGradle 7 to settings.gradle and adding the Minecraft Mavenizer repository to dependencyResolutionManagement.repositories. At the time, needing to account for ATs not being artifact transformers wasn't an issue. What a pain in the ass.

  2. LexManos commented on Mar 3, 2026

    @LexManos
    MemberAuthor

    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.

  3. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    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.

  4. LexManos commented on Mar 3, 2026

    @LexManos
    MemberAuthor

    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"

  5. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    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.

  6. LexManos commented on Mar 3, 2026

    @LexManos
    MemberAuthor

    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 of sub/build.gradle -> sub/settings.gradle -> settings.gradle and use the first found repo as the mavenizer output.

    Assuming we can get the "this project" directory from settings plugin.

  7. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    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 to FAIL_ON_PROJECF_REPOS on some of our own projects (before needing to change it to gradle.beforeProject to 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.gradle and 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.gradle before 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.

  8. LexManos commented on Mar 3, 2026

    @LexManos
    MemberAuthor

    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.

  9. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    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) in settings.gradle add 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) from MinecraftExtensionImpl.ForSettings to 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.

  10. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    I should mention that doing this means we effectively deprecate the usage of minecraft.getMavenizer(), especially in settings.gradle, but I'd rather do that then try and add extra background magic.

  11. LexManos commented on Mar 3, 2026

    @LexManos
    MemberAuthor

    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 MDKExamples

    Simple test case is literally just gradlew build in that project.

  12. Jonathing commented on Mar 3, 2026

    @Jonathing
    Member

    Sounds good.

  13. added theissue type on Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions