import io.franzbecker.gradle.lombok.task.DelombokTask plugins { id 'com.gradleup.shadow' version '8.3.9' id 'io.franzbecker.gradle-lombok' version '5.0.0' } repositories { mavenCentral() } allprojects { apply plugin: 'java' apply plugin: 'jacoco' apply plugin: 'java-library' apply plugin: 'maven-publish' apply plugin: 'com.gradleup.shadow' // no lombok for that project, cause its doing naughty things with stubing java.lang classes if (project != project(':headlessmc-modlauncher')) { // Consider switching to https://github.com/freefair/gradle-plugins/tree/main/lombok-plugin looks more maintained? apply plugin: 'io.franzbecker.gradle-lombok' lombok { version '1.18.42' } } group 'io.github.headlesshq.headlessmc' version rootProject.project_version repositories { mavenCentral() maven { name '3arthMaven' url 'https://3arthqu4ke.github.io/maven' } maven { name 'JitPackMaven' url 'https://jitpack.io' } } if (hmc_graal_build.toBoolean()) { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } else { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 compileJava { if (JavaVersion.current().isJava9Compatible()) { options.compilerArgs.addAll(['--release', '8']) } } } configurations { jarLibs implementation.extendsFrom jarLibs jarLibsApi api.extendsFrom jarLibsApi } dependencies { compileOnly 'org.jetbrains:annotations:26.0.2-1' testCompileOnly 'org.jetbrains:annotations:26.0.2-1' // no lombok for modlauncher cause we do bad hacks there in the java9 stub. if (project != project(':headlessmc-modlauncher')) { compileOnly 'org.projectlombok:lombok:1.18.42' annotationProcessor 'org.projectlombok:lombok:1.18.42' testCompileOnly 'org.projectlombok:lombok:1.18.42' testAnnotationProcessor 'org.projectlombok:lombok:1.18.42' } testImplementation 'org.junit.jupiter:junit-jupiter-api:5.14.2' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.14.2' testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.14.1' } test { useJUnitPlatform() testLogging { events "failed" exceptionFormat "full" } finalizedBy jacocoTestReport } jacocoTestReport { dependsOn test } jar { archivesBaseName = project.name duplicatesStrategy = DuplicatesStrategy.EXCLUDE } java { withSourcesJar() withJavadocJar() } // TODO: even though we are doing all of this Intellij // still complains about bytecode not matching the source... if (sourceSets.main.java.srcDirs.stream().anyMatch { it.exists()} && project != project(':headlessmc-modlauncher') && (!hmc_graal_build.toBoolean() || project != project(':headlessmc-graalvm'))) { tasks.register('delombok', DelombokTask) { dependsOn compileJava ext.outputDir = file(layout.buildDirectory.dir('delombok')) outputs.dir(ext.outputDir) sourceSets.main.java.srcDirs.each { if (it.exists()) { inputs.dir(it) args(it, '-f', 'suppressWarnings:skip', '-f', 'generated:skip', '-f', 'danceAroundIdeChecks:skip', '-f', 'generateDelombokComment:skip', '-f', 'javaLangAsFQN:skip', '-d', ext.outputDir) } } } javadoc { dependsOn delombok source = delombok.outputDir } sourcesJar { dependsOn delombok from delombok.outputDir // I tried every single exclude/include pattern but I could not get any to work exclude (fileTreeElement -> { return !((FileTreeElement) fileTreeElement) .getFile() .toPath() .toAbsolutePath() .startsWith(delombok.outputDir.toPath().toAbsolutePath()) }) } javadoc { options.addStringOption('Xdoclint:none', '-quiet') options.linkSource true } } jar { archiveClassifier.set('dev') manifest { attributes( "Implementation-Title": project.name, "Implementation-Version": version, ) } if (project != project(':headlessmc-lwjgl')) { manifest { attributes( "Automatic-Module-Name": "io.github.headlesshq.${project.name.replace("launcher-", "").replace('-', '.')}" ) } } } shadowJar { configurations = [project.configurations.jarLibs, project.configurations.jarLibsApi] archiveClassifier.set('') } jar.finalizedBy(shadowJar) def pubSuffix = System.getenv('IS_MAVEN_PUB') != null ? '' : System.getenv('GITHUB_RUN_NUMBER') != null && System.getenv('GITHUB_SHA') != null ? "-${System.getenv('GITHUB_RUN_NUMBER')}-${System.getenv('GITHUB_SHA').substring(0, 7)}" : project.version.endsWith('-SNAPSHOT') ? '' : '' publishing { publications { "${project.name.toLowerCase(Locale.ENGLISH)}"(MavenPublication) { ((MavenPublication) it).groupId "${project.group}" ((MavenPublication) it).artifactId "${project.archivesBaseName.toLowerCase(Locale.ENGLISH)}" ((MavenPublication) it).version "${project.version}${pubSuffix}" // TODO: testFixtures are part of commons artifact? // Exclude shadowJars from publication components.withType(AdhocComponentWithVariants).forEach { c -> c.withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { skip() } } from components.java } } repositories { // mavenLocal() if (System.getenv('DEPLOY_TO_GITHUB_PACKAGES_URL') != null) { maven { name = 'GithubPagesMaven' url = System.getenv('DEPLOY_TO_GITHUB_PACKAGES_URL') credentials { username = System.getenv('GITHUB_USER') password = System.getenv('GITHUB_TOKEN') } } } else { maven { name = 'BuildDirMaven' url = rootProject.layout.buildDirectory.dir('maven') } } } } publish { dependsOn(build) } tasks.withType(Test).tap { configureEach { jacoco { // our classloader potentially includes no ProtectionDomains? includeNoLocationClasses true jacoco.excludes = ['jdk.internal.*', 'io.github.headlesshq.headlessmc.lwjgl.agent.*'] } } } } javadoc { source subprojects.collect { it.sourceSets.main.allJava } classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath }) } dependencies { // create maven publication that contains all modules api project(':headlessmc-api') api project(':headlessmc-auth') api project(':headlessmc-jline') api project(':headlessmc-logging') api project(':headlessmc-launcher') api project(':headlessmc-launcher-wrapper') api project(':headlessmc-modlauncher') api project(':headlessmc-lwjgl') api project(':headlessmc-runtime') } tasks.register('jacocoRootReport', JacocoReport) { description = 'Generates an aggregate report from all subprojects' group = 'verification' dependsOn(subprojects.test) additionalSourceDirs.from = files(subprojects.sourceSets.main.allSource.srcDirs) sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs) classDirectories.from = files(subprojects.sourceSets.main.output) executionData.from = files(subprojects.jacocoTestReport.executionData) reports { xml.required.set(true) } } tasks.register('copyJars', Copy) { dependsOn subprojects.shadowJar subprojects.each { subproject -> // jfx jar is > 100MB, I do not want to fill my github storage? if (subproject.name != 'headlessmc-launcher-jfx') { from(subproject.shadowJar) } } into project.file(System.getProperty('hmc.jar.dir', 'build/libs')) } build { dependsOn(subprojects.shadowJar) finalizedBy(copyJars) } // the launchers report will otherwise contain coverage data about some of the // libraries we use in those two jars, e.g. xdarks Deencapsulation //noinspection ConfigurationAvoidance (idk does not seem to work with it) tasks.withType(JacocoReport) { afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { def tree = fileTree(dir: it, exclude: [ '**/headlessmc/headlessmc-launcher.jar', '**/headlessmc-launcher-wrapper.jar', '**/headlessmc/headlessmc-runtime.jar', '**/headlessmc/headlessmc-lwjgl.jar', '**/headlessmc/forge-cli.jar', '**/org/objectweb/asm/**', 'io/github/headlesshq/headlessmc/lwjgl/agent/**', 'io/github/headlesshq/headlessmc/web/**', 'io/github/headlesshq/headlessmc/web/**/*.*', 'io/github/headlesshq/headlessmc/web/cheerpj/**/*.*', 'io/github/headlesshq/headlessmc/web/cheerpj/plugin/**', 'io/github/headlesshq/headlessmc/web/cheerpj/plugin/*.*' ]) // because 'io/github/headlesshq/headlessmc/web/cheerpj/plugin/**' does not work return tree.exclude { details -> return details.file.canonicalPath.contains('headlessmc-web') } })) } reports { xml.required.set(true) } } allprojects { afterEvaluate { tasks.withType(GenerateMavenPom).configureEach { if (it.pom == null) { return } it.pom.withXml { asNode().dependencies.dependency.each { dependency -> if (dependency.artifactId.last().value().last() in ['junit-jupiter-api', 'junit-jupiter-engine', 'forgecli']) { assert dependency.parent().remove(dependency) } } } } } } generateMetadataFileForHeadlessmcPublication.mustRunAfter(copyJars)