Skip to content

Commit 4179a94

Browse files
LexManosJonathing
andauthored
[7.0] Add support for run tokens (#1051)
- Add support for legacy `{source_roots}` token. - Bump Mavenizer to 0.4.35, which exposes needed info for token replacements. - Port eclipse run config fixes from ForgeDev. - Add missing Javadocs. --------- Co-authored-by: Jonathing <me@jonathing.me>
1 parent 4739ecd commit 4179a94

24 files changed

+1086
-293
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ public interface MavenizerInstance extends ProviderConvertible<ExternalModuleDep
2222
/// @return The dependency generated by this instance
2323
@Override Provider<ExternalModuleDependency> asProvider();
2424

25+
/// Gets the mappings channel used by the Mavenizer instance.
26+
///
27+
/// @return The mappings channel used, after all sanitization has been done, should match exactly to the generated maven artifact
28+
/// @see MinecraftMappings#getChannel()
29+
Provider<String> getMappingChannel();
30+
2531
/// Gets the mappings version used by the Mavenizer instance.
2632
///
27-
/// @return The mappings version used
33+
/// @return The mappings version used, after all sanitization has been done, should match exactly to the generated maven artifact
2834
/// @see MinecraftMappings#getVersion()
2935
Provider<String> getMappingVersion();
3036

@@ -53,4 +59,16 @@ public interface MavenizerInstance extends ProviderConvertible<ExternalModuleDep
5359
/// [org.gradle.api.artifacts.dsl.DependencyFactory#create(CharSequence)] or
5460
/// [org.gradle.api.artifacts.dsl.DependencyHandler#addProvider(String, Provider)].
5561
Provider<File> getToObfFile();
62+
63+
/// Gets the Minecraft Version used by the Mavenizer instance.
64+
/// Only returns a value when Mavenizer is above 0.4.33
65+
///
66+
/// @return The Minecraft Version
67+
Provider<String> getMinecraftVersion();
68+
69+
/// Gets the MCP Config version used by the Mavenizer instance.
70+
/// Only returns a value when Mavenizer is above 0.4.33, and we're targeting
71+
/// an artifact that uses MCP Config. So Forge for Minecraft 1.13+
72+
/// @return The MCP Version
73+
Provider<String> getMCPVersion();
5674
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,21 @@ public interface SlimeLauncherOptions extends SlimeLauncherOptionsNested, Named
2020
@Override
2121
@Input String getName();
2222

23+
/// Configures source set-specific attributes for this run.
24+
///
25+
/// Use this, for example, if you need to configure test-specific arguments, properties, or environment variables.
26+
///
27+
/// @param sourceSet The source set to configure this run for
28+
/// @param action The configuring action
2329
default void with(SourceSet sourceSet, Action<? super SlimeLauncherOptionsNested> action) {
2430
this.with(sourceSet.getName(), action);
2531
}
2632

33+
/// Configures source set-specific attributes for this run.
34+
///
35+
/// @param sourceSetName The source set's name to configure this run for
36+
/// @param action The configuring action
37+
/// @see #with(SourceSet, Action)
2738
void with(String sourceSetName, Action<? super SlimeLauncherOptionsNested> action);
2839

2940
/// The classpath to use.

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

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,26 @@
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.Named;
14+
import org.gradle.api.NamedDomainObjectContainer;
715
import org.gradle.api.file.DirectoryProperty;
816
import org.gradle.api.provider.ListProperty;
917
import org.gradle.api.provider.MapProperty;
1018
import org.gradle.api.provider.Property;
1119
import org.gradle.api.provider.Provider;
1220
import org.gradle.api.tasks.Input;
1321
import org.gradle.api.tasks.Internal;
22+
import org.gradle.api.tasks.Nested;
1423
import org.gradle.api.tasks.Optional;
24+
import org.gradle.api.tasks.SourceSet;
1525

26+
import java.util.List;
1627
import java.util.Map;
1728

1829
public interface SlimeLauncherOptionsNested {
@@ -24,7 +35,7 @@ public interface SlimeLauncherOptionsNested {
2435
/// @return A property for the main class
2536
@Input @Optional Property<String> getMainClass();
2637

27-
/// Wither or not to inherit arguments from the UserDev provided run configs.
38+
/// Whether or not to inherit arguments from the UserDev provided run configs.
2839
///
2940
/// If you set this to false you must specify all arguments to start the process manually.
3041
///
@@ -39,7 +50,7 @@ public interface SlimeLauncherOptionsNested {
3950
/// @return A property for the arguments to pass to the main class
4051
@Input @Optional ListProperty<String> getArgs();
4152

42-
/// Wither or not to inherit JVM arguments from the UserDev provided run configs.
53+
/// Whether or not to inherit JVM arguments from the UserDev provided run configs.
4354
///
4455
/// If you set this to false you must specify all JVM arguments to start the process manually.
4556
///
@@ -203,4 +214,57 @@ public interface SlimeLauncherOptionsNested {
203214
/// add a single variable, use [#environment(String,Object)].
204215
/// @see #getEnvironment()
205216
void environment(Provider<? extends Map<String, ?>> properties);
217+
218+
/// The legacy mod configurations to use.
219+
///
220+
/// This is used to define the mod's source paths for legacy versions when they cannot be interpreted automatically.
221+
/// Use this if you use non-standard source paths for your mod or source set.
222+
///
223+
/// @return The legacy mod configurations.
224+
@Nested NamedDomainObjectContainer<? extends ModConfig> getMods();
225+
226+
/// Configures the legacy mod configurations to use.
227+
///
228+
/// @param closure The configuring closure
229+
/// @see #getMods()
230+
default void mods(
231+
@DelegatesTo(NamedDomainObjectContainer.class)
232+
@ClosureParams(value = FromString.class, options = "org.gradle.api.NamedDomainObjectContainer<net.minecraftforge.gradle.SlimeLauncherOptionsNested$ModConfig>")
233+
Closure<?> closure
234+
) {
235+
this.getMods().configure(closure);
236+
}
237+
238+
/// Configures the legacy mod configurations to use.
239+
///
240+
/// @param action The configuring action
241+
/// @see #getMods()
242+
default void mods(Action<? super NamedDomainObjectContainer<? extends ModConfig>> action) {
243+
this.mods(Closures.action(this, action));
244+
}
245+
246+
/// Represents a legacy mod configuration for older versions of Forge.
247+
///
248+
/// @see #getMods()
249+
interface ModConfig extends Named {
250+
/// Sets the source sets to use for this configuration.
251+
///
252+
/// @param sources The source sets to use
253+
void setSources(List<SourceSet> sources);
254+
255+
/// Adds to the source sets to use for this configuration.
256+
///
257+
/// @param sources The source sets to use
258+
void sources(List<SourceSet> sources);
259+
260+
/// Adds to the source sets to use for this configuration.
261+
///
262+
/// @param sources The source sets to use
263+
void sources(SourceSet... sources);
264+
265+
/// Adds to the source sets to use for this configuration.
266+
///
267+
/// @param source The source set to use
268+
void source(SourceSet source);
269+
}
206270
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import groovy.transform.NamedParam;
1010
import groovy.transform.NamedParams;
1111
import net.minecraftforge.gradle.ClosureOwner;
12-
import net.minecraftforge.gradle.MinecraftDependency;
1312
import net.minecraftforge.gradle.MinecraftMappings;
1413
import net.minecraftforge.gradle.SlimeLauncherOptions;
1514
import org.gradle.api.Action;
@@ -27,7 +26,6 @@
2726
import org.gradle.api.attributes.AttributeContainer;
2827
import org.gradle.api.capabilities.Capability;
2928
import org.gradle.api.file.ConfigurableFileCollection;
30-
import org.gradle.api.file.RegularFileProperty;
3129
import org.gradle.api.reflect.HasPublicType;
3230
import org.gradle.api.reflect.TypeOf;
3331
import org.jspecify.annotations.Nullable;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package net.minecraftforge.gradle.internal;
66

77
import net.minecraftforge.util.os.OS;
8-
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
98
import org.gradle.api.Action;
109
import org.gradle.api.attributes.Attribute;
1110
import org.gradle.api.attributes.AttributeDisambiguationRule;

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,4 @@ protected void run(Parameters parameters) {
119119
parameters.problems().reportAccessTransformersNotApplied(e);
120120
}
121121
}
122-
123-
static abstract class MavenizerSyncCheck extends ForgeGradleFlowAction<MavenizerSyncCheck.Parameters> {
124-
static abstract class Parameters extends ForgeGradleFlowAction.Parameters {
125-
final DirectoryProperty dependencyOutput = this.getObjects().directoryProperty();
126-
final Property<String> dependency = this.getObjects().property(String.class);
127-
128-
@Inject
129-
public Parameters() { }
130-
}
131-
132-
@Inject
133-
public MavenizerSyncCheck() { }
134-
135-
@Override
136-
protected void run(Parameters parameters) {
137-
if (parameters.dependencyOutput.getAsFile().get().exists()) return;
138-
139-
parameters.problems().mavenizerOutOfDate(parameters.getFailure().isPresent(), parameters.dependency.get());
140-
}
141-
}
142122
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import org.gradle.api.logging.Logger;
1212
import org.gradle.api.logging.Logging;
1313
import org.gradle.api.plugins.ExtensionAware;
14-
import org.gradle.util.GradleVersion;
1514
import org.jspecify.annotations.Nullable;
1615

1716
import javax.inject.Inject;

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66

77
import net.minecraftforge.gradle.MinecraftMappings;
88
import net.minecraftforge.gradleutils.shared.EnhancedProblems;
9-
import org.gradle.api.Action;
109
import org.gradle.api.artifacts.Dependency;
1110
import org.gradle.api.artifacts.ExternalModuleDependency;
12-
import org.gradle.api.problems.ProblemSpec;
1311
import org.gradle.api.problems.Problems;
1412
import org.gradle.api.problems.Severity;
1513
import org.gradle.api.provider.ProviderFactory;
@@ -129,27 +127,6 @@ RuntimeException changingMinecraftDependency(Dependency dependency) {
129127
//endregion
130128

131129
//region Minecraft Maven
132-
void mavenizerOutOfDate(boolean throwIt, Object dependency) {
133-
String name = "mavenizer-out-of-date";
134-
String displayName = "Minecraft Mavenizer is out-of-date";
135-
Action<? super ProblemSpec> problemSpec = spec -> spec
136-
.details("""
137-
Gradle cannot compile your sources or run the game because the Minecraft Mavenizer is out-of-date.
138-
The Mavenizer must be re-run in order for the changes made to the Minecraft dependency to take effect.
139-
Affected dependency: '%s'"""
140-
.formatted(dependency))
141-
.severity(Severity.ERROR)
142-
.solution("Re-import your project in your IDE, as this will automatically synchronize the Mavenizer.")
143-
.solution("Run `gradlew` with no arguments, as this will automatically synchronize the Mavenizer.")
144-
.solution("Temporary revert any edits to the Minecraft dependency until the Mavenizer is re-run.")
145-
.solution(HELP_MESSAGE);
146-
147-
if (throwIt)
148-
throw this.throwing(new IllegalStateException(displayName), name, displayName, problemSpec);
149-
else
150-
this.report(name, displayName, problemSpec);
151-
}
152-
153130
void reportMavenizerNotHighestRepository() {
154131
this.report("mavenizer-not-highest-repo", "Mavenizer repository is not the highest", spec -> spec
155132
.details("""
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) Forge Development LLC and contributors
3+
* SPDX-License-Identifier: LGPL-2.1-only
4+
*/
5+
package net.minecraftforge.gradle.internal;
6+
7+
import org.jspecify.annotations.Nullable;
8+
9+
import java.util.function.Supplier;
10+
11+
class Lazy<T> implements Supplier<T> {
12+
private final Supplier<T> supplier;
13+
private boolean computed = false;
14+
private @Nullable T value = null;
15+
16+
public Lazy(final Supplier<T> supplier) {
17+
this.supplier = supplier;
18+
}
19+
20+
@Override
21+
public final @Nullable T get() {
22+
if (this.computed)
23+
return this.value;
24+
25+
synchronized (this) {
26+
if (this.computed)
27+
return this.value;
28+
this.computed = true;
29+
return this.value = supplier.get();
30+
}
31+
}
32+
}

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66

77
import groovy.json.JsonSlurper;
88
import net.minecraftforge.gradle.MavenizerInstance;
9-
import org.gradle.api.Transformer;
109
import org.gradle.api.artifacts.ExternalModuleDependency;
10+
import org.gradle.api.logging.Logger;
11+
import org.gradle.api.logging.Logging;
1112
import org.gradle.api.provider.MapProperty;
1213
import org.gradle.api.provider.Provider;
1314
import org.jspecify.annotations.Nullable;
1415

1516
import java.io.File;
17+
import java.util.List;
1618
import java.util.Map;
1719

1820
class MavenizerInstanceImpl implements MavenizerInstance {
21+
private static final Logger LOGGER = Logging.getLogger(MavenizerInstanceImpl.class);
1922
private final MinecraftExtensionImpl.ForProjectImpl extension;
2023
private final Provider<Boolean> valueSource;
2124
private final ExternalModuleDependency dependency;
@@ -55,11 +58,29 @@ private Provider<String> get(String key) {
5558
}));
5659
}
5760

61+
private Provider<String> get(String key, @Nullable String _default, String requiredVersion) {
62+
return this.invoke.getting(key)
63+
.orElse(this.extension.getProviders().provider(() -> {
64+
// This should only happen when someone hardcodes their tool version, warn them
65+
var message = "Mavenizer did not output expected json data " + key +", Make sure you're using Mavenizer >= " + requiredVersion;
66+
if (_default != null) {
67+
LOGGER.warn(message);
68+
return _default;
69+
}
70+
throw new IllegalStateException("Mavenizer did not output expected json data " + key +", Make sure you're using Mavenizer >= " + requiredVersion);
71+
}));
72+
}
73+
5874
@Override
5975
public Provider<ExternalModuleDependency> asProvider() {
6076
return this.invoke.map(m -> this.dependency);
6177
}
6278

79+
@Override
80+
public Provider<String> getMappingChannel() {
81+
return get("mappings.channel");
82+
}
83+
6384
@Override
6485
public Provider<String> getMappingVersion() {
6586
return get("mappings.version");
@@ -84,4 +105,20 @@ public Provider<String> getToObf() {
84105
public Provider<File> getToObfFile() {
85106
return get("mappings.obf.file").map(this.extension.getProject()::file);
86107
}
108+
109+
@Override
110+
public Provider<String> getMinecraftVersion() {
111+
return get("mc.version", "UNKNOWN", "0.4.33");
112+
}
113+
114+
@Override
115+
public Provider<String> getMCPVersion() {
116+
return get("mcp.version", "UNKNOWN", "0.4.33");
117+
}
118+
119+
// Internal, not sure if I want to return
120+
public Provider<List<String>> getPatcherModules() {
121+
return get("patcher.modules", "", "0.4.33")
122+
.map(value -> value.isBlank() ? List.of() : List.of(value.split(",")));
123+
}
87124
}

0 commit comments

Comments
 (0)