diff --git a/src/legacy/java/net/neoforged/moddevgradle/legacyforge/dsl/LegacyForgeExtension.java b/src/legacy/java/net/neoforged/moddevgradle/legacyforge/dsl/LegacyForgeExtension.java index bd207a27..43ae47c5 100644 --- a/src/legacy/java/net/neoforged/moddevgradle/legacyforge/dsl/LegacyForgeExtension.java +++ b/src/legacy/java/net/neoforged/moddevgradle/legacyforge/dsl/LegacyForgeExtension.java @@ -18,8 +18,9 @@ public abstract class LegacyForgeExtension extends ModDevExtension { @Inject public LegacyForgeExtension(Project project, DataFileCollection accessTransformers, - DataFileCollection interfaceInjectionData) { - super(project, accessTransformers, interfaceInjectionData); + DataFileCollection interfaceInjectionData, + DataFileCollection enumExtensionsData) { + super(project, accessTransformers, interfaceInjectionData, enumExtensionsData); this.project = project; } diff --git a/src/legacy/java/net/neoforged/moddevgradle/legacyforge/internal/LegacyForgeModDevPlugin.java b/src/legacy/java/net/neoforged/moddevgradle/legacyforge/internal/LegacyForgeModDevPlugin.java index a3f7ef17..c8ae98e3 100644 --- a/src/legacy/java/net/neoforged/moddevgradle/legacyforge/internal/LegacyForgeModDevPlugin.java +++ b/src/legacy/java/net/neoforged/moddevgradle/legacyforge/internal/LegacyForgeModDevPlugin.java @@ -104,7 +104,8 @@ public void apply(Project project) { LegacyForgeExtension.class, project, dataFileCollections.accessTransformers().extension(), - dataFileCollections.interfaceInjectionData().extension()); + dataFileCollections.interfaceInjectionData().extension(), + dataFileCollections.enumExtensionsData().extension()); } public void enable(Project project, LegacyForgeModdingSettings settings, LegacyForgeExtension extension) { @@ -153,6 +154,7 @@ public void enable(Project project, LegacyForgeModdingSettings settings, LegacyF artifactNamingStrategy, configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS), configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA), + configurations.getByName(DataFileCollections.CONFIGURATION_ENUM_EXTENSIONS_DATA), versionCapabilities, settings.isDisableRecompilation()); diff --git a/src/main/java/net/neoforged/moddevgradle/dsl/ModDevExtension.java b/src/main/java/net/neoforged/moddevgradle/dsl/ModDevExtension.java index 021719a8..51bb11e3 100644 --- a/src/main/java/net/neoforged/moddevgradle/dsl/ModDevExtension.java +++ b/src/main/java/net/neoforged/moddevgradle/dsl/ModDevExtension.java @@ -24,17 +24,20 @@ public abstract class ModDevExtension { private final Project project; private final DataFileCollection accessTransformers; private final DataFileCollection interfaceInjectionData; + private final DataFileCollection enumExtensionsData; @Inject public ModDevExtension(Project project, DataFileCollection accessTransformers, - DataFileCollection interfaceInjectionData) { + DataFileCollection interfaceInjectionData, + DataFileCollection enumExtensionsData) { mods = project.container(ModModel.class); runs = project.container(RunModel.class, name -> project.getObjects().newInstance(RunModel.class, name, project, mods)); parchment = project.getObjects().newInstance(Parchment.class); this.project = project; this.accessTransformers = accessTransformers; this.interfaceInjectionData = interfaceInjectionData; + this.enumExtensionsData = enumExtensionsData; getValidateAccessTransformers().convention(false); // Make sync tasks run @@ -89,6 +92,28 @@ public void setInterfaceInjectionData(Object... paths) { getInterfaceInjectionData().getFiles().setFrom(paths); } + /** + * The data-files describing additional enum extension declarations to be added to Minecraft enums. + *

+ * This is an advanced property: Extending enums in your development environment using this property will not actually extend the enums in your published mod. You must register your enum extensions in your mod metadata for that. + * + * @see Extensible Enums + */ + public void enumExtensionsData(Action action) { + action.execute(enumExtensionsData); + } + + public DataFileCollection getEnumExtensionsData() { + return enumExtensionsData; + } + + /** + * Replaces current enum extensions data files. + */ + public void setEnumExtensionsData(Object... paths) { + getEnumExtensionsData().getFiles().setFrom(paths); + } + /** * Enable access transformer validation, raising fatal errors if an AT targets a member that doesn't exist. *

diff --git a/src/main/java/net/neoforged/moddevgradle/dsl/NeoForgeExtension.java b/src/main/java/net/neoforged/moddevgradle/dsl/NeoForgeExtension.java index c090517a..8b50abe5 100644 --- a/src/main/java/net/neoforged/moddevgradle/dsl/NeoForgeExtension.java +++ b/src/main/java/net/neoforged/moddevgradle/dsl/NeoForgeExtension.java @@ -17,8 +17,8 @@ public abstract class NeoForgeExtension extends ModDevExtension { private final UnitTest unitTest; @Inject - public NeoForgeExtension(Project project, DataFileCollection accessTransformers, DataFileCollection interfaceInjectionData) { - super(project, accessTransformers, interfaceInjectionData); + public NeoForgeExtension(Project project, DataFileCollection accessTransformers, DataFileCollection interfaceInjectionData, DataFileCollection enumExtensionsData) { + super(project, accessTransformers, interfaceInjectionData, enumExtensionsData); this.project = project; unitTest = project.getObjects().newInstance(UnitTest.class); unitTest.getLoadedMods().convention(getMods()); diff --git a/src/main/java/net/neoforged/moddevgradle/internal/DataFileCollections.java b/src/main/java/net/neoforged/moddevgradle/internal/DataFileCollections.java index 2079587e..ee0a5d8d 100644 --- a/src/main/java/net/neoforged/moddevgradle/internal/DataFileCollections.java +++ b/src/main/java/net/neoforged/moddevgradle/internal/DataFileCollections.java @@ -23,12 +23,15 @@ */ @ApiStatus.Internal public record DataFileCollections(CollectionWrapper accessTransformers, - CollectionWrapper interfaceInjectionData) { + CollectionWrapper interfaceInjectionData, + CollectionWrapper enumExtensionsData) { public static final String CONFIGURATION_ACCESS_TRANSFORMERS = "accessTransformers"; public static final String CONFIGURATION_INTERFACE_INJECTION_DATA = "interfaceInjectionData"; + public static final String CONFIGURATION_ENUM_EXTENSIONS_DATA = "enumExtensionsData"; + /** * Constructs the default data file collections for access transformers and intrface injection data * with sensible defaults. @@ -62,7 +65,13 @@ public static DataFileCollections create(Project project) { "Interface injection data adds extend/implements clauses for interfaces to Minecraft code at development time", "interfaceinjection"); - return new DataFileCollections(accessTransformers, interfaceInjectionData); + var enumExtensionsData = createCollection( + project, + CONFIGURATION_ENUM_EXTENSIONS_DATA, + "Enum extensions data adds new enum constants to Minecraft enums at development time", + "enumextensions"); + + return new DataFileCollections(accessTransformers, interfaceInjectionData, enumExtensionsData); } public record CollectionWrapper(DataFileCollection extension, Configuration configuration) {} diff --git a/src/main/java/net/neoforged/moddevgradle/internal/ModDevArtifactsWorkflow.java b/src/main/java/net/neoforged/moddevgradle/internal/ModDevArtifactsWorkflow.java index 40b1723d..a81cf34e 100644 --- a/src/main/java/net/neoforged/moddevgradle/internal/ModDevArtifactsWorkflow.java +++ b/src/main/java/net/neoforged/moddevgradle/internal/ModDevArtifactsWorkflow.java @@ -67,6 +67,7 @@ public static ModDevArtifactsWorkflow create(Project project, ArtifactNamingStrategy artifactNamingStrategy, Configuration accessTransformers, Configuration interfaceInjectionData, + Configuration enumExtensionsData, VersionCapabilitiesInternal versionCapabilities, boolean disableRecompilation) { if (project.getExtensions().findByName(EXTENSION_NAME) != null) { @@ -147,6 +148,7 @@ public static ModDevArtifactsWorkflow create(Project project, } })); task.getInterfaceInjectionData().from(interfaceInjectionData); + task.getEnumExtensionsData().from(enumExtensionsData); task.getParchmentData().from(parchmentData); task.getParchmentEnabled().set(parchment.getEnabled()); task.getParchmentConflictResolutionPrefix().set(parchment.getConflictResolutionPrefix()); diff --git a/src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java b/src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java index 97f0e7f5..51272691 100644 --- a/src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java +++ b/src/main/java/net/neoforged/moddevgradle/internal/ModDevPlugin.java @@ -41,7 +41,8 @@ public void apply(Project project) { NeoForgeExtension.NAME, NeoForgeExtension.class, dataFileCollections.accessTransformers().extension(), - dataFileCollections.interfaceInjectionData().extension()); + dataFileCollections.interfaceInjectionData().extension(), + dataFileCollections.enumExtensionsData().extension()); } public void enable( @@ -97,6 +98,7 @@ public void enable( artifactNamingStrategy, configurations.getByName(DataFileCollections.CONFIGURATION_ACCESS_TRANSFORMERS), configurations.getByName(DataFileCollections.CONFIGURATION_INTERFACE_INJECTION_DATA), + configurations.getByName(DataFileCollections.CONFIGURATION_ENUM_EXTENSIONS_DATA), versionCapabilities, settings.isDisableRecompilation()); diff --git a/src/main/java/net/neoforged/nfrtgradle/CreateMinecraftArtifacts.java b/src/main/java/net/neoforged/nfrtgradle/CreateMinecraftArtifacts.java index d9f9eb54..49f8867f 100644 --- a/src/main/java/net/neoforged/nfrtgradle/CreateMinecraftArtifacts.java +++ b/src/main/java/net/neoforged/nfrtgradle/CreateMinecraftArtifacts.java @@ -80,6 +80,12 @@ public CreateMinecraftArtifacts() { @InputFiles public abstract ConfigurableFileCollection getInterfaceInjectionData(); + /** + * Files added to this collection will be passed to NFRT via the {@code --enum-extensions.data} command line option. + */ + @InputFiles + public abstract ConfigurableFileCollection getEnumExtensionsData(); + /** * If set to true, all files from {@link #getAccessTransformers()} are added as validated ATs and will fail the build * if they contain errors, or they target non-existent code elements. @@ -296,6 +302,11 @@ public void createArtifacts() { args.add(interfaceInjectionFile.getAbsolutePath()); } + for (var enumExtensionsFile : getEnumExtensionsData().getFiles()) { + args.add("--enum-extensions-data"); + args.add(enumExtensionsFile.getAbsolutePath()); + } + if (getParchmentEnabled().get()) { var parchmentData = getParchmentData().getFiles(); if (parchmentData.size() == 1) { diff --git a/src/test/java/net/neoforged/moddevgradle/functional/DataFileCollectionFunctionalTest.java b/src/test/java/net/neoforged/moddevgradle/functional/DataFileCollectionFunctionalTest.java index e71d5e48..bdc23ba4 100644 --- a/src/test/java/net/neoforged/moddevgradle/functional/DataFileCollectionFunctionalTest.java +++ b/src/test/java/net/neoforged/moddevgradle/functional/DataFileCollectionFunctionalTest.java @@ -111,6 +111,34 @@ public void testPublishInterfaceInjectionFile() throws IOException { entry("publish-if-1.0-interfaceinjection3.json", "{}")); } + @Test + public void testPublishEnumExtensionsFile() throws IOException { + writeProjectFile("enumextensions.json", "{}"); + writeProjectFile("subfolder/enumextensions.json", "{}"); + Files.writeString(testProjectDir.toPath().resolve("enumextensions.json"), "{}"); + + publishDataFiles("test", "publish-if", "1.0", """ + def generatedDataFile = tasks.register("generateDataFile") { + outputs.file("build/generatedDataFile.json") + doFirst { + outputs.files.singleFile.text = '{}' + } + } + neoForge { + enumExtensionsData { + publish(file('enumextensions.json')) + publish(file('subfolder/enumextensions.json')) + publish(generatedDataFile) + } + } + """); + + assertThat(consumeDataFilePublication("enumExtensionsData", "test:publish-if:1.0")).containsOnly( + entry("publish-if-1.0-enumextensions1.json", "{}"), + entry("publish-if-1.0-enumextensions2.json", "{}"), + entry("publish-if-1.0-enumextensions3.json", "{}")); + } + @Test public void testNoEmptyVariantsArePublished() throws IOException { publishDataFiles("test", "publish-empty", "1.0", "");