yarn/build.gradle

601 lines
16 KiB
Groovy
Raw Normal View History

2016-08-17 15:23:28 -04:00
buildscript {
repositories {
jcenter()
maven {
2019-06-28 17:55:20 -04:00
name "Fabric Repository"
url 'https://maven.fabricmc.net'
}
2019-06-28 17:55:20 -04:00
mavenLocal()
}
dependencies {
2019-09-12 09:25:30 -04:00
classpath "cuchaz:enigma:0.14.2.134"
classpath "net.fabricmc:stitch:0.2.1.61"
2019-06-13 03:39:42 -04:00
classpath "commons-io:commons-io:2.6"
classpath "com.google.guava:guava:28.0-jre"
classpath 'de.undercouch:gradle-download-task:3.4.3'
classpath 'net.fabricmc:tiny-remapper:+'
}
2016-08-17 15:23:28 -04:00
}
plugins {
id 'de.undercouch.download' version '3.4.3'
id 'maven'
id 'maven-publish'
}
2019-10-30 12:28:24 -04:00
def minecraft_version = "19w44a"
2016-09-09 08:47:32 -04:00
def ENV = System.getenv()
// Fetch build number from Jenkins
def build_number = ENV.BUILD_NUMBER ?: "local"
2019-04-10 12:20:44 -04:00
def yarnVersion = "${minecraft_version}+build.$build_number"
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'
}
}
configurations {
enigmaRuntime {
resolutionStrategy {
cacheDynamicVersionsFor 0, "seconds"
cacheChangingModulesFor 0, "seconds"
}
}
}
dependencies {
enigmaRuntime "net.fabricmc:stitch:0.2.1.61"
2019-09-12 09:25:30 -04:00
enigmaRuntime "cuchaz:enigma:0.14.2.134:all"
}
def setupGroup = "jar setup"
def yarnGroup = "yarn"
def buildMappingGroup = "mapping build"
def mapJarGroup = "jar mapping"
def mappingsDir = file("mappings")
2019-06-28 17:55:20 -04:00
def mappingsExportOfficialDir = file("mappings_official")
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 yarnJar = file("${minecraft_version}-yarn.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/")
import cuchaz.enigma.command.CheckMappingsCommand
2019-06-28 17:55:20 -04:00
import cuchaz.enigma.command.ComposeMappingsCommand
import cuchaz.enigma.command.ConvertMappingsCommand
2016-08-17 15:23:28 -04:00
import com.google.common.hash.Hashing
import com.google.common.io.Files
import com.google.common.net.UrlEscapers
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.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) {
def hash = 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
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 {
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
if (!clientJar.exists() || !validateChecksum(clientJar, version.downloads.client.sha1)) {
logger.lifecycle(":downloading minecraft client")
FileUtils.copyURLToFile(new URL(version.downloads.client.url), clientJar)
}
if (!serverJar.exists() || !validateChecksum(serverJar, version.downloads.server.sha1)) {
logger.lifecycle(":downloading minecraft server")
FileUtils.copyURLToFile(new URL(version.downloads.server.url), serverJar)
}
}
}
2019-06-28 17:55:20 -04:00
task downloadIntermediary(type: Download){
group = buildMappingGroup
def url = "https://github.com/FabricMC/intermediary/raw/master/mappings/${minecraft_version}.tiny"
src UrlEscapers.urlFragmentEscaper().escape(url)
dest new File(cacheFilesMinecraft, "${minecraft_version}-intermediary.tiny")
}
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")
2018-12-22 06:56:35 -05:00
def client = inputs.files.files.find {it.name.endsWith("-client.jar")}
def server = inputs.files.files.find {it.name.endsWith("-server.jar")}
def merged = mergedFile
2016-08-17 15:23:28 -04:00
2019-01-16 13:37:56 -05:00
if(merged.exists()){
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
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
}
}
2016-08-17 15:23:28 -04:00
}
}
2016-09-08 18:42:45 -04:00
2019-06-28 17:55:20 -04:00
task invertIntermediary(dependsOn: ["downloadIntermediary"], type: FileOutput) {
group = buildMappingGroup
2019-06-28 17:55:20 -04:00
def inputFile = downloadIntermediary.dest
2016-09-21 08:52:54 -04:00
2019-06-28 17:55:20 -04:00
def outputFile = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-inverted.tiny")
outputs.file(outputFile)
fileOutput = outputFile
outputs.upToDateWhen {false}
2019-06-28 17:55:20 -04:00
doLast {
logger.lifecycle(":building inverted intermediary")
String[] args = [
2019-06-28 17:55:20 -04:00
inputFile.getAbsolutePath(),
outputFile.getAbsolutePath(),
"intermediary", "official"
]
new CommandReorderTiny().run(args)
}
}
2019-04-18 17:22:36 -04:00
task patchIntermediary(dependsOn: ["mergeJars", "downloadIntermediary"], type: FileOutput) {
group = buildMappingGroup
2019-04-18 17:22:36 -04:00
def intermediaryTinyInput = downloadIntermediary.dest
def outputFile = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary-full.tiny")
outputs.file(outputFile)
fileOutput = outputFile
outputs.upToDateWhen {false}
2019-04-18 17:22:36 -04:00
doLast {
logger.lifecycle(":patching intermediary")
String[] args = [
mergedFile.getAbsolutePath(),
intermediaryTinyInput.getAbsolutePath(),
outputFile.getAbsolutePath(),
"--writeAll"
]
new CommandRewriteIntermediary().run(args)
}
}
2019-06-28 17:55:20 -04:00
task mapIntermediaryJar(dependsOn: [downloadMcLibs, downloadIntermediary, mergeJars]) {
group = mapJarGroup
inputs.files downloadMcLibs.outputs.files.files
outputs.file(intermediaryJar)
//Force the task to always run
outputs.upToDateWhen {false}
doLast {
logger.lifecycle(":mapping minecraft to intermediary")
def tinyInput = new File(cacheFilesMinecraft, "${minecraft_version}-intermediary.tiny")
mapJar(intermediaryJar, mergedFile, tinyInput, libraries, "official", "intermediary")
}
}
task setupYarn(dependsOn: mapIntermediaryJar) {
group = yarnGroup
}
task yarn(dependsOn: setupYarn) {
group = yarnGroup
doLast {
ant.setLifecycleLogLevel "WARN"
ant.java(
classname: 'cuchaz.enigma.Main',
classpath: configurations.enigmaRuntime.asPath,
fork: true,
spawn: true
) {
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 {
group = buildMappingGroup
inputs.dir mappingsDir
doLast {
logger.lifecycle(":checking mappings")
String[] args = [
mergedFile.getAbsolutePath(),
mappingsDir.getAbsolutePath()
]
new CheckMappingsCommand().run(args)
}
}
task buildYarnTiny(dependsOn: "mergeJars", type: FileOutput) {
group = buildMappingGroup
inputs.dir mappingsDir
if (!libs.exists()) {
libs.mkdirs()
}
2018-10-31 09:05:19 -04:00
2018-12-09 16:14:34 -05:00
def yarnTiny = new File(tempDir, "yarn-mappings.tiny")
fileOutput = yarnTiny
2018-10-31 09:05:19 -04:00
outputs.upToDateWhen {false}
2018-10-31 09:05:19 -04:00
doLast {
logger.lifecycle(":generating tiny mappings")
String[] args = [
"enigma",
mappingsDir.getAbsolutePath(),
2019-06-28 17:55:20 -04:00
"tiny:intermediary:named",
yarnTiny.getAbsolutePath()
]
new ConvertMappingsCommand().run(args)
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
2018-12-09 16:14:34 -05:00
def yarnTinyInput = buildYarnTiny.fileOutput
2019-06-28 17:55:20 -04:00
def intermediaryTinyInput = invertIntermediary.fileOutput
2018-10-31 09:05:19 -04:00
def unorderedResultMappings = new File(tempDir, "mappings-unordered.tiny")
def resultMappings = new File(tempDir, "mappings.tiny")
outputs.file(resultMappings)
fileOutput = resultMappings
2018-10-31 09:05:19 -04: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 = [
intermediaryTinyInput.getAbsolutePath(),
yarnTinyInput.getAbsolutePath(),
unorderedResultMappings.getAbsolutePath(),
2018-11-02 12:17:55 -04:00
"intermediary",
"official"
2018-10-31 09:05:19 -04:00
]
new CommandMergeTiny().run(args)
logger.lifecycle(":reordering merged intermediary")
String[] args2 = [
unorderedResultMappings.getAbsolutePath(),
resultMappings.getAbsolutePath(),
"official", "intermediary", "named"
]
new CommandReorderTiny().run(args2)
2018-10-31 09:05:19 -04:00
}
}
2018-11-02 11:07:46 -04:00
task tinyJar(type: Jar, dependsOn: "mergeTiny") {
group = buildMappingGroup
outputs.upToDateWhen {false}
2018-12-09 16:14:34 -05:00
archiveName = "yarn-${yarnVersion}.jar"
2018-11-02 11:07:46 -04:00
destinationDir(file("build/libs"))
2018-11-02 12:02:21 -04:00
classifier = ""
2018-11-02 11:07:46 -04:00
from (mergeTiny.fileOutput) {
rename { "mappings/mappings.tiny" }
}
}
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)
fileOutput = outputFile
def inputFile = mergeTiny.fileOutput
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
}
2018-10-31 09:05:19 -04:00
tasks.build.dependsOn "compressTiny"
2018-11-02 11:07:46 -04:00
tasks.build.dependsOn "tinyJar"
2019-06-28 17:55:20 -04:00
task mapYarnJar(dependsOn: ["compressTiny", "mapIntermediaryJar"]) {
group = mapJarGroup
inputs.files downloadMcLibs.outputs.files.files
outputs.file(yarnJar)
2016-09-21 08:52:54 -04:00
2019-06-28 17:55:20 -04:00
//Force the task to always run
outputs.upToDateWhen {false}
2016-09-21 08:52:54 -04:00
doLast {
2019-06-28 17:55:20 -04:00
logger.lifecycle(":mapping minecraft to yarn")
2019-06-28 17:55:20 -04:00
def tinyInput = new File("build/libs/yarn-tiny-${yarnVersion}.gz")
mapJar(yarnJar, intermediaryJar, tinyInput, libraries, "intermediary", "named")
}
2016-09-21 08:52:54 -04:00
}
2019-06-28 17:55:20 -04:00
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 = [
"tiny",
composeInput.getAbsolutePath(),
"enigma",
file("mappings/").getAbsolutePath(),
"enigma",
file("mappings_official/").getAbsolutePath(),
"right"
]
new ComposeMappingsCommand().run(args)
}
}
2019-06-28 17:55:20 -04:00
task importMappingsOfficial(dependsOn: "invertIntermediary") {
def composeInput = invertIntermediary.fileOutput
doLast {
2019-06-28 17:55:20 -04:00
logger.lifecycle(":importing mappings")
String[] args = [
"tiny",
composeInput.getAbsolutePath(),
"enigma",
file("mappings_official/").getAbsolutePath(),
"enigma",
file("mappings/").getAbsolutePath(),
"right"
]
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
def noEnum = mergeTiny.fileOutput
def namedWithEnum = new File(tempDir, "named-with-enum.tiny")
fileOutput = namedWithEnum
2019-06-28 17:55:20 -04:00
outputs.file(namedWithEnum)
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":seeking auto-mappable fields")
String[] argsPropose = [
mergedFile.getAbsolutePath(), // must use official jar
noEnum.getAbsolutePath(),
namedWithEnum.getAbsolutePath()
]
new CommandProposeFieldNames().run(argsPropose)
}
}
task mapNamedJar(dependsOn: [buildTinyWithEnum, mapIntermediaryJar]) {
group = mapJarGroup
inputs.files downloadMcLibs.outputs.files.files
outputs.file(namedJar)
//Force the task to always run
outputs.upToDateWhen { false }
doLast {
logger.lifecycle(":mapping minecraft to named")
mapJar(namedJar, intermediaryJar, buildTinyWithEnum.fileOutput, libraries, "intermediary", "named")
}
}
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
2018-10-31 09:05:19 -04:00
artifact (compressTiny.fileOutput) {
2018-10-30 07:29:43 -04:00
classifier "tiny"
builtBy compressTiny
2018-10-30 07:29:43 -04:00
}
2018-11-02 11:07:46 -04:00
artifact (tinyJar)
2018-10-30 07:29:43 -04:00
}
}
repositories {
maven {
url "http://mavenupload.modmuss50.me/"
if (project.hasProperty('mavenPass')) {
credentials {
username 'buildslave'
password project.getProperty('mavenPass')
}
}
}
}
}
void mapJar(File output, File input, File mappings, File libraries, String from, String to){
if (output.exists()) {
output.delete()
}
def remapper = TinyRemapper.newRemapper()
.withMappings(TinyUtils.createTinyMappingProvider(mappings.toPath(), from, to))
.renameInvalidLocals(true)
.rebuildSourceFilenames(true)
.build()
try {
def outputConsumer = new OutputConsumerPath(output.toPath())
outputConsumer.addNonClassFiles(input.toPath())
remapper.readInputs(input.toPath())
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 {
@OutputFile File fileOutput
}