Skip to content

Commit

Permalink
Resolve NeoForm & NeoForge ZIP-Archives Earlier to Access Configs in …
Browse files Browse the repository at this point in the history
…Specifications (#86)

Refactor NeoForm & NeoForge archive handling such that the archives are resolved earlier. That allows simplification of the runtime specifications by resolving the configuration files in the archives when the specifications are built.
  • Loading branch information
shartte authored Feb 3, 2024
1 parent ecea0a6 commit 5b70c30
Show file tree
Hide file tree
Showing 18 changed files with 401 additions and 482 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
if: success() || failure()
run: npx junit-report-merger junit.xml "**/TEST-*.xml"

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test-results
Expand Down
60 changes: 52 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,59 @@
NeoGradle
===========
# NeoGradle

Minecraft mod development framework used by NeoForge and FML for the Gradle build system.
Minecraft mod development framework, used by NeoForge and FML for the Gradle build system.

For a quick start, see how the [NeoForge Mod Development Kit](https://github.com/neoforged/MDK) uses NeoGradle, or see
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).

## Plugins

NeoGradle is separated into several different plugins that can be applied independently of each other.

### Userdev Plugin

This plugin is used for building mods with NeoForge. As a modder, this will in many cases be the only plugin you use.

```gradle
plugins {
id 'net.neoforged.gradle.userdev' version '<neogradle_version>'
}
dependencies {
implementation 'net.neoforged:neoforge:<neoforge_version>'
}
```

When this plugin detects a dependency on NeoForge, it will spring into action and create the necessary NeoForm runtime tasks to build a usable Minecraft JAR-file that contains the requested NeoForge version.

### NeoForm Runtime Plugin

This plugin enables use of the NeoForm runtime and allows projects to depend directly on deobfuscated but otherwise
unmodified Minecraft artifacts.

This plugin is used internally by other plugins and is usually only needed for advanced use cases.

```gradle
plugins {
id 'net.neoforged.gradle.neoform' version '<neogradle_version>'
}
dependencies {
// For depending on a Minecraft JAR-file with both client- and server-classes
implementation "net.minecraft:neoform_joined:<neoform-version>'
// For depending on the Minecraft client JAR-file
implementation "net.minecraft:neoform_client:<neoform-version>'
// For depending on the Minecraft dedicated server JAR-file
implementation "net.minecraft:neoform_server:<neoform-version>'
}
```

## Apply Parchment Mappings

To get human-readable parameter names in decompiled Minecraft source-code, as well as Javadocs, crowed-sourced data
To get human-readable parameter names in decompiled Minecraft source-code, as well as Javadocs, crowdsourced 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.
Expand All @@ -22,7 +65,7 @@ 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.
The subsystem also has a Gradle DSL and supports more parameters, explained in the following Gradle snippet:

```gradle
subsystems {
Expand Down Expand Up @@ -61,20 +104,21 @@ subsystems {
}
```

## Advanced Settings

## Override Decompiler Settings
### Override Decompiler Settings

The settings used by the decompiler when preparing Minecraft dependencies can be overridden
using [Gradle properties](https://docs.gradle.org/current/userguide/project_properties.html).
This can be useful to trade slower build-times for being able to run NeoGradle on lower-end machines.
This can be useful to run NeoGradle on lower-end machines, at the cost of slower build times.

| Property | Description |
|----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
| `neogradle.subsystems.decompiler.maxMemory` | How much heap memory is given to the decompiler. Can be specified either in gigabyte (`4g`) or megabyte (`4096m`). |
| `neogradle.subsystems.decompiler.maxThreads` | By default the decompiler uses all available CPU cores. This setting can be used to limit it to a given number of threads. |
| `neogradle.subsystems.decompiler.logLevel` | Can be used to override the [decompiler loglevel](https://vineflower.org/usage/#cmdoption-log). |

## Override Recompiler Settings
### Override Recompiler Settings

The settings used by Neogradle for recompiling the decompiled Minecraft source code can be customized
using [Gradle properties](https://docs.gradle.org/current/userguide/project_properties.html).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public abstract class IvyDummyRepositoryEntry implements ConfigurableDSLElement<
private final Collection<RepositoryReference> dependencies;

/**
* @param project The project thsi entry resides in.
* @param project The project this entry resides in.
* @param group The group of the dependency.
* @param name The name of the dependency.
* @param version The version of the dependency.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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

import java.io.File;
Expand All @@ -19,6 +21,20 @@ public static File resolveTool(final Project project, final String tool) {
).getFiles().iterator().next();
}

public static ResolvedArtifact resolveToolArtifact(final Project project, final String tool) {
return ConfigurationUtils.temporaryUnhandledConfiguration(
project.getConfigurations(),
project.getDependencies().create(tool)
).getResolvedConfiguration().getResolvedArtifacts().iterator().next();
}

public static ResolvedArtifact resolveToolArtifact(final Project project, final Dependency tool) {
return ConfigurationUtils.temporaryUnhandledConfiguration(
project.getConfigurations(),
tool
).getResolvedConfiguration().getResolvedArtifacts().iterator().next();
}

public static Provider<File> resolveTool(final Project project, final Provider<String> tool) {
return tool.map(toolArtifactId -> resolveTool(project, toolArtifactId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package net.neoforged.gradle.dsl.neoform.runtime.specification

import groovy.transform.CompileStatic
import net.neoforged.gradle.dsl.common.runtime.spec.Specification
import net.neoforged.gradle.dsl.common.util.Artifact;
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Provider;
import org.jetbrains.annotations.NotNull;

/**
Expand All @@ -14,13 +12,13 @@ import org.jetbrains.annotations.NotNull;
interface NeoFormSpecification extends Specification {

/**
* Defines the NeoForm artifact that is used to build the specification.
* The version of NeoForm that shall be used.
*
* @return The NeoForm artifact.
* @return The NeoForm version.
*/
@NotNull
Artifact getNeoFormArtifact();
String getNeoFormVersion();

/**
* A collection of files which need to be added to the recompile classpath,
* for the recompile phase to succeed.
Expand All @@ -39,76 +37,21 @@ interface NeoFormSpecification extends Specification {
interface Builder<S extends NeoFormSpecification, B extends Builder<S, B>> extends Specification.Builder<S, B> {

/**
* Configures the specification for use with the given NeoForm Group, extracted from the given provider.
*
* @param neoFormGroup The NeoForm Group provider.
* @return The builder.
*/
@NotNull
B withNeoFormGroup(@NotNull final Provider<String> neoFormGroup);

/**
* Configures the specification for use with the given NeoForm Group.
*
* @param neoFormGroup The NeoForm Group to use.
* @return The builder.
*/
@NotNull
B withNeoFormGroup(@NotNull final String neoFormGroup);

/**
* Configures the specification for use with the given NeoForm Name, extracted from the given provider.
*
* @param neoFormName The NeoForm Name provider.
* @return The builder.
*/
@NotNull
B withNeoFormName(@NotNull final Provider<String> neoFormName);

/**
* Configures the specification for use with the given NeoForm Name.
*
* @param neoFormName The NeoForm Name to use.
* @return The builder.
*/
@NotNull
B withNeoFormName(@NotNull final String neoFormName);

/**
* Configures the specification for use with the given NeoForm version, extracted from the given provider.
*
* @param neoFormVersion The NeoForm version provider.
* @return The builder.
*/
@NotNull
B withNeoFormVersion(@NotNull final Provider<String> neoFormVersion);

/**
* Configures the specification for use with the given NeoForm version.
*
* @param neoFormVersion The NeoForm version to use.
* @return The builder.
*/
@NotNull
B withNeoFormVersion(@NotNull final String neoFormVersion);

/**
* Configures the specification for use with the given NeoForm Artifact, extracted from the given provider.
*
* @param neoFormArtifact The NeoForm Artifact provider.
* @return The builder.
* Configures the specification to use NeoForm in the given version.
*/
@NotNull
B withNeoFormArtifact(@NotNull final Provider<Artifact> neoFormArtifact);
default B withNeoFormVersion(@NotNull final String version) {
withNeoFormDependency(project.getDependencies().create("net.neoforged:neoform:" + version + "@zip"));
}

/**
* Configures the specification for use with the given NeoForm Artifact.
* Configures the specification for use with the given NeoForm dependency.
*
* @param neoFormArtifact The NeoForm Artifact to use.
* @param dependencyNotation The coordinates of the NeoForm archive in Gradle notation.
* @return The builder.
*/
@NotNull
B withNeoFormArtifact(@NotNull final Artifact neoFormArtifact);
B withNeoFormDependency(@NotNull final Object dependencyNotation);

/**
* Configures the specification to use the given file collection as additional recompile dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.gradle.api.tasks.Optional

import javax.inject.Inject
import java.lang.reflect.Type
import java.nio.charset.StandardCharsets
import java.util.function.BiFunction
import java.util.function.Function

Expand All @@ -33,13 +34,19 @@ abstract class UserdevProfile implements ConfigurableDSLElement<UserdevProfile>
this.factory = factory
}

public static Gson createGson(ObjectFactory objectFactory) {
static Gson createGson(ObjectFactory objectFactory) {
return new GsonBuilder().disableHtmlEscaping()
.registerTypeHierarchyAdapter(UserdevProfile.class, new Serializer(objectFactory))
.registerTypeHierarchyAdapter(ToolExecution.class, new ToolExecution.Serializer(objectFactory))
.create()
}

static UserdevProfile get(ObjectFactory objectFactory, InputStream input) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
return createGson(objectFactory).fromJson(reader, UserdevProfile.class);
}
}

@Input
@DSLProperty
@Optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ public void apply(@Nonnull Project project) {
// Needed to gain access to the common systems
project.getPluginManager().apply(CommonPlugin.class);

NeoFormRuntimeExtension runtimeExtension = project.getExtensions().create("neoFormRuntime", NeoFormRuntimeExtension.class, project);
project.getExtensions().create("neoFormRuntime", NeoFormRuntimeExtension.class, project);

NeoFormOfficialNamingChannelConfigurator.getInstance().configure(project);

//Setup handling of the dependencies
NeoFormDependencyManager.getInstance().apply(project);
// Setup handling of the dependencies
NeoFormDependencyManager.apply(project);

//Add Known repos
// Add Known repos
project.getRepositories().maven(e -> {
e.setUrl(UrlConstants.NEO_FORGE_MAVEN);
e.metadataSources(MavenArtifactRepository.MetadataSources::mavenPom);
Expand Down
Loading

0 comments on commit 5b70c30

Please sign in to comment.