Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parchment Prototype #83

Merged
merged 4 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,60 @@ our official [Documentation](https://docs.neoforged.net/neogradle/docs/).

To see the latest available version of NeoGradle, visit the [NeoForged project page](https://projects.neoforged.net/neoforged/neogradle).

## Apply Parchment Mappings

To get human-readable parameter names in decompiled Minecraft source-code, as well as Javadocs, crowed-sourced data
from the [Parchment project](https://parchmentmc.org) can be applied to the Minecraft source-code before it is recompiled.

This is currently only supported when applying the NeoGradle userdev Plugin.

The most basic configuration is using the following properties in gradle.properties:

```
neogradle.subsystems.parchment.minecraftVersion=1.20.2
neogradle.subsystems.parchment.mappingsVersion=2023.12.10
```

The subsystem also has Gradle DSL and supports more parameters explained in the following Gradle snippet.

```gradle
subsystems {
parchment {
# The Minecraft version for which the Parchment mappings were created.
# This does not necessarily need to match the Minecraft version your mod targets
# Defaults to the value of Gradle property neogradle.subsystems.parchment.minecraftVersion
minecraftVersion = "1.20.2"

# The version of Parchment mappings to apply.
# See https://parchmentmc.org/docs/getting-started for a list.
# Defaults to the value of Gradle property neogradle.subsystems.parchment.mappingsVersion
mappingsVersion = "2023.12.10"

# Overrides the full Maven coordinate of the Parchment artifact to use
# This is computed from the minecraftVersion and mappingsVersion properties by default.
# If you set this property explicitly, minecraftVersion and mappingsVersion will be ignored.
# The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.parchmentArtifact
# parchmentArtifact = "org.parchmentmc.data:parchment-$minecraftVersion:$mappingsVersion:checked@zip"

# Overrides the full Maven coordinate of the tool used to apply the Parchment mappings
# See https://github.com/neoforged/JavaSourceTransformer
# The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.toolArtifact
# toolArtifact = "net.neoforged.jst:jst-cli-bundle:1.0.29"

# Set this to false if you don't want the https://maven.parchmentmc.org/ repository to be added automatically when
# applying Parchment mappings is enabled
# The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.addRepository
# addRepository = true

# Can be used to explicitly disable this subsystem. By default, it will be enabled automatically as soon
# as parchmentArtifact or minecraftVersion and mappingsVersion are set.
# The built-in default value can also be overriden using the Gradle property neogradle.subsystems.parchment.enabled
# enabled = true
}
}
```


## Override Decompiler Settings

The settings used by the decompiler when preparing Minecraft dependencies can be overridden
Expand Down
Original file line number Diff line number Diff line change
@@ -1,51 +1,129 @@
package net.neoforged.gradle.common.extensions.subsystems;

import net.minecraftforge.gdi.ConfigurableDSLElement;
import net.neoforged.gradle.dsl.common.extensions.subsystems.Decompiler;
import net.neoforged.gradle.dsl.common.extensions.subsystems.DecompilerLogLevel;
import net.neoforged.gradle.dsl.common.extensions.subsystems.Parchment;
import net.neoforged.gradle.dsl.common.extensions.subsystems.Recompiler;
import net.neoforged.gradle.dsl.common.extensions.subsystems.Subsystems;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.repositories.MavenArtifactRepository;
import org.gradle.api.provider.Provider;

import javax.inject.Inject;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_ARTIFACT_PREFIX;
import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_GROUP;
import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_MAVEN_URL;
import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_PARCHMENT_TOOL_ARTIFACT;
import static net.neoforged.gradle.dsl.common.util.Constants.DEFAULT_RECOMPILER_MAX_MEMORY;
import static net.neoforged.gradle.dsl.common.util.Constants.SUBSYSTEM_PROPERTY_PREFIX;

public abstract class SubsystemsExtension implements ConfigurableDSLElement<Subsystems>, Subsystems {
private static final String PROPERTY_PREFIX = "neogradle.subsystems.";
private static final String DEFAULT_RECOMPILER_MAX_MEMORY = "1g";

private final Project project;

@Inject
public SubsystemsExtension(Project project) {
this.project = project;

// Decompiler default settings
getDecompiler().getMaxMemory().convention(getStringProperty("decompiler.maxMemory"));
getDecompiler().getMaxThreads().convention(getStringProperty("decompiler.maxThreads").map(Integer::parseUnsignedInt));
getDecompiler().getLogLevel().convention(getStringProperty("decompiler.logLevel").map(s -> {
configureDecompilerDefaults();
configureRecompilerDefaults();
configureParchmentDefaults();
}

private void configureDecompilerDefaults() {
Decompiler decompiler = getDecompiler();
decompiler.getMaxMemory().convention(getStringProperty("decompiler.maxMemory"));
decompiler.getMaxThreads().convention(getStringProperty("decompiler.maxThreads").map(Integer::parseUnsignedInt));
decompiler.getLogLevel().convention(getStringProperty("decompiler.logLevel").map(s -> {
try {
return DecompilerLogLevel.valueOf(s.toUpperCase(Locale.ROOT));
} catch (Exception e) {
throw new GradleException("Unknown DecompilerLogLevel: " + s + ". Available options: " + Arrays.toString(DecompilerLogLevel.values()));
}
}));
getDecompiler().getJvmArgs().convention(getSpaceSeparatedListProperty("decompiler.jvmArgs").orElse(Collections.emptyList()));
decompiler.getJvmArgs().convention(getSpaceSeparatedListProperty("decompiler.jvmArgs").orElse(Collections.emptyList()));
}

// Recompiler default settings
getRecompiler().getArgs().convention(getSpaceSeparatedListProperty("recompiler.args").orElse(Collections.emptyList()));
getRecompiler().getJvmArgs().convention(getSpaceSeparatedListProperty("recompiler.jvmArgs").orElse(Collections.emptyList()));
getRecompiler().getMaxMemory().convention(getStringProperty("recompiler.maxMemory").orElse(DEFAULT_RECOMPILER_MAX_MEMORY));
private void configureRecompilerDefaults() {
Recompiler recompiler = getRecompiler();
recompiler.getArgs().convention(getSpaceSeparatedListProperty("recompiler.args").orElse(Collections.emptyList()));
recompiler.getJvmArgs().convention(getSpaceSeparatedListProperty("recompiler.jvmArgs").orElse(Collections.emptyList()));
recompiler.getMaxMemory().convention(getStringProperty("recompiler.maxMemory").orElse(DEFAULT_RECOMPILER_MAX_MEMORY));
}

private void configureParchmentDefaults() {
Parchment parchment = getParchment();
parchment.getParchmentArtifact().convention(
getStringProperty("parchment.parchmentArtifact").orElse(
parchment.getMinecraftVersion()
.zip(parchment.getMappingsVersion(), (minecraftVersion, mappingVersion) -> {
return DEFAULT_PARCHMENT_GROUP
+ ":" + DEFAULT_PARCHMENT_ARTIFACT_PREFIX + minecraftVersion
+ ":" + mappingVersion
// We need the checked variant for now since it resolves
// parameters conflicting with local variables by prefixing everything with "p"
+ ":checked"
+ "@zip";
})
)
);
parchment.getMinecraftVersion().convention(
getStringProperty("parchment.minecraftVersion")
);
parchment.getMappingsVersion().convention(
getStringProperty("parchment.mappingsVersion")
);
parchment.getToolArtifact().convention(
getStringProperty("parchment.toolArtifact").orElse(DEFAULT_PARCHMENT_TOOL_ARTIFACT)
);
parchment.getAddRepository().convention(
getBooleanProperty("parchment.addRepository").orElse(true)
);
parchment.getEnabled().convention(parchment.getParchmentArtifact()
.map(s -> !s.isEmpty()).orElse(getBooleanProperty("parchment.enabled").orElse(false)));

// Add a filtered parchment repository automatically if enabled
project.afterEvaluate(p -> {
if (!parchment.getEnabled().get() || !parchment.getAddRepository().get()) {
return;
}
MavenArtifactRepository repo = p.getRepositories().maven(m -> {
m.setName("Parchment Data");
m.setUrl(URI.create(DEFAULT_PARCHMENT_MAVEN_URL));
m.mavenContent(mavenContent -> mavenContent.includeGroup(DEFAULT_PARCHMENT_GROUP));
});
// Make sure it comes first due to its filtered group, that should speed up resolution
p.getRepositories().remove(repo);
p.getRepositories().addFirst(repo);
});
}

private Provider<String> getStringProperty(String propertyName) {
return this.project.getProviders().gradleProperty(PROPERTY_PREFIX + propertyName);
return this.project.getProviders().gradleProperty(SUBSYSTEM_PROPERTY_PREFIX + propertyName);
}

private Provider<Boolean> getBooleanProperty(String propertyName) {
String fullPropertyName = SUBSYSTEM_PROPERTY_PREFIX + propertyName;
return this.project.getProviders().gradleProperty(fullPropertyName)
.map(value -> {
try {
return Boolean.valueOf(value);
} catch (Exception e) {
throw new GradleException("Gradle Property " + fullPropertyName + " is not set to a boolean value: '" + value + "'");
}
});
}

private Provider<List<String>> getSpaceSeparatedListProperty(String propertyName) {
return this.project.getProviders().gradleProperty(PROPERTY_PREFIX + propertyName)
return this.project.getProviders().gradleProperty(SUBSYSTEM_PROPERTY_PREFIX + propertyName)
.map(s -> Arrays.asList(s.split("\\s+")));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@

import net.neoforged.gradle.dsl.common.util.ConfigurationUtils;
import org.gradle.api.Project;
import org.gradle.api.provider.Provider;

import java.io.File;

public class ToolUtilities {

private ToolUtilities() {
throw new IllegalStateException("Tried to create utility class!");
}

public static File resolveTool(final Project project, final String tool) {
return ConfigurationUtils.temporaryUnhandledConfiguration(
project.getConfigurations(),
project.getDependencies().create(tool)
).getFiles().iterator().next();
}

public static Provider<File> resolveTool(final Project project, final Provider<String> tool) {
return tool.map(toolArtifactId -> resolveTool(project, toolArtifactId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package net.neoforged.gradle.dsl.common.extensions.subsystems

import groovy.transform.CompileStatic
import net.minecraftforge.gdi.ConfigurableDSLElement
import net.minecraftforge.gdi.annotations.DSLProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional

/**
* Allows configuration of Parchment mappings for userdev.
*/
@CompileStatic
interface Parchment extends ConfigurableDSLElement<Parchment> {

/**
* Artifact coordinates for parchment mappings.
*/
@Input
@Optional
@DSLProperty
Property<String> getParchmentArtifact();

/**
* Minecraft version of parchment to use. This property is
* ignored if {@link #getParchmentArtifact()} is set explicitly.
*/
@Input
@Optional
@DSLProperty
Property<String> getMinecraftVersion();

/**
* Mapping version of default parchment to use. This property is
* ignored if {@link #getParchmentArtifact()} is set explicitly.
*/
@Input
@Optional
@DSLProperty
Property<String> getMappingsVersion();

/**
* Artifact coordinates for the tool used to apply the mappings. Overriding this is an advanced use case.
*/
@Input
@Optional
@DSLProperty
Property<String> getToolArtifact();

/**
* If enabled (the default), the parchment repository will automatically be added to the project,
* if {@link #getEnabled()} is true.
*/
@Internal
@DSLProperty
Property<Boolean> getAddRepository();

/**
* Enables or disables the system. It is enabled by default if a {@link #getParchmentArtifact()} is specified.
*/
@Input
@DSLProperty
Property<Boolean> getEnabled();

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ interface Subsystems extends BaseDSLElement<Subsystems> {
@DSLProperty
Recompiler getRecompiler();

/**
* @return settings for applying Parchment mappings.
*/
@Nested
@DSLProperty
Parchment getParchment();

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ class Constants {
public static final String FART_VERSION = "1.0.2";
public static final String FART_ARTIFACT_INTERPOLATION = "net.minecraftforge:ForgeAutoRenamingTool:%s:all";
public static final String FART = String.format(FART_ARTIFACT_INTERPOLATION, FART_VERSION);
public static final String SRG2SOURCE = "net.minecraftforge:Srg2Source:8.+:fatjar";
public static final String SIDESTRIPPER = "net.minecraftforge:mergetool:1.1.5:fatjar";
public static final String INSTALLERTOOLS = "net.minecraftforge:installertools:1.3.2:fatjar";
public static final String JARCOMPATIBILITYCHECKER = "net.minecraftforge:JarCompatibilityChecker:0.1.+:all";

public static final String VINEFLOWER_VERSION = "1.9.3";
public static final String VINEFLOWER_ARTIFACT_INTERPOLATION = "org.vineflower:vineflower:%s";
public static final String VINEFLOWER = String.format(VINEFLOWER_ARTIFACT_INTERPOLATION, VINEFLOWER_VERSION);

public static final String DEFAULT_PARCHMENT_GROUP = "org.parchmentmc.data"
public static final String DEFAULT_PARCHMENT_ARTIFACT_PREFIX = "parchment-"
public static final String DEFAULT_PARCHMENT_MAVEN_URL = "https://maven.parchmentmc.org/"
public static final String DEFAULT_PARCHMENT_TOOL_ARTIFACT = "net.neoforged.jst:jst-cli-bundle:1.0.29"

public static final String DEFAULT_RECOMPILER_MAX_MEMORY = "1g"

public static final String SUBSYSTEM_PROPERTY_PREFIX = "neogradle.subsystems."
}
Loading