Skip to content

Commit

Permalink
Convert AW to AT for ForgeGradle
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeregorix committed Dec 22, 2024
1 parent 061dfd0 commit c644444
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 27 deletions.
5 changes: 5 additions & 0 deletions build-logic/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ indra {
dependencies {
api(apiLibs.gson)
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:${apiLibs.versions.ideaExt.get()}")
implementation(libs.at)
implementation(libs.accessWidener)

// arch-loom is used by SpongeNeo but must be declared here to avoid a classloader conflict with its transitive dependencies
api("dev.architectury:architectury-loom:1.6.411")
}

indraSpotlessLicenser {
Expand Down
9 changes: 8 additions & 1 deletion build-logic/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ pluginManagement {

dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories { pluginManagement.repositories.each { add(it) } }
repositories {
pluginManagement.repositories.each { add(it) }
maven {
url = "https://maven.architectury.dev/"
name = "architectury"
}
}

versionCatalogs {
libs {
from files("../gradle/libs.versions.toml")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.gradle.impl;

import dev.architectury.at.AccessChange;
import dev.architectury.at.AccessTransform;
import dev.architectury.at.AccessTransformSet;
import dev.architectury.at.ModifierChange;
import dev.architectury.at.io.AccessTransformFormats;
import net.fabricmc.accesswidener.AccessWidenerReader;
import net.fabricmc.accesswidener.AccessWidenerVisitor;
import org.cadixdev.bombe.type.signature.MethodSignature;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Set;

public abstract class ConvertAWToAT extends DefaultTask {

@InputFiles
public abstract ConfigurableFileCollection getAccessWideners();

public void accessWideners(Object... paths) {
this.getAccessWideners().from(paths);
}

@OutputFile
public abstract RegularFileProperty getAccessTransformer();

@TaskAction
public void convert() {
final Set<File> awFiles = this.getAccessWideners().getFiles();
final File atFile = this.getAccessTransformer().get().getAsFile();

final AccessTransformSet at = AccessTransformSet.create();

for (final File awFile : awFiles) {
try (final BufferedReader reader = Files.newBufferedReader(awFile.toPath())) {
ConvertAWToAT.convert(reader, at);
} catch (final IOException e) {
throw new GradleException("Failed to read access widener: " + awFile, e);
}
}

try (final BufferedWriter writer = Files.newBufferedWriter(atFile.toPath())) {
AccessTransformFormats.FML.write(writer, at);
} catch (IOException e) {
throw new GradleException("Failed to write access transformer: " + atFile, e);
}
}

public static void convert(final BufferedReader reader, final AccessTransformSet at) throws IOException {
new AccessWidenerReader(new AccessWidenerVisitor() {
@Override
public void visitClass(final String name, final AccessWidenerReader.AccessType access, final boolean transitive) {
at.getOrCreateClass(name).merge(ConvertAWToAT.convertEntry(access));
}

@Override
public void visitMethod(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
at.getOrCreateClass(owner).mergeMethod(MethodSignature.of(name, descriptor), ConvertAWToAT.convertEntry(access));
}

@Override
public void visitField(final String owner, final String name, final String descriptor, final AccessWidenerReader.AccessType access, final boolean transitive) {
at.getOrCreateClass(owner).mergeField(name, ConvertAWToAT.convertEntry(access));
}
}).read(reader);
}

public static AccessTransform convertEntry(final AccessWidenerReader.AccessType access) {
return switch (access) {
case ACCESSIBLE -> AccessTransform.of(AccessChange.PUBLIC);
case EXTENDABLE, MUTABLE -> AccessTransform.of(AccessChange.PUBLIC, ModifierChange.REMOVE);
};
}
}
11 changes: 4 additions & 7 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ dependencies {
}
}

minecraft {
accessWideners(main.resources.filter { it.name.endsWith(".accesswidener") })
}

allprojects {
configurations.configureEach {
resolutionStrategy.dependencySubstitution {
Expand All @@ -199,13 +203,6 @@ allprojects {
minecraft {
version(minecraftVersion)
injectRepositories(false)
project.sourceSets["main"].resources
.filter { it.name.endsWith(".accesswidener") }
.files
.forEach {
accessWideners(it)
parent?.minecraft?.accessWideners(it)
}
}

dependencies {
Expand Down
12 changes: 9 additions & 3 deletions forge/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import net.minecraftforge.gradle.userdev.UserDevExtension
import org.spongepowered.gradle.impl.ConvertAWToAT

buildscript {
repositories {
Expand Down Expand Up @@ -201,20 +202,25 @@ dependencies {
runtimeOnly(project(bootstrapDevProject.path))
}

val convertAWToAT = tasks.register("convertAWToAT", ConvertAWToAT::class) {
accessWideners(main.get().resources.filter { it.name.endsWith(".accesswidener") })
accessWideners(forgeMain.resources.filter { it.name.endsWith(".accesswidener") })
accessTransformer.set(project.layout.buildDirectory.file("generated/resources/at.cfg"))
}

val mixinConfigs: MutableSet<String> = spongeImpl.mixinConfigurations

extensions.configure(UserDevExtension::class) {
mappings("official", "1.21.3")
// accessWidenerPath.set(file("../src/main/resources/common.accesswidener")) TODO
accessTransformers.from(convertAWToAT.flatMap { it.accessTransformer })

reobf = false

runs {
configureEach {
ideaModule("Sponge.SpongeForge.main")

property("forge.logging.markers", "REGISTRIES")
property("forge.logging.console.level", "debug")
// property("forge.logging.console.level", "debug")

// jvmArgs("-Dbsl.debug=true") // Uncomment to debug bootstrap classpath

Expand Down
7 changes: 1 addition & 6 deletions generator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ plugins {
description = "Code generator for automatically producing API catalog classes based off of Vanilla MC data"

minecraft {
rootProject.sourceSets["main"].resources
.filter { it.name.endsWith(".accesswidener") }
.files
.forEach {
accessWideners(it)
}
accessWideners(rootProject.sourceSets["main"].resources.filter { it.name.endsWith(".accesswidener") })
}

configurations.configureEach {
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ terminalConsoleAppender = { module = "net.minecrell:terminalconsoleappender", ve

# buildtime-only
vineflower = { module = "org.vineflower:vineflower", version.ref = "vineflower" }
at = { module = "dev.architectury:at", version = "1.0.1" }

[plugins]
blossom = { id = "net.kyori.blossom", version = "2.1.0" }
Expand Down
2 changes: 1 addition & 1 deletion neoforge/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {
alias(libs.plugins.shadow)
id("implementation-structure")
alias(libs.plugins.blossom)
id("dev.architectury.loom") version "1.6.411"
id("dev.architectury.loom")
}

val commonProject = parent!!
Expand Down
11 changes: 2 additions & 9 deletions vanilla/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,8 @@ val superclassConfigs = spongeImpl.getNamedConfigurations("superClassChanges")
val mixinConfigs = spongeImpl.mixinConfigurations

minecraft {
main.get().resources
.filter { it.name.endsWith(".accesswidener") }
.files
.forEach { accessWideners(it) }

vanillaMain.resources
.filter { it.name.endsWith(".accesswidener") }
.files
.forEach { accessWideners(it) }
accessWideners(main.get().resources.filter { it.name.endsWith(".accesswidener") })
accessWideners(vanillaMain.resources.filter { it.name.endsWith(".accesswidener") })
}

configurations.configureEach {
Expand Down

0 comments on commit c644444

Please sign in to comment.