Skip to content

Commit e571bb5

Browse files
authored
Rework how Minecraft dependencies are handled (#1020)
More to come before RC/release, which I am working on now.
1 parent 9fb8767 commit e571bb5

16 files changed

+395
-239
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ dependencies {
6464
compileOnlyApi libs.accesstransformers.gradle
6565

6666
// Utils
67+
implementation libs.maven.artifact
6768
implementation libs.bundles.utils
6869
}
6970

@@ -92,6 +93,7 @@ tasks.named('shadowJar', ShadowJar) {
9293
archiveClassifier = null
9394
relocationPrefix = 'net.minecraftforge.gradle.shadow'
9495

96+
minimize()
9597
dependencies {
9698
exclude dependency(projects.runtimeEnvironmentCheck)
9799
exclude dependency(libs.annotations.jspecify)

settings.gradle

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ gradle.beforeProject { Project project ->
2424

2525
//@formatter:off
2626
dependencyResolutionManagement.versionCatalogs.register('libs') {
27-
version 'gradleutils', '3.3.39'
27+
version 'gradleutils', '3.3.40'
2828

2929
plugin 'licenser', 'net.minecraftforge.licenser' version '1.2.0' // https://plugins.gradle.org/plugin/net.minecraftforge.licenser
3030
plugin 'gradleutils', 'net.minecraftforge.gradleutils' versionRef 'gradleutils'
@@ -49,6 +49,9 @@ dependencyResolutionManagement.versionCatalogs.register('libs') {
4949
// https://plugins.gradle.org/plugin/net.minecraftforge.accesstransformers
5050
library 'accesstransformers-gradle', 'net.minecraftforge.accesstransformers', 'net.minecraftforge.accesstransformers.gradle.plugin' version '5.0.1'
5151

52+
// Artifact Versioning
53+
library 'maven-artifact', 'org.apache.maven', 'maven-artifact' version '3.9.11'
54+
5255
library 'utils-data', 'net.minecraftforge', 'json-data-utils' version '0.4.1' // https://files.minecraftforge.net/net/minecraftforge/json-data-utils/index.html
5356
library 'utils-os', 'net.minecraftforge', 'os-utils' version '0.1.0' // https://files.minecraftforge.net/net/minecraftforge/os-utils/index.html
5457
library 'utils-hash', 'net.minecraftforge', 'hash-utils' version '0.1.12' // https://files.minecraftforge.net/net/minecraftforge/hash-utils/index.html

src/main/java/net/minecraftforge/gradle/MinecraftDependency.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@
44
*/
55
package net.minecraftforge.gradle;
66

7+
import groovy.lang.Closure;
8+
import groovy.lang.DelegatesTo;
9+
import groovy.transform.stc.ClosureParams;
10+
import groovy.transform.stc.FromString;
11+
import net.minecraftforge.gradleutils.shared.Closures;
12+
import org.gradle.api.Action;
13+
import org.gradle.api.NamedDomainObjectContainer;
14+
715
/// The Minecraft dependency contains information essential for how the
816
/// {@linkplain MinecraftExtensionForProject minecraft extension} processes Minecraft dependencies.
9-
public interface MinecraftDependency extends MinecraftMappingsContainer { }
17+
public interface MinecraftDependency extends MinecraftMappingsContainer {
18+
/// The collection of Slime Launcher options with which to create the launcher tasks.
19+
///
20+
/// @return The collection of run task options
21+
NamedDomainObjectContainer<? extends SlimeLauncherOptions> getRuns();
22+
23+
/// Configures the Slime Launcher options for this project, which will be used to create the launcher tasks.
24+
///
25+
/// @param closure The configuring closure
26+
default void runs(
27+
@DelegatesTo(NamedDomainObjectContainer.class)
28+
@ClosureParams(value = FromString.class, options = "org.gradle.api.NamedDomainObjectContainer<net.minecraftforge.gradle.SlimeLauncherOptions>")
29+
Closure<?> closure
30+
) {
31+
this.getRuns().configure(closure);
32+
}
33+
34+
/// Configures the Slime Launcher options for this project, which will be used to create the launcher tasks.
35+
///
36+
/// @param action The configuring action
37+
default void runs(Action<? super NamedDomainObjectContainer<? extends SlimeLauncherOptions>> action) {
38+
this.runs(Closures.action(this, action));
39+
}
40+
}

src/main/java/net/minecraftforge/gradle/MinecraftExtensionForProject.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ public interface MinecraftExtensionForProject<T extends ClosureOwner> extends Mi
2727
/// Configures the Slime Launcher options for this project, which will be used to create the launcher tasks.
2828
///
2929
/// @param closure The configuring closure
30-
void runs(
30+
default void runs(
3131
@DelegatesTo(NamedDomainObjectContainer.class)
3232
@ClosureParams(value = FromString.class, options = "org.gradle.api.NamedDomainObjectContainer<net.minecraftforge.gradle.SlimeLauncherOptions>")
3333
Closure<?> closure
34-
);
34+
) {
35+
this.getRuns().configure(closure);
36+
}
3537

3638
/// Configures the Slime Launcher options for this project, which will be used to create the launcher tasks.
3739
///

src/main/java/net/minecraftforge/gradle/internal/ClosureOwnerInternal.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
import groovy.transform.NamedParams;
1111
import net.minecraftforge.gradle.ClosureOwner;
1212
import net.minecraftforge.gradle.MinecraftMappings;
13+
import net.minecraftforge.gradle.SlimeLauncherOptions;
1314
import org.gradle.api.Action;
15+
import org.gradle.api.NamedDomainObjectContainer;
1416
import org.gradle.api.artifacts.DependencyArtifact;
1517
import org.gradle.api.artifacts.ExcludeRule;
1618
import org.gradle.api.artifacts.ExternalModuleDependency;
@@ -82,6 +84,11 @@ default void mappings(
8284
this.getOwnerDelegate().mappings(namedArgs);
8385
}
8486

87+
@Override
88+
default NamedDomainObjectContainer<? extends SlimeLauncherOptions> getRuns() {
89+
return this.getOwnerDelegate().getRuns();
90+
}
91+
8592
@Override
8693
default boolean isChanging() {
8794
throw stub();
@@ -288,6 +295,11 @@ default void mappings(
288295
this.getOwnerDelegate().mappings(namedArgs);
289296
}
290297

298+
@Override
299+
default NamedDomainObjectContainer<? extends SlimeLauncherOptions> getRuns() {
300+
return this.getOwnerDelegate().getRuns();
301+
}
302+
291303
@Override
292304
default boolean isChanging() {
293305
throw stub();

src/main/java/net/minecraftforge/gradle/internal/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ final class Constants {
2020
static final String SLIMELAUNCHER_MAIN = "net.minecraftforge.launcher.Main";
2121

2222
static final String MAVENIZER_NAME = "mavenizer";
23-
static final String MAVENIZER_VERSION = "0.4.14";
23+
static final String MAVENIZER_VERSION = "0.4.15";
2424
static final String MAVENIZER_DL_URL = "https://maven.minecraftforge.net/net/minecraftforge/minecraft-mavenizer/" + MAVENIZER_VERSION + "/minecraft-mavenizer-" + MAVENIZER_VERSION + ".jar";
2525
static final int MAVENIZER_JAVA_VERSION = 25;
2626
static final String MAVENIZER_MAIN = "net.minecraftforge.mcmaven.cli.Main";
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package net.minecraftforge.gradle.internal;
2+
3+
import net.minecraftforge.util.os.OS;
4+
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
5+
import org.gradle.api.Action;
6+
import org.gradle.api.attributes.Attribute;
7+
import org.gradle.api.attributes.AttributeDisambiguationRule;
8+
import org.gradle.api.attributes.MultipleCandidatesDetails;
9+
import org.gradle.api.provider.SetProperty;
10+
import org.gradle.api.provider.ValueSource;
11+
import org.gradle.api.provider.ValueSourceParameters;
12+
import org.gradle.api.provider.ValueSourceSpec;
13+
import org.jspecify.annotations.NullUnmarked;
14+
import org.jspecify.annotations.Nullable;
15+
16+
import javax.inject.Inject;
17+
import java.util.Comparator;
18+
import java.util.EnumSet;
19+
import java.util.Set;
20+
21+
final class ForgeAttributes {
22+
static final class OperatingSystem {
23+
static final Attribute<String> ATTRIBUTE = Attribute.of("net.minecraftforge.native.operatingSystem", String.class);
24+
25+
static abstract class DisambiguationRule implements AttributeDisambiguationRule<String> {
26+
private final OS current;
27+
28+
@Inject
29+
public DisambiguationRule(OS current) {
30+
this.current = current;
31+
}
32+
33+
@Override
34+
public void execute(MultipleCandidatesDetails<String> details) {
35+
var options = details.getCandidateValues().stream().map(OS::byKey).toList();
36+
37+
if (options.contains(current)) {
38+
details.closestMatch(current.key());
39+
return;
40+
}
41+
42+
for (var os : options) {
43+
var fallback = execute(current, os);
44+
if (fallback != null) {
45+
details.closestMatch(fallback);
46+
return;
47+
}
48+
}
49+
}
50+
51+
@NullUnmarked
52+
private String execute(OS current, OS os) {
53+
return current == os
54+
? os.key()
55+
: os != null ? execute(current, os.fallback()) : null;
56+
}
57+
}
58+
59+
abstract static class CurrentValue implements ValueSource<OS, CurrentValue.Parameters> {
60+
interface Parameters extends ValueSourceParameters {
61+
Action<? super ValueSourceSpec<Parameters>> DEFAULT = spec -> spec.getParameters().getAllowedOperatingSystems().set(Set.of(OS.WINDOWS, OS.MACOS, OS.LINUX));
62+
63+
SetProperty<OS> getAllowedOperatingSystems();
64+
}
65+
66+
@Inject
67+
public CurrentValue() { }
68+
69+
@Override
70+
public @Nullable OS obtain() {
71+
var allowed = getParameters().getAllowedOperatingSystems().getOrElse(EnumSet.noneOf(OS.class)).toArray(new OS[0]);
72+
return allowed.length > 0
73+
? OS.current(allowed)
74+
: OS.current();
75+
}
76+
}
77+
}
78+
79+
static final class MappingsChannel {
80+
static final Attribute<String> ATTRIBUTE = Attribute.of("net.minecraftforge.mappings.channel", String.class);
81+
82+
static abstract class DisambiguationRule implements AttributeDisambiguationRule<String> {
83+
@Inject
84+
public DisambiguationRule() { }
85+
86+
@Override
87+
public void execute(MultipleCandidatesDetails<String> details) {
88+
var options = details.getCandidateValues();
89+
if (options.contains("official")) {
90+
details.closestMatch("official");
91+
} else if (options.contains("parchment")) {
92+
details.closestMatch("parchment");
93+
}
94+
}
95+
}
96+
}
97+
98+
static final class MappingsVersion {
99+
static final Attribute<String> ATTRIBUTE = Attribute.of("net.minecraftforge.mappings.version", String.class);
100+
101+
static final Comparator<String> COMPARATOR = Comparator.comparing(DefaultArtifactVersion::new);
102+
}
103+
}

src/main/java/net/minecraftforge/gradle/internal/ForgeGradleProblems.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,17 @@ void mavenizerOutOfDate(boolean throwIt, Object dependency) {
150150
this.report(name, displayName, problemSpec);
151151
}
152152

153+
void reportCannotAccessSettingsRepos(Exception e) {
154+
this.report("cannot-access-settings-repos", "Cannot access Settings repositories", spec -> spec
155+
.details("""
156+
ForgeGradle is unable to access the repositories defined by the Settings' dependency resolution management.
157+
This is a ForgeGradle bug and needs to be reported to the ForgeGradle issue tracker on GitHub.""")
158+
.severity(Severity.ERROR)
159+
.withException(e)
160+
.solution("For now, only declare repositories in the project.")
161+
.solution(HELP_MESSAGE));
162+
}
163+
153164
void reportMcMavenNotDeclared() {
154165
if (!this.test("net.minecraftforge.gradle.warnings.repository.missing.mavenizer")) return;
155166

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package net.minecraftforge.gradle.internal;
2+
3+
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
4+
import org.jspecify.annotations.Nullable;
5+
6+
import java.util.List;
7+
8+
record ForgeGradleSharedData(
9+
@Nullable MinecraftMappingsImpl mappings
10+
) {
11+
static final String NAME = "__fg_shared_data";
12+
}

0 commit comments

Comments
 (0)