Files
ReplayModCinematic/versions/common.gradle

343 lines
12 KiB
Groovy

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.ow2.asm:asm:6.0'
}
// This and calls to it should really also be handled by the gradle/reprod/init.gradle script
// but apparently there's no sane way to do that for external scripts in gradle :(
def convertRepoToHttp = { repo ->
if (repo instanceof MavenArtifactRepository && repo.url.toString().startsWith('https://')) {
URL url = repo.url.toURL()
repo.url = new URL("http", url.getHost(), url.getPort(), url.getFile()).toURI()
}
}
if (System.getenv('REPRODUCIBLE_BUILD') == '1') repositories.all convertRepoToHttp
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = 1.8
targetCompatibility = 1.8
afterEvaluate {
def gitVer = gitDescribe()
if (gitVer.startsWith('1.12.2-')) gitVer = gitVer.substring('1.12.2-'.length()) // until the first proper version
version = project.minecraft.version + '-' + gitVer
}
group= "com.replaymod"
archivesBaseName = "replaymod"
minecraft {
coreMod = 'com.replaymod.core.LoadingPlugin'
runDir = "../../eclipse"
}
afterEvaluate {
minecraft.replace '@MOD_VERSION@', project.version
// Includes intentional whitespace to stop Forge from declaring the mod to be compatible with
// a newer srg-compatible MC version (that may be using a different protocol version)
minecraft.replace '@MC_VERSION@', "[ ${project.minecraft.version} ]"
}
repositories {
maven {
name = "SpongePowered Repo"
url = "http://repo.spongepowered.org/maven/"
}
maven { url 'https://jitpack.io' }
}
// And because gradle does *something*, this definition even needs to be duplicated instead of shared
def convertRepoToHttp = { repo ->
if (repo instanceof MavenArtifactRepository && repo.url.toString().startsWith('https://')) {
URL url = repo.url.toURL()
repo.url = new URL("http", url.getHost(), url.getPort(), url.getFile()).toURI()
}
}
if (System.getenv('REPRODUCIBLE_BUILD') == '1') repositories.all convertRepoToHttp
configurations {
shade
compile.extendsFrom shade
}
dependencies {
// compile 'com.github.SpongePowered:Mixin:404f5da' // 0.7.5-SNAPSHOT
// ^ mixin doesn't compile on jitpack, so we'll have to depend on the SNAPSHOT and build it manually for reprod
compile 'org.spongepowered:mixin:0.7.5-SNAPSHOT'
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
shade 'org.apache.commons:commons-exec:1.3'
def withoutGuava = { exclude group: 'com.google.guava', module: 'guava-jdk5' }
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0', withoutGuava
shade 'com.google.api-client:google-api-client-gson:1.20.0', withoutGuava
shade 'com.google.api-client:google-api-client-java6:1.20.0', withoutGuava
shade 'com.google.oauth-client:google-oauth-client-jetty:1.20.0'
shade 'org.aspectj:aspectjrt:1.8.2'
testCompile 'junit:junit:4.11'
}
if (project.name != 'core') {
apply from: '../preprocessor.gradle'
def preprocessedSrc = 'build/preprocessed/src'
def preprocessedRes = 'build/preprocessed/res'
def originalSrc = '../../src/main/java'
def originalRes = '../../src/main/resources'
def (major, minor, patch) = project.name.tokenize('.')
def mcVersion = "${major}${minor.padLeft(2, '0')}${(patch ?: '').padLeft(2, '0')}"
def vars = [MC: mcVersion as int]
sourceSets {
main.java.srcDir preprocessedSrc
main.resources.srcDir preprocessedRes
}
task preprocessJava {
inputs.dir(originalSrc)
outputs.dir(preprocessedSrc)
doLast {
project.convertTree(vars, originalSrc, preprocessedSrc)
}
}
task preprocessResources {
inputs.dir(originalRes)
outputs.dir(preprocessedRes)
doLast {
project.convertTree(vars, originalRes, preprocessedRes)
}
}
compileJava.dependsOn preprocessJava
processResources.dependsOn preprocessResources
[deobfMcMCP, deobfMcSRG].each { task ->
task.dependsOn preprocessResources
}
minecraft.accessTransformer preprocessedRes + '/META-INF/replaymod_at.cfg'
}
def shade = {files(
configurations.compile.findAll {it.name.startsWith 'mixin-'}
+ configurations.shade
)}
task configureRelocation() {
dependsOn tasks.jar
doLast {
def extraSrg = tasks.reobfJar.extraSrgLines
shade().filter { it.exists() }.collect {
def tree = it.isDirectory() ? fileTree(it) : zipTree(it)
def pkgs = [].toSet()
tree.visit { file ->
if (!file.directory && file.name.endsWith('.class')) {
def pkg = file.path.substring(0, file.path.lastIndexOf('/'))
if (!pkg.startsWith('com/replaymod')) {
pkgs << pkg
}
}
}
pkgs
}.flatten().unique().each { pkg ->
extraSrg << "PK: $pkg com/replaymod/lib/$pkg".toString()
}
}
}
tasks.reobfJar.dependsOn configureRelocation
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
dependsOn configurations.compile
dependsOn configurations.shade
def noticeDir = file("$buildDir/NOTICE")
doFirst {
noticeDir.deleteDir()
noticeDir.mkdirs()
shade().collect { it.isDirectory() ? fileTree(it) : zipTree(it) }.each {
it.matching { include '**/NOTICE*' }.each {
new File(noticeDir, 'NOTICE.txt') << it.getText('UTF-8') + '\n'
}
}
}
from noticeDir
from ({shade().collect { it.isDirectory() ? it : zipTree(it) }}) {
exclude '**/NOTICE*'
eachFile {
if (getName() == 'LICENSE.txt') {
setName(getFile().getParentFile().getName().split('.jar_')[0].tokenize('-')[0] + '-LICENSE.txt')
}
}
}
manifest {
attributes 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker',
'TweakOrder': '0',
'FMLCorePluginContainsFMLMod': 'true',
'FMLAT': 'replaymod_at.cfg'
}
}
def gitDescribe() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--always', '--dirty=*'
standardOutput = stdout
}
return stdout.toString().trim()
} catch (e) {
return "unknown"
}
}
processResources
{
// this will ensure that this task is redone when the versions change.
inputs.property 'version', { project.version }
inputs.property 'mcversion', { project.minecraft.version }
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
expand 'version': project.version, 'mcversion': project.minecraft.version
}
// copy everything else, thats not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
sourceSets {
main {
ext.refMap = "mixins.replaymod.refmap.json"
}
integrationTest {
compileClasspath += main.runtimeClasspath + main.output
java {
srcDir file('src/integration-test/java')
}
resources.srcDir file('src/integration-test/resources')
}
}
task copySrg(type: Copy, dependsOn: 'genSrgs') {
from {project.tasks.genSrgs.mcpToSrg}
into 'build'
}
setupDecompWorkspace.dependsOn copySrg
setupDevWorkspace.dependsOn copySrg
project.tasks.idea.dependsOn copySrg
// Mixin uses multiple HashMaps to generate the refmap.
// HashMaps are unordered collections and as such do not produce deterministic output.
// To fix that, we simply sort the refmap json file.
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
compileJava.doLast {
File refmapFile = compileJava.ext.refMapFile
if (refmapFile.exists()) {
def ordered
ordered = {
if (it instanceof Map) {
def sorted = new TreeMap(it)
sorted.replaceAll { k, v -> ordered(v) }
sorted
} else if (it instanceof List) {
it.replaceAll { v -> ordered(v) }
} else {
it
}
}
def json = JsonOutput.toJson(ordered(new JsonSlurper().parse(refmapFile)))
refmapFile.withWriter { it.write json }
}
}
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
import org.objectweb.asm.*
import static org.objectweb.asm.Opcodes.ASM5
// MC binaries were complied with a java version that produces invalid class files under certain circumstances
// This causes setupCIWorkspace to be insufficient for compiling.
// Related JDK bug: https://bugs.openjdk.java.net/browse/JDK-8066725
// As a workaround, to use setupCIWorkspace on Drone, we modify the bin jar in-place and remove all parameter annotations.
// WARNING: This piece of code ignores any and all gradle conventions and will probably fail horribly when run outside
// of a single-use environment (e.g. Drone). Use setupDecompWorkspace for normal use.
tasks.deobfMcMCP.doLast {
println "Applying RuntimeInvisibleParameterAnnotations workaround..."
File jar = getOutJar()
File tmp = new File((File) getTemporaryDir(), "workaround.jar")
tmp.withOutputStream {
new ZipOutputStream(it).withStream { dst ->
new ZipFile(jar).withCloseable { src ->
src.entries().each {
if (it.name.startsWith("net/minecraft/") && it.name.endsWith(".class")) {
def cw = new ClassWriter(0)
def cv = new ClassVisitor(ASM5, cw) {
@Override
MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodVisitor(ASM5, cv.visitMethod(access, name, desc, signature, exceptions)) {
@Override
AnnotationVisitor visitParameterAnnotation(int parameter, String pdesc, boolean visible) {
return null // Strip all parameter annotations
}
}
}
}
new ClassReader(src.getInputStream(it)).accept(cv, 0)
dst.putNextEntry(new ZipEntry(it.name))
dst.write(cw.toByteArray())
} else {
dst.putNextEntry(it)
dst.write(src.getInputStream(it).bytes)
}
}
}
}
}
jar.delete()
tmp.renameTo(jar)
}
task runIntegrationTest(type: JavaExec, dependsOn: ["makeStart", "jar"]) {
main = 'GradleStart'
standardOutput = System.out
errorOutput = System.err
workingDir file(minecraft.runDir)
def testDir = new File(minecraft.runDir, "integration-test")
doFirst {
testDir.deleteDir()
testDir.mkdirs()
}
doLast {
testDir.deleteDir()
}
afterEvaluate {
def runClient = tasks.getByName("runClient")
runIntegrationTest.jvmArgs = runClient.jvmArgs + "-Dfml.noGrab=true"
runIntegrationTest.args = runClient.args + "--gameDir" + testDir.canonicalPath
runIntegrationTest.classpath runClient.classpath + sourceSets.integrationTest.output
}
}
defaultTasks 'build'