Rewrite the internals of mod configuration remapping to fix bugs (#807)

* Add test for #801

* Add test for #572

* Rewrite mod configuration remapping internals to fix bugs

Fixes #801. Fixes #572.

- Instead of individual mod configs getting remapped, Loom now remaps
  "collector configs": `mod[Compile/Runtime]Classpath[source set name]`
  (eg `modRuntimeClasspathMain` -> `modRuntimeClasspathMainRemapped`)
  - This lets us use Gradle's `org.gradle.usage` attributes to select
    whether it's a compile-time or runtime dependency
  - Note: Remap configurations sourcing from `api` are partially left
    intact due to their special logic in the `namedElements` configuration.
- Setting the proper usages fixes #801.
- No dependency files are added to the real target configurations
  (like `api` and `implementation`) anymore.
  - This fixes #572, since `runtimeClasspath` and `compileClasspath` don't
    leak transitive dependencies unlike `implementation` etc.

* Fix checkstyle

* Fix split env dependency consumers

* Only use collector configs for remapped deps and let the inputs stay intact

This way the code has less duplication.

* Improve log messages

* Update year

* Add some comments

* Fix compilation

* Use LinkedHashMap for reliable iteration order through remapped configs

* Use ImmutableMap.of instead of Map.of for reliable ordering

* ModConfigurationRemapper: Move namedElements handling out of forEach

* Add regression test for a crash where loader is resolved after other mods

* Fix the aforementioned bug

* Rename InstallerDataTest -> DependencyOrderTest

* Add TODO about refresh dependencies

The code currently processes the same deps multiple times when
--refresh-dependencies/-Dloom.refresh=true/a cache invalidation
is applied.

Co-authored-by: modmuss50 <modmuss50@gmail.com>
This commit is contained in:
Juuz
2023-01-22 01:03:42 +02:00
committed by GitHub
parent 7f06b64693
commit 06e9fb16e5
13 changed files with 441 additions and 162 deletions

View File

@@ -1,7 +1,7 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 2022 FabricMC
* Copyright (c) 2022-2023 FabricMC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -28,7 +28,6 @@ import java.util.Set;
import javax.inject.Inject;
import com.google.common.base.Preconditions;
import org.gradle.api.Named;
import org.gradle.api.NamedDomainObjectProvider;
import org.gradle.api.Project;
@@ -41,9 +40,6 @@ import org.gradle.api.tasks.SourceSet;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import net.fabricmc.loom.LoomGradleExtension;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftJarConfiguration;
/**
* A {@link Named} object for configuring "proxy" configurations that remap artifacts.
*/
@@ -132,50 +128,12 @@ public abstract class RemapConfigurationSettings implements Named {
return getName() + "Mapped";
}
@ApiStatus.Internal
@Internal
public final Provider<String> getClientRemappedConfigurationName() {
return getClientSourceConfigurationName().map(s -> s + "Mapped");
}
@ApiStatus.Internal
@Internal
public final NamedDomainObjectProvider<Configuration> getSourceConfiguration() {
return getConfigurationByName(getName());
}
@ApiStatus.Internal
@Internal
public final NamedDomainObjectProvider<Configuration> getRemappedConfiguration() {
return getConfigurationByName(getRemappedConfigurationName());
}
@ApiStatus.Internal
@Internal
public final NamedDomainObjectProvider<Configuration> getTargetConfiguration() {
return getConfigurationByName(getTargetConfigurationName().get());
}
@ApiStatus.Internal
@Internal
public final Provider<Configuration> getClientTargetConfiguration() {
return getProject().provider(() -> {
boolean split = LoomGradleExtension.get(getProject()).getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.SPLIT;
Preconditions.checkArgument(split, "Cannot get client target configuration when project is not split");
return getConfigurationByName(getClientSourceConfigurationName().get()).get();
});
}
@ApiStatus.Internal
@Internal
public final Provider<Configuration> getClientRemappedConfiguration() {
return getProject().provider(() -> {
boolean split = LoomGradleExtension.get(getProject()).getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.SPLIT;
Preconditions.checkArgument(split, "Cannot get client remapped configuration when project is not split");
return getConfigurationByName(getClientRemappedConfigurationName().get()).get();
});
}
@Internal
private NamedDomainObjectProvider<Configuration> getConfigurationByName(String name) {
return getProject().getConfigurations().named(name);