architectury / architectury-loom

A Gradle plugin to setup environments for Fabric, Forge, NeoForge and Quilt modding.
https://docs.architectury.dev/loom/introduction
MIT License
115 stars 41 forks source link

Repository Content is Not Filtered Correctly #221

Closed halotroop2288 closed 4 months ago

halotroop2288 commented 5 months ago

The Problem

Architectury Loom automatically adds maven repositories to the list which may not be appropriate, such as the minecraftforge.net repository, which shouldn't be used by default.

Aside from being sub-optimal for projects that do not need these repositories at all, this also causes issues with broken links. For instance, Gradle wants to download Lombok from minecraftforge.net, and cannot find it there. The build fails there and then, without searching other repositories.

Long Gradle stacktrace snippet ``` org.gradle.internal.resolve.ArtifactResolveException: Could not download lombok-1.18.30.jar (org.projectlombok:lombok:1.18.30) at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveArtifact(ExternalResourceResolver.java:473) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository$ResolveAndCacheRepositoryAccess.resolveArtifact(CachingModuleComponentRepository.java:463) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.lambda$resolveArtifact$12(ErrorHandlingModuleComponentRepository.java:169) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.tryResolveAndMaybeDisable(ErrorHandlingModuleComponentRepository.java:236) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.performOperationWithRetries(ErrorHandlingModuleComponentRepository.java:193) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.resolveArtifact(ErrorHandlingModuleComponentRepository.java:167) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.FilteredModuleComponentRepository$FilteringAccess.resolveArtifact(FilteredModuleComponentRepository.java:117) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainArtifactResolver.resolveArtifactLater(RepositoryChainArtifactResolver.java:76) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainArtifactResolver.lambda$resolveArtifact$0(RepositoryChainArtifactResolver.java:64) at org.gradle.internal.model.CalculatedValueContainerFactory$SupplierBackedCalculator.calculateValue(CalculatedValueContainerFactory.java:74) at org.gradle.internal.model.CalculatedValueContainer$CalculationState.lambda$attachValue$0(CalculatedValueContainer.java:229) at org.gradle.internal.Try.ofFailable(Try.java:41) at org.gradle.internal.model.CalculatedValueContainer$CalculationState.attachValue(CalculatedValueContainer.java:224) at org.gradle.internal.model.CalculatedValueContainer.finalizeIfNotAlready(CalculatedValueContainer.java:197) at org.gradle.internal.model.CalculatedValueContainer.finalizeIfNotAlready(CalculatedValueContainer.java:188) at org.gradle.api.internal.artifacts.ivyservice.resolveengine.artifact.ArtifactBackedResolvedVariant$DownloadArtifactFile.run(ArtifactBackedResolvedVariant.java:189) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationExecutor$QueueWorker.execute(DefaultBuildOperationExecutor.java:161) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runOperation(DefaultBuildOperationQueue.java:272) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.doRunBatch(DefaultBuildOperationQueue.java:253) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.lambda$runBatch$0(DefaultBuildOperationQueue.java:238) at org.gradle.internal.resources.AbstractResourceLockRegistry.whileDisallowingLockChanges(AbstractResourceLockRegistry.java:50) at org.gradle.internal.work.DefaultWorkerLeaseService.whileDisallowingProjectLockChanges(DefaultWorkerLeaseService.java:236) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.lambda$runBatch$1(DefaultBuildOperationQueue.java:238) at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:264) at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:128) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runBatch(DefaultBuildOperationQueue.java:224) at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.run(DefaultBuildOperationQueue.java:192) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: org.gradle.api.resources.ResourceException: Could not get resource 'https://maven.minecraftforge.net/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar'. at org.gradle.internal.resource.ResourceExceptions.failure(ResourceExceptions.java:74) at org.gradle.internal.resource.ResourceExceptions.getFailed(ResourceExceptions.java:57) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadByCoords(DefaultExternalResourceArtifactResolver.java:154) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadStaticResource(DefaultExternalResourceArtifactResolver.java:94) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.resolveArtifact(DefaultExternalResourceArtifactResolver.java:62) at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveArtifact(ExternalResourceResolver.java:466) ... 35 more Caused by: org.gradle.internal.resource.transport.http.HttpRequestException: Could not HEAD 'https://maven.minecraftforge.net/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar'. at org.gradle.internal.resource.transport.http.HttpClientHelper.createHttpRequestException(HttpClientHelper.java:122) at org.gradle.internal.resource.transport.http.HttpClientHelper.performRequest(HttpClientHelper.java:116) at org.gradle.internal.resource.transport.http.HttpClientHelper.performRawHead(HttpClientHelper.java:90) at org.gradle.internal.resource.transport.http.HttpClientHelper.performHead(HttpClientHelper.java:94) at org.gradle.internal.resource.transport.http.HttpResourceAccessor.getMetaData(HttpResourceAccessor.java:64) at org.gradle.internal.resource.transfer.DefaultExternalResourceConnector.getMetaData(DefaultExternalResourceConnector.java:66) at org.gradle.internal.resource.transfer.ProgressLoggingExternalResourceAccessor$MetadataOperation.call(ProgressLoggingExternalResourceAccessor.java:155) at org.gradle.internal.resource.transfer.ProgressLoggingExternalResourceAccessor$MetadataOperation.call(ProgressLoggingExternalResourceAccessor.java:143) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.resource.transfer.ProgressLoggingExternalResourceAccessor.getMetaData(ProgressLoggingExternalResourceAccessor.java:52) at org.gradle.internal.resource.transfer.AccessorBackedExternalResource.getMetaData(AccessorBackedExternalResource.java:156) at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.lambda$getResource$1(DefaultCacheAwareExternalResourceAccessor.java:98) at org.gradle.cache.internal.ProducerGuard$AdaptiveProducerGuard.guardByKey(ProducerGuard.java:97) at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.getResource(DefaultCacheAwareExternalResourceAccessor.java:80) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadByCoords(DefaultExternalResourceArtifactResolver.java:149) ... 38 more ```

