yarn/build.gradle

1090 lines
29 KiB
Groovy
Raw Normal View History

2016-08-17 15:23:28 -04:00
buildscript {
repositories {
maven {
2019-06-28 17:55:20 -04:00
name "Fabric Repository"
url 'https://maven.fabricmc.net'
}
mavenCentral()
}
dependencies {
2020-06-03 14:47:17 -04:00
classpath "cuchaz:enigma-cli:${project.enigma_version}"
classpath "net.fabricmc:stitch:${project.stitch_version}"
classpath "commons-io:commons-io:2.8.0"
classpath 'de.undercouch:gradle-download-task:4.1.1'
classpath 'net.fabricmc:tiny-remapper:0.3.2'
classpath "net.fabricmc.unpick:unpick:${project.unpick_version}"
classpath "net.fabricmc.unpick:unpick-format-utils:${project.unpick_version}"
}
2016-08-17 15:23:28 -04:00
}
plugins {
id 'de.undercouch.download' version '4.1.1'
id 'base'
id 'maven-publish'
id 'java' // for jd gen
id 'org.cadixdev.licenser' version '0.5.1'
id 'net.fabricmc.filament' version '0.2.0'
}
def minecraft_version = "21w17a"
2016-09-09 08:47:32 -04:00
def ENV = System.getenv()
2020-11-06 18:33:17 -05:00
// Fetch build number from Github Actions
def build_number = ENV.BUILD_NUMBER ?: "local"
2019-04-10 12:20:44 -04:00
def yarnVersion = "${minecraft_version}+build.$build_number"
version = yarnVersion
2016-09-09 08:47:32 -04:00
repositories {
mavenCentral()
maven {
2019-06-28 17:55:20 -04:00
name "Fabric Repository"
url 'https://maven.fabricmc.net'
}
maven {
name "Mojang"
url 'https://libraries.minecraft.net/'
}
mavenLocal()
}
configurations {
enigmaRuntime {
resolutionStrategy {
cacheDynamicVersionsFor 0, "seconds"
cacheChangingModulesFor 0, "seconds"
}
}
javadocClasspath
decompileClasspath
mappingPoetJar {
transitive = false
}
mappingPoet {
extendsFrom mappingPoetJar
transitive = true
}
unpick
}
def unpickMetaFile = file("unpick-definitions/unpick.json")
dependencies {
2020-06-03 14:47:17 -04:00
enigmaRuntime "cuchaz:enigma-swing:${project.enigma_version}"
enigmaRuntime "net.fabricmc:stitch:${project.stitch_version}"
javadocClasspath "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
javadocClasspath "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
javadocClasspath "com.google.code.findbugs:jsr305:3.0.2" // for some other jsr annotations
decompileClasspath "net.fabricmc:cfr:${project.cfr_version}"
mappingPoetJar 'net.fabricmc:mappingpoet:0.2.7'
unpick "net.fabricmc.unpick:unpick-cli:${project.unpick_version}"
}
def setupGroup = "jar setup"
def yarnGroup = "yarn"
def buildMappingGroup = "mapping build"
def mapJarGroup = "jar mapping"
def mappingsDir = file("mappings")
def cacheFilesMinecraft = file(".gradle/minecraft")
2018-10-31 09:05:19 -04:00
def tempDir = file(".gradle/temp")
def mergedFile = file("${minecraft_version}-merged.jar")
def intermediaryJar = file("${minecraft_version}-intermediary.jar")
def unpickedJar = file("${minecraft_version}-intermediary-unpicked.jar")
def namedJar = file("${minecraft_version}-named.jar")
def versionFile = new File(cacheFilesMinecraft, "${minecraft_version}.json")
def clientJar = new File(cacheFilesMinecraft, "${minecraft_version}-client.jar")
def serverJar = new File(cacheFilesMinecraft, "${minecraft_version}-server.jar")
2019-06-28 17:55:20 -04:00
def libraries = new File(cacheFilesMinecraft, "libraries")
2018-10-30 07:29:43 -04:00
def libs = new File("build/libs/")
2019-11-07 06:38:33 -05:00
import com.google.common.hash.Hashing
import cuchaz.enigma.command.CheckMappingsCommand
2019-06-28 17:55:20 -04:00
import cuchaz.enigma.command.ComposeMappingsCommand
import cuchaz.enigma.command.ConvertMappingsCommand
import cuchaz.enigma.command.MapSpecializedMethodsCommand
import groovy.io.FileType
import groovy.json.JsonSlurper
import net.fabricmc.stitch.commands.CommandMergeTiny
import net.fabricmc.stitch.commands.CommandProposeFieldNames
import net.fabricmc.stitch.commands.CommandReorderTiny
2019-04-18 17:22:36 -04:00
import net.fabricmc.stitch.commands.CommandRewriteIntermediary
import net.fabricmc.stitch.commands.tinyv2.CommandMergeTinyV2
import net.fabricmc.stitch.commands.tinyv2.CommandProposeV2FieldNames
import net.fabricmc.stitch.commands.tinyv2.CommandReorderTinyV2
import net.fabricmc.stitch.merge.JarMerger
import net.fabricmc.tinyremapper.OutputConsumerPath
import net.fabricmc.tinyremapper.TinyRemapper
import net.fabricmc.tinyremapper.TinyUtils
import org.apache.commons.io.FileUtils
import java.nio.charset.StandardCharsets
import java.util.zip.GZIPOutputStream
2016-08-17 15:23:28 -04:00
boolean validateChecksum(File file, String checksum) {
if (file != null) {
2019-11-07 06:38:33 -05:00
def hash = com.google.common.io.Files.asByteSource(file).hash(Hashing.sha1())
2016-08-17 15:23:28 -04:00
def builder = new StringBuilder()
hash.asBytes().each {
builder.append(Integer.toString((it & 0xFF) + 0x100, 16).substring(1))
}
return builder.toString().equals(checksum)
}
return false
}
task downloadVersionsManifest {
group = setupGroup
//inputs.property "mc_ver", minecraft_version
inputs.property "currenttime", new Date()
def manifestFile = new File(cacheFilesMinecraft, "version_manifest.json")
outputs.file(manifestFile)
doLast {
logger.lifecycle(":downloading minecraft versions manifest")
FileUtils.copyURLToFile(new URL("https://launchermeta.mojang.com/mc/game/version_manifest.json"), manifestFile)
}
}
def getManifestVersion(File manifestFile, String minecraft_version) {
def manifest = manifestFile.exists() ? new JsonSlurper().parseText(FileUtils.readFileToString(manifestFile)) : null
2019-11-07 06:38:33 -05:00
return manifest != null ? manifest.versions.stream().filter({
it.id.equals(minecraft_version)
}).findFirst() : java.util.Optional.empty()
}
task downloadWantedVersionManifest(dependsOn: downloadVersionsManifest) {
group = setupGroup
def manifestFile = downloadVersionsManifest.outputs.files.singleFile
def manifestVersion = getManifestVersion(manifestFile, minecraft_version)
//have to grab the release time as there's a current timestamp on each element?!
inputs.property "releaseTime", manifestVersion.isPresent() ? manifestVersion.get().releaseTime : -1
outputs.file versionFile
doLast {
2019-11-07 06:38:33 -05:00
manifestVersion = getManifestVersion(manifestFile, minecraft_version)
//nb need to re-read here in case it didn't exist before
if (manifestVersion.isPresent() || versionFile.exists()) {
if (manifestVersion.isPresent()) {
FileUtils.copyURLToFile(new URL(manifestVersion.get().url), versionFile)
}
} else {
throw new RuntimeException("No version data for Minecraft version ${minecraft_version}")
}
}
}
2016-08-17 15:23:28 -04:00
task downloadMcJars(dependsOn: downloadWantedVersionManifest) {
group = setupGroup
inputs.files versionFile
2016-08-17 15:23:28 -04:00
outputs.files(clientJar, serverJar)
2016-08-17 15:23:28 -04:00
outputs.upToDateWhen {
2016-08-17 15:23:28 -04:00
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile))
return clientJar.exists() && serverJar.exists() && validateChecksum(clientJar, version.downloads.client.sha1) && validateChecksum(serverJar, version.downloads.server.sha1)
}
doLast {
if (!versionFile.exists()) {
throw new RuntimeException("Can't download the jars without the ${versionFile.name} file!")
}
2016-08-17 15:23:28 -04:00
//reload in case it changed
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile))
logger.lifecycle(":downloading minecraft jars")
2016-08-17 15:23:28 -04:00
download {
src new URL(version.downloads.client.url)
dest clientJar
overwrite false
2016-08-17 15:23:28 -04:00
}
download {
src new URL(version.downloads.server.url)
dest serverJar
overwrite false
2016-08-17 15:23:28 -04:00
}
}
}
task downloadIntermediary(type: Download) {
2019-06-28 17:55:20 -04:00
group = buildMappingGroup
def url = "https://github.com/FabricMC/intermediary/raw/master/mappings/${minecraft_version}.tiny"
2019-11-07 13:15:42 -05:00
src com.google.common.net.UrlEscapers.urlFragmentEscaper().escape(url)
dest new File(cacheFilesMinecraft, "${minecraft_version}-intermediary.tiny")
2019-06-28 17:55:20 -04:00
}
task downloadIntermediaryV2(type: Download) {
group = buildMappingGroup
def url = "https://maven.fabricmc.net/net/fabricmc/intermediary/${minecraft_version}/intermediary-${minecraft_version}-v2.jar"
src com.google.common.net.UrlEscapers.urlFragmentEscaper().escape(url)
dest new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-v2.jar")
}
task extractIntermediaryV2(dependsOn: downloadIntermediaryV2, type: Copy) {
def output = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-v2.tiny")
from({ zipTree(downloadIntermediaryV2.dest) }) {
include 'mappings/mappings.tiny'
rename 'mappings.tiny', "../${output.name}"
}
into output.parentFile
}
task mergeJars(dependsOn: downloadMcJars) {
group = setupGroup
inputs.files downloadMcJars.outputs.files.files
outputs.file(mergedFile)
2016-08-17 15:23:28 -04:00
doLast {
logger.lifecycle(":merging jars")
2019-11-07 06:38:33 -05:00
def client = inputs.files.files.find { it.name.endsWith("-client.jar") }
def server = inputs.files.files.find { it.name.endsWith("-server.jar") }
2018-12-22 06:56:35 -05:00
def merged = mergedFile
2016-08-17 15:23:28 -04:00
2019-11-07 06:38:33 -05:00
if (merged.exists()) {
2019-01-16 13:37:56 -05:00
return
}
2016-08-17 15:23:28 -04:00
def jarMerger = new JarMerger(client, server, merged)
jarMerger.merge()
jarMerger.close()
}
}
2019-06-28 17:55:20 -04:00
task downloadMcLibs(dependsOn: downloadWantedVersionManifest) {
group = setupGroup
inputs.files versionFile
2019-07-02 17:36:55 -04:00
outputs.dir(libraries)
2019-06-28 17:55:20 -04:00
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2016-08-17 15:23:28 -04:00
doLast {
2019-06-28 17:55:20 -04:00
if (!versionFile.exists()) {
throw new RuntimeException("Can't download the jars without the ${versionFile.name} file!")
}
def version = new JsonSlurper().parseText(FileUtils.readFileToString(versionFile, StandardCharsets.UTF_8))
2019-06-28 17:55:20 -04:00
logger.lifecycle(":downloading minecraft libraries")
if (!libraries.exists()) {
libraries.mkdirs()
}
version.libraries.each {
def downloadUrl = it.downloads.artifact.url
download {
src downloadUrl
dest new File(libraries, downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1))
overwrite false
}
project.dependencies.add("decompileClasspath", it.name)
}
2016-08-17 15:23:28 -04:00
}
}
2016-09-08 18:42:45 -04:00
task invertIntermediary(dependsOn: downloadIntermediary, type: FileOutput) {
group = buildMappingGroup
def v1Input = downloadIntermediary.dest
2016-09-21 08:52:54 -04:00
2019-11-07 06:38:33 -05:00
output = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-inverted.tiny")
outputs.file(output)
2019-06-28 17:55:20 -04:00
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2019-06-28 17:55:20 -04:00
doLast {
logger.lifecycle(":building inverted intermediary")
2019-11-07 06:38:33 -05:00
String[] v1Args = [
v1Input.getAbsolutePath(),
output.getAbsolutePath(),
"intermediary", "official"
]
2019-11-07 06:38:33 -05:00
new CommandReorderTiny().run(v1Args)
}
}
task invertIntermediaryv2(dependsOn: extractIntermediaryV2, type: FileOutput) {
group = buildMappingGroup
def v2Input = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-v2.tiny")
output = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-inverted-v2.tiny")
outputs.file(output)
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":building inverted intermediary v2")
String[] v2Args = [
v2Input.getAbsolutePath(),
output.getAbsolutePath(),
"intermediary", "official"
]
new CommandReorderTinyV2().run(v2Args)
}
}
task patchIntermediary(dependsOn: [mergeJars, downloadIntermediary]) {
group = buildMappingGroup
def intermediaryTinyInput = downloadIntermediary.outputs.files.singleFile
2019-04-18 17:22:36 -04:00
def outputFile = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-full.tiny")
outputs.file(outputFile)
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2019-04-18 17:22:36 -04:00
doLast {
logger.lifecycle(":patching intermediary")
String[] args = [
2019-11-07 06:38:33 -05:00
mergedFile.getAbsolutePath(),
intermediaryTinyInput.getAbsolutePath(),
outputFile.getAbsolutePath(),
"--writeAll"
2019-04-18 17:22:36 -04:00
]
new CommandRewriteIntermediary().run(args)
}
}
task mapIntermediaryJar(dependsOn: [downloadMcLibs, downloadIntermediary, mergeJars]) {
2019-06-28 17:55:20 -04:00
group = mapJarGroup
inputs.files downloadMcLibs.outputs.files.files
outputs.file(intermediaryJar)
//Force the task to always run
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2019-06-28 17:55:20 -04:00
doLast {
logger.lifecycle(":mapping minecraft to intermediary")
def tinyInput = downloadIntermediary.dest
2019-06-28 17:55:20 -04:00
mapJar(intermediaryJar, mergedFile, tinyInput, libraries, "official", "intermediary")
}
}
task yarnUnpicked(dependsOn: "unpickIntermediaryJar") {
2019-06-28 17:55:20 -04:00
group = yarnGroup
doLast {
ant.setLifecycleLogLevel "WARN"
ant.java(
classname: 'cuchaz.enigma.gui.Main',
classpath: configurations.enigmaRuntime.asPath,
fork: true,
spawn: true
) {
jvmarg(value: "-Xmx2048m")
arg(value: '-jar')
arg(value: unpickedJar.getAbsolutePath())
arg(value: '-mappings')
arg(value: mappingsDir.getAbsolutePath())
arg(value: '-profile')
arg(value: 'enigma_profile.json')
}
}
2019-06-28 17:55:20 -04:00
}
task yarn(dependsOn: mapIntermediaryJar) {
2019-06-28 17:55:20 -04:00
group = yarnGroup
doLast {
ant.setLifecycleLogLevel "WARN"
ant.java(
2020-06-03 14:47:17 -04:00
classname: 'cuchaz.enigma.gui.Main',
2019-11-07 06:38:33 -05:00
classpath: configurations.enigmaRuntime.asPath,
fork: true,
spawn: true
2019-06-28 17:55:20 -04:00
) {
jvmarg(value: "-Xmx2048m")
arg(value: '-jar')
arg(value: intermediaryJar.getAbsolutePath())
arg(value: '-mappings')
arg(value: mappingsDir.getAbsolutePath())
arg(value: '-profile')
arg(value: 'enigma_profile.json')
}
}
}
task checkMappings(dependsOn: mapIntermediaryJar) {
2019-06-28 17:55:20 -04:00
group = buildMappingGroup
inputs.dir mappingsDir
doLast {
logger.lifecycle(":checking mappings")
String[] args = [
intermediaryJar.getAbsolutePath(),
2019-11-07 06:38:33 -05:00
mappingsDir.getAbsolutePath()
2019-06-28 17:55:20 -04:00
]
try {
new CheckMappingsCommand().run(args)
} catch (IllegalStateException ignored) {
// just print, don't fail the task
}
2019-06-28 17:55:20 -04:00
}
}
task buildYarnTiny(dependsOn: mapIntermediaryJar, type: WithV2FileOutput) {
group = buildMappingGroup
inputs.dir mappingsDir
if (!libs.exists()) {
libs.mkdirs()
}
2018-10-31 09:05:19 -04:00
2019-11-07 06:38:33 -05:00
v1Output = new File(tempDir, "yarn-mappings.tiny")
v2Output = new File(tempDir, "yarn-mappings-v2.tiny")
outputs.upToDateWhen { false }
2018-10-31 09:05:19 -04:00
doLast {
logger.lifecycle(":generating tiny mappings")
new MapSpecializedMethodsCommand().run(
intermediaryJar.getAbsolutePath(),
"enigma",
mappingsDir.getAbsolutePath(),
"tinyv2:intermediary:named",
v2Output.getAbsolutePath()
)
new ConvertMappingsCommand().run(
"tinyv2",
v2Output.getAbsolutePath(),
"tiny:intermediary:named",
v1Output.getAbsolutePath())
2018-10-31 09:05:19 -04:00
}
}
2019-06-28 17:55:20 -04:00
task mergeTiny(dependsOn: ["buildYarnTiny", "invertIntermediary"], type: FileOutput) {
group = buildMappingGroup
2019-11-07 06:38:33 -05:00
def yarnTinyInput = buildYarnTiny.v1Output
def intermediaryTinyInput = invertIntermediary.output
2018-10-31 09:05:19 -04:00
def unorderedResultMappings = new File(tempDir, "mappings-unordered.tiny")
2019-11-07 06:38:33 -05:00
output = new File(tempDir, "mappings.tiny")
outputs.file(output)
2018-10-31 09:05:19 -04:00
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2018-10-31 09:05:19 -04:00
doLast {
2018-12-09 16:14:34 -05:00
logger.lifecycle(":merging yarn and intermediary")
2018-10-31 09:05:19 -04:00
String[] args = [
2019-11-07 06:38:33 -05:00
intermediaryTinyInput.getAbsolutePath(),
yarnTinyInput.getAbsolutePath(),
unorderedResultMappings.getAbsolutePath(),
"intermediary",
"official"
2018-10-31 09:05:19 -04:00
]
new CommandMergeTiny().run(args)
logger.lifecycle(":reordering merged intermediary")
String[] args2 = [
2019-11-07 06:38:33 -05:00
unorderedResultMappings.getAbsolutePath(),
output.getAbsolutePath(),
"official", "intermediary", "named"
]
new CommandReorderTiny().run(args2)
2018-10-31 09:05:19 -04:00
}
}
2019-11-07 06:38:33 -05:00
task tinyJar(type: Jar, dependsOn: mergeTiny) {
group = buildMappingGroup
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
archiveFileName = "yarn-${yarnVersion}.jar"
destinationDirectory.set(file("build/libs"))
2018-11-02 12:02:21 -04:00
classifier = ""
2019-11-07 06:38:33 -05:00
from(mergeTiny.output) {
2018-11-02 11:07:46 -04:00
rename { "mappings/mappings.tiny" }
}
}
2019-11-07 06:38:33 -05:00
task compressTiny(dependsOn: [tinyJar, mergeTiny], type: FileOutput) {
group = buildMappingGroup
2018-12-09 16:14:34 -05:00
def outputFile = new File(libs, "yarn-tiny-${yarnVersion}.gz")
2018-10-31 09:05:19 -04:00
outputs.file(outputFile)
2019-11-07 06:38:33 -05:00
output = outputFile
2018-10-31 09:05:19 -04:00
2019-11-07 06:38:33 -05:00
def inputFile = mergeTiny.output
2019-11-07 06:38:33 -05:00
outputs.upToDateWhen { false }
2018-10-31 09:05:19 -04:00
doLast {
logger.lifecycle(":compressing tiny mappings")
def buffer = new byte[1024]
def fileOutputStream = new FileOutputStream(outputFile)
def outputStream = new GZIPOutputStream(fileOutputStream)
def fileInputStream = new FileInputStream(inputFile)
def length
while ((length = fileInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length)
}
fileInputStream.close()
outputStream.finish()
outputStream.close()
}
}
2016-09-21 08:52:54 -04:00
2018-11-02 12:17:55 -04:00
clean.doFirst {
delete tempDir, cacheFilesMinecraft
}
tasks.build.dependsOn "compressTiny","tinyJar","v2UnmergedYarnJar", "v2MergedYarnJar"
task exportMappingsOfficial(dependsOn: downloadIntermediary) {
def composeInput = downloadIntermediary.dest
2018-10-27 10:37:37 -04:00
doLast {
2019-06-28 17:55:20 -04:00
logger.lifecycle(":exporting mappings")
String[] args = [
2019-11-07 06:38:33 -05:00
"tiny",
composeInput.getAbsolutePath(),
"enigma",
file("mappings/").getAbsolutePath(),
"enigma",
file("mappings_official/").getAbsolutePath(),
"right"
2019-06-28 17:55:20 -04:00
]
new ComposeMappingsCommand().run(args)
}
}
2019-11-07 06:38:33 -05:00
task importMappingsOfficial(dependsOn: invertIntermediary) {
def composeInput = invertIntermediary.output
doLast {
2019-06-28 17:55:20 -04:00
logger.lifecycle(":importing mappings")
String[] args = [
2019-11-07 06:38:33 -05:00
"tiny",
composeInput.getAbsolutePath(),
"enigma",
file("mappings_official/").getAbsolutePath(),
"enigma",
file("mappings/").getAbsolutePath(),
"right"
2019-06-28 17:55:20 -04:00
]
2019-06-28 17:55:20 -04:00
new ComposeMappingsCommand().run(args)
}
}
2018-10-30 07:29:43 -04:00
task buildTinyWithEnum(dependsOn: "mergeTiny", type: FileOutput) {
group = buildMappingGroup
2019-11-07 06:38:33 -05:00
def noEnum = mergeTiny.output
output = new File(tempDir, "named-with-enum.tiny")
2019-11-07 06:38:33 -05:00
outputs.file(output)
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":seeking auto-mappable fields")
String[] argsPropose = [
2019-11-07 06:38:33 -05:00
mergedFile.getAbsolutePath(), // must use official jar
noEnum.getAbsolutePath(),
output.getAbsolutePath()
]
new CommandProposeFieldNames().run(argsPropose)
}
}
task mapNamedJar(dependsOn: ["mergeV2", "unpickIntermediaryJar"]) {
group = mapJarGroup
inputs.files downloadMcLibs.outputs.files.files
outputs.file(namedJar)
//Force the task to always run
outputs.upToDateWhen { false }
def jsrToJetbrains = [
"javax/annotation/Nullable": "org/jetbrains/annotations/Nullable",
"javax/annotation/Nonnull": "org/jetbrains/annotations/NotNull",
"javax/annotation/concurrent/Immutable": "org/jetbrains/annotations/Unmodifiable"
]
doLast {
logger.lifecycle(":mapping minecraft to named")
mapJar(namedJar, unpickedJar, mergeV2.output, libraries, "intermediary", "named") {
it.withMappings { out ->
jsrToJetbrains.each { e ->
out.acceptClass e.key, e.value
}
}
}
2019-11-07 06:38:33 -05:00
}
}
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Reader
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Writer
import daomephsta.unpick.constantmappers.datadriven.parser.v2.UnpickV2Remapper
import daomephsta.unpick.constantmappers.datadriven.parser.FieldKey
import daomephsta.unpick.constantmappers.datadriven.parser.MethodKey
import net.fabricmc.mapping.tree.TinyMappingFactory
// Merge all of the unpick definitions into a single file to be shipped
task combineUnpickDefinitions(type : FileOutput) {
output = new File(tempDir, "definitions.unpick")
outputs.upToDateWhen { false }
group "unpick"
doFirst {
output.delete()
}
doLast {
def writer = new UnpickV2Writer()
file("unpick-definitions").eachFile {
if (!it.name.endsWith(".unpick")) {
return
}
it.withInputStream {
new UnpickV2Reader(it).withCloseable {
it.accept(writer)
}
}
}
output.text = writer.output
}
}
task remapUnpickDefinitionsIntermediary(type : FileOutputInput, dependsOn: [combineUnpickDefinitions, buildYarnTiny]) {
output = new File(tempDir, "intermediary-definitions.unpick")
input = combineUnpickDefinitions.output
File mappingsInput = buildYarnTiny.v2Output
outputs.upToDateWhen { false }
group "unpick"
doFirst {
output.delete()
}
doLast {
def classMappings = [:]
def methodMappings = [:]
def fieldMappings = [:]
mappingsInput.withReader {reader ->
def tinyTree = TinyMappingFactory.loadWithDetection(reader)
tinyTree.classes.each { classDef ->
classMappings.put(
classDef.getName("named"),
classDef.getName("intermediary")
)
classDef.methods.each { methodDef ->
methodMappings.put(
new MethodKey(
classDef.getName("named"),
methodDef.getName("named"),
methodDef.getDescriptor("named")
),
methodDef.getName("intermediary")
)
}
classDef.fields.forEach { fieldDef ->
fieldMappings.put(
new FieldKey(
classDef.getName("named"),
fieldDef.getName("named")
),
fieldDef.getName("intermediary")
)
}
}
}
input.withInputStream {
new UnpickV2Reader(it).withCloseable {reader ->
def writer = new UnpickV2Writer()
reader.accept(new UnpickV2Remapper(classMappings, methodMappings, fieldMappings, writer))
output.text = writer.output
}
}
}
}
task unpickIntermediaryJar(type: JavaExec, dependsOn: [mapIntermediaryJar, "constantsJar", remapUnpickDefinitionsIntermediary]) {
outputs.upToDateWhen { false }
group "unpick"
main "daomephsta.unpick.cli.Main"
systemProperty "java.util.logging.config.file", file('unpick-logging.properties')
classpath configurations.unpick
doFirst {
2021-03-26 13:57:15 -04:00
args intermediaryJar.absolutePath, unpickedJar.absolutePath, remapUnpickDefinitionsIntermediary.output.absolutePath, constantsJar.archiveFile.get().asFile.absolutePath
configurations.decompileClasspath.files.each {
args it.absolutePath
}
}
}
// Setup the build for the unpicked constants
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8"
if (JavaVersion.current().isJava9Compatible()) {
it.options.release = 8
}
}
sourceSets {
constants
packageDocs // package info files
}
license {
header file("HEADER")
sourceSets = [sourceSets.constants, sourceSets.packageDocs]
include '**/*.java'
}
task constantsJar(type: Jar) {
from sourceSets.constants.output
archiveClassifier = "constants"
}
task sourcesJar(type: Jar, dependsOn: classes) {
archiveClassifier = "sources"
from sourceSets.constants.allSource
}
compilePackageDocsJava {
it.options.encoding = "UTF-8"
it.options.release = 11
}
// Only build jars for package infos if we need to actually expose stuff like annotation in the future.
// Also need to downgrade java in that case!
build.dependsOn constantsJar
2019-11-07 06:38:33 -05:00
task insertAutoGeneratedEnumMappings(dependsOn : [buildYarnTiny,mapIntermediaryJar], type : FileOutput){
group = buildMappingGroup
def noEnumV2 = buildYarnTiny.v2Output
output = new File(tempDir, "unmerged-named-v2-with-enum.tiny")
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":seeking auto-mappable fields for unmerged mappings")
String[] argsProposeV2 = [
intermediaryJar.getAbsolutePath(), // must use intermediary jar
noEnumV2.getAbsolutePath(),
output.getAbsolutePath(),
"false" // don't replace existing names right now
2019-11-07 06:38:33 -05:00
]
new CommandProposeV2FieldNames().run(argsProposeV2)
}
}
task mergeV2(dependsOn: ["v2UnmergedYarnJar", "invertIntermediaryv2"], type: FileOutput) {
def mergedV2 = new File(tempDir, "merged-v2.tiny");
output = new File(tempDir, "merged-reordered-v2.tiny")
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":merging yarn and intermediary v2")
String[] args = [
invertIntermediaryv2.output.getAbsolutePath(),
insertAutoGeneratedEnumMappings.output.getAbsolutePath(),
mergedV2.getAbsolutePath(),
"intermediary",
"official"
]
new CommandMergeTinyV2().run(args)
//Reorder the mappings to match the output of loom
args = [
mergedV2.getAbsolutePath(),
output.getAbsolutePath(),
"official",
"intermediary",
"named"
]
new CommandReorderTinyV2().run(args)
}
}
task v2UnmergedYarnJar(dependsOn: [insertAutoGeneratedEnumMappings, combineUnpickDefinitions], type: Jar) {
2019-11-07 06:38:33 -05:00
def mappings = insertAutoGeneratedEnumMappings.output
group = "mapping build"
outputs.upToDateWhen { false }
archiveFileName = "yarn-${yarnVersion}-v2.jar"
2019-11-07 06:38:33 -05:00
from(file(mappings)) {
rename mappings.name, "mappings/mappings.tiny"
}
from(combineUnpickDefinitions.output) {
rename combineUnpickDefinitions.output.name, "extras/definitions.unpick"
}
from (file(unpickMetaFile)) {
expand version: project.unpick_version
rename unpickMetaFile.name, "extras/unpick.json"
}
destinationDirectory.set(file("build/libs"))
}
task v2MergedYarnJar(dependsOn: ["mergeV2"], type: Jar) {
def mappings = mergeV2.output
group = "mapping build"
outputs.upToDateWhen { false }
archiveFileName = "yarn-${yarnVersion}-mergedv2.jar"
from(file(mappings)) {
rename mappings.name, "mappings/mappings.tiny"
}
from(combineUnpickDefinitions.output) {
rename combineUnpickDefinitions.output.name, "extras/definitions.unpick"
}
from (file(unpickMetaFile)) {
expand version: project.unpick_version
rename unpickMetaFile.name, "extras/unpick.json"
}
destinationDirectory.set(file("build/libs"))
}
def fakeSourceDir = file(".gradle/temp/fakeSource")
task genFakeSource(type: JavaExec, dependsOn: ["mergeV2", "mapNamedJar"]) {
group = "javadoc generation"
outputs.upToDateWhen { false }
main "net.fabricmc.mappingpoet.Main"
classpath configurations.mappingPoet
// use merged v2 so we have all namespaces in jd
args mergeV2.output.getAbsolutePath(), namedJar.getAbsolutePath(), fakeSourceDir.getAbsolutePath(), libraries.getAbsolutePath()
doLast {
logger.lifecycle ":Fake source generated"
}
}
task decompileCFR(type: JavaExec, dependsOn: [mapNamedJar]) {
doFirst {
classpath = configurations.decompileClasspath
}
main = "org.benf.cfr.reader.Main"
args namedJar.getAbsolutePath(), "--outputdir", file("namedSrc").absolutePath
doFirst {
file("namedSrc").deleteDir()
}
}
javadoc {
dependsOn genFakeSource
dependsOn downloadMcLibs
group = "javadoc generation"
outputs.upToDateWhen { false }
def mappingPoetJar = project.provider { zipTree configurations.mappingPoetJar.singleFile }
failOnError = false
// verbose = true // enable to debug
options {
// verbose() // enable to debug
source = "11"
encoding = 'UTF-8'
charSet = 'UTF-8'
memberLevel = JavadocMemberLevel.PRIVATE
splitIndex true
tags(
'apiNote:a:API Note:',
'implSpec:a:Implementation Requirements:',
'implNote:a:Implementation Note:'
)
taglets "net.fabricmc.mappingpoet.jd.MappingTaglet"
// taglet path, header, extra stylesheet settings deferred
it.use()
addBooleanOption "-allow-script-in-comments", true
links(
'https://guava.dev/releases/21.0/api/docs/',
'https://www.javadoc.io/doc/com.google.code.gson/gson/2.8.0/',
'https://logging.apache.org/log4j/2.x/log4j-api/apidocs/',
"https://javadoc.io/doc/org.jetbrains/annotations/${project.jetbrains_annotations_version}/",
'https://www.javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/',
'https://javadoc.lwjgl.org/',
'https://fastutil.di.unimi.it/docs/',
'https://netty.io/4.1/api/',
'https://commons.apache.org/proper/commons-logging/javadocs/api-1.1.3/',
'https://commons.apache.org/proper/commons-lang/javadocs/api-3.5',
'https://commons.apache.org/proper/commons-io/javadocs/api-2.5',
'https://commons.apache.org/proper/commons-codec/archives/1.10/apidocs',
'https://commons.apache.org/proper/commons-compress/javadocs/api-1.8.1/',
"https://maven.fabricmc.net/docs/fabric-loader-${project.fabric_loader_version}/",
"https://docs.oracle.com/en/java/javase/11/docs/api/"
// Need to add loader jd publication for env annotations!
)
// https://docs.oracle.com/en/java/javase/15/docs/specs/man/javadoc.html#additional-options-provided-by-the-standard-doclet
addBooleanOption 'Xdoclint:html', true
addBooleanOption 'Xdoclint:syntax', true
addBooleanOption 'Xdoclint:reference', true
addBooleanOption 'Xdoclint:accessibility', true
}
source fileTree(fakeSourceDir) + sourceSets.constants.allJava + sourceSets.packageDocs.allJava
classpath = configurations.javadocClasspath.plus downloadMcLibs.outputs.files.asFileTree
finalizedBy {
task copyCopyOnClickScript(type: Copy) {
from mappingPoetJar
include "copy_on_click.js"
into javadoc.outputDirectory
}
}
doFirst {
// lazy setting
options {
tagletPath configurations.mappingPoet.files.toList()
header mappingPoetJar.get().filter { it.name == 'javadoc_header.txt' }.singleFile.readLines()[0] // cannot include line breaks
addFileOption "-add-stylesheet", mappingPoetJar.get().filter { it.name == 'forms.css' }.singleFile
}
}
}
task javadocJar(type: Jar, dependsOn: ["javadoc"]) {
group = "javadoc generation"
from javadoc.destinationDir
archiveVersion.set yarnVersion
archiveClassifier = 'javadoc'
}
generatePackageInfoMappings {
dependsOn mapIntermediaryJar
inputJar = intermediaryJar
packageName = "net/minecraft/unused/packageinfo/"
outputDir = file("mappings/net/minecraft/unused/packageinfo")
}
javadocLint {
group = "javadoc generation"
mappingDirectory = file("mappings")
}
check.dependsOn javadocLint
2018-10-30 07:29:43 -04:00
publishing {
publications {
maven(MavenPublication) {
groupId 'net.fabricmc'
2018-12-09 16:14:34 -05:00
artifactId "yarn"
version yarnVersion
2018-10-30 07:29:43 -04:00
2019-11-07 06:38:33 -05:00
artifact(compressTiny.output) {
2018-10-30 07:29:43 -04:00
classifier "tiny"
builtBy compressTiny
2018-10-30 07:29:43 -04:00
}
2019-11-07 06:38:33 -05:00
artifact(tinyJar)
artifact(v2UnmergedYarnJar) {
classifier "v2"
}
artifact(v2MergedYarnJar) {
classifier "mergedv2"
}
artifact(constantsJar) {
classifier "constants"
}
artifact sourcesJar
artifact javadocJar
2018-10-30 07:29:43 -04:00
}
2019-11-07 06:38:33 -05:00
2018-10-30 07:29:43 -04:00
}
repositories {
2020-11-06 18:33:17 -05:00
if (ENV.MAVEN_URL) {
maven {
url ENV.MAVEN_URL
2018-10-30 07:29:43 -04:00
credentials {
2020-11-06 18:33:17 -05:00
username ENV.MAVEN_USERNAME
password ENV.MAVEN_PASSWORD
2018-10-30 07:29:43 -04:00
}
}
}
}
}
void mapJar(File output, File input, File mappings, File libraries, String from, String to,
Action<TinyRemapper.Builder> action = { }) {
if (output.exists()) {
output.delete()
}
def remapperBuilder = TinyRemapper.newRemapper()
2019-11-07 06:38:33 -05:00
.withMappings(TinyUtils.createTinyMappingProvider(mappings.toPath(), from, to))
.renameInvalidLocals(true)
.rebuildSourceFilenames(true)
action.execute(remapperBuilder)
def remapper = remapperBuilder
2019-11-07 06:38:33 -05:00
.build()
try {
def outputConsumer = new OutputConsumerPath(output.toPath())
outputConsumer.addNonClassFiles(input.toPath())
remapper.readInputs(input.toPath())
2019-11-07 06:38:33 -05:00
libraries.eachFileRecurse(FileType.FILES) { file ->
remapper.readClassPath(file.toPath())
}
remapper.apply(outputConsumer)
outputConsumer.close()
2019-01-16 13:37:56 -05:00
remapper.finish()
} catch (Exception e) {
2019-01-16 13:37:56 -05:00
remapper.finish()
throw new RuntimeException("Failed to remap jar", e)
}
}
2018-10-30 07:29:43 -04:00
class FileOutput extends DefaultTask {
2019-11-07 06:38:33 -05:00
@OutputFile
File output
}
2019-11-07 06:38:33 -05:00
class FileOutputInput extends DefaultTask {
@InputFile
File input
@OutputFile
File output
}
2019-11-07 06:38:33 -05:00
class WithV2FileOutput extends DefaultTask {
@OutputFile
File v1Output
@OutputFile
File v2Output
2020-03-20 18:57:01 -04:00
}