Proposal

Simply filtering additional repositories should fix this particular issue. Unfortunately it seems that overriding the repository content is not possible on the user's end after Loom is applied. But ideally, these repositories should be entirely opt-in and added automatically when actually needed. See Unimined's invocation of necessary maven repositories.

Temporary Workaround

This can be worked around by applying Loom after the repositories block, for now.

Here is my working configuration, (using Gradle version catalogs for dependencies):

plugins {
    alias libs.plugins.loom apply false
}

repositories {
    mavenCentral()
    maven {
        name = 'Fabric'
        url = 'https://maven.fabricmc.net'
        content { includeGroupAndSubgroups('net.fabricmc') }
    }
    maven {
        name = 'Parchment'
        url = 'https://maven.parchmentmc.org'
        content { includeGroupAndSubgroups('org.parchmentmc')}
    }
    maven {
        name = 'Minecraft Forge'
        url = 'https://maven.minecraftforge.net'
        content { excludeGroupByRegex('.*') }
    }
}

apply plugin: 'dev.architectury.loom'

loom.silentMojangMappingsLicense()

dependencies {
    minecraft libs.minecraft
    mappings loom.layered {
        officialMojangMappings()
        parchment("org.parchmentmc.data:parchment-${libs.versions.minecraft.get()}:${libs.versions.parchment.get()}@zip")
    }

    annotationProcessor libs.lombok
    implementation libs.fabric.loader
    // ...
}
Juuxel commented 5 months ago

The filtering can be done by adjusting this further: https://github.com/architectury/architectury-loom/blob/8da7cc0f877ff572e7701ad6d63f5d171b328173/src/main/java/net/fabricmc/loom/LoomRepositoryPlugin.java#L97-L101

I think the opt-in logic can also be done in the repository plugin since gradle.properties should be loaded by then (and we can parse the file manually too of course). The Forge repo can just be gated behind a platform check[^1]. (We could also add the NeoForged repo the same way since it currently needs to be added by users).

[^1]: We have to be careful here to check all subproject platforms too for settings.gradle Loom applications to include all necessary platforms.