413 lines
9.8 KiB
Groovy
413 lines
9.8 KiB
Groovy
/*
|
|
* Build logic for Progressia
|
|
* build.gradle
|
|
*
|
|
* Please refer to
|
|
*
|
|
* docs/building/BuildScriptReference.md
|
|
*
|
|
* for user reference.
|
|
*/
|
|
|
|
plugins {
|
|
id 'java'
|
|
|
|
// GrGit
|
|
// A JGit wrapper for Groovy used to access git commit info
|
|
id 'org.ajoberstar.grgit' version '4.1.1'
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Configure Java version
|
|
*/
|
|
|
|
java {
|
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
targetCompatibility = JavaVersion.VERSION_1_8
|
|
}
|
|
|
|
compileJava {
|
|
/*
|
|
* We want to compile for Java 8.
|
|
* If we are using JDK 8, no further action is required.
|
|
* However, on JDK 9 and later versions, '--release' option is required,
|
|
* which is missing on JDK 8.
|
|
*/
|
|
if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
|
|
options.compilerArgs.addAll(['--release', '8'])
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Set encoding
|
|
*/
|
|
|
|
compileJava {
|
|
options.encoding = 'utf8'
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Dependencies
|
|
*/
|
|
|
|
repositories {
|
|
mavenCentral()
|
|
|
|
/*
|
|
* Windcorp Maven repository
|
|
* Currently used by:
|
|
* - ru.windcorp.fork.io.github.java-graphics:glm:1.0.1
|
|
*/
|
|
maven { url 'https://windcorp.ru/./maven' }
|
|
}
|
|
|
|
dependencies {
|
|
// Google Guava
|
|
// A generic utilities library
|
|
implementation 'com.google.guava:guava:31.0.1-jre'
|
|
|
|
// Trove4j
|
|
// Provides optimized Collections for primitive types
|
|
implementation 'net.sf.trove4j:trove4j:3.0.3'
|
|
|
|
// java-graphics
|
|
// A GLM (OpenGL Mathematics) port to Java
|
|
// Unfortunately, Maven Central Repository provides an outdated version of this library, which contains several critical bugs
|
|
implementation 'ru.windcorp.fork.io.github.java-graphics:glm:1.0.1'
|
|
|
|
// Log4j
|
|
// A logging library
|
|
implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
|
|
implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
|
|
|
|
// JUnit
|
|
// A unit-testing library
|
|
testImplementation 'junit:junit:4.13.2'
|
|
|
|
// Also see LWJGL dependencies in build_logic/lwjgl.gradle
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Version resolution
|
|
*/
|
|
|
|
import org.ajoberstar.grgit.*
|
|
|
|
// Pattern: vMAJOR.MINOR.PATCH[-SUFFIX]
|
|
project.ext.tagFormat = /^v(\d+)\.(\d+)\.(\d+)(-[\w\-]*)?$/
|
|
|
|
String version_parseVersion(String tag, boolean increment) {
|
|
try {
|
|
|
|
def data = (tag =~ tagFormat)[0]
|
|
|
|
def major = data[1]
|
|
def minor = data[2]
|
|
def patch = data[3] as int
|
|
def suffix = data[4] ?: ''
|
|
|
|
if (increment) {
|
|
def oldVersion = "$major.$minor.$patch$suffix"
|
|
patch++
|
|
def newVersion = "$major.$minor.$patch$suffix"
|
|
|
|
logger.info "Version parsed from Git: $oldVersion, incremented to $newVersion"
|
|
return newVersion
|
|
} else {
|
|
def newVersion = "$major.$minor.$patch$suffix"
|
|
logger.info "Version parsed from Git: $newVersion"
|
|
return newVersion
|
|
}
|
|
|
|
} catch (any) {
|
|
logger.warn "Could not parse version from tag \"$tag\""
|
|
return tag
|
|
}
|
|
}
|
|
|
|
Tag version_findRelevantTag(Grgit git) {
|
|
def tags = git.tag.list()
|
|
|
|
def commits = [ git.head() ]
|
|
def visited = new HashSet<>()
|
|
|
|
while (true) {
|
|
if (commits.isEmpty()) return null
|
|
|
|
def nextCommits = new HashSet<>()
|
|
|
|
def formatSpecificationPrinted = false
|
|
for (def commit : commits) {
|
|
def tag = tags.findAll { it.commit == commit } ?.max { it.dateTime }
|
|
|
|
if (tag != null) {
|
|
if (tag.name ==~ tagFormat) {
|
|
return tag
|
|
} else {
|
|
if (!formatSpecificationPrinted) {
|
|
formatSpecificationPrinted = true
|
|
logger.info 'Expecting tag format: vMAJOR.MINOR.PATCH[-SUFFIX]'
|
|
}
|
|
logger.info 'Ignoring tag due to invalid format: {}', tag.name
|
|
}
|
|
}
|
|
|
|
nextCommits.addAll commit.parentIds.collect(git.resolve.&toCommit)
|
|
}
|
|
|
|
visited.addAll commits
|
|
nextCommits.removeAll visited
|
|
commits = nextCommits
|
|
}
|
|
}
|
|
|
|
task resolveVersion {
|
|
description 'Resolves version information from Git repository or project properties.'
|
|
|
|
doFirst {
|
|
|
|
project.ext.commit = System.env.GIT_COMMIT
|
|
project.ext.branch = System.env.GIT_BRANCH
|
|
|
|
try {
|
|
def git = Grgit.open(dir: project.projectDir)
|
|
|
|
project.ext.commit = commit ?: git.head().id
|
|
project.ext.branch = branch ?: git.branch.current().name
|
|
|
|
if (project.version != 'unspecified') {
|
|
// Leave version as-is
|
|
} else {
|
|
|
|
// Resolve version from Git
|
|
def tag = version_findRelevantTag(git)
|
|
if (tag == null) {
|
|
|
|
String suffix
|
|
if (project.hasProperty('buildId')) {
|
|
suffix = project.buildId;
|
|
} else {
|
|
suffix = java.time.ZonedDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern('yyyy_MM_dd'))
|
|
}
|
|
project.version = "999.0.0-$suffix"
|
|
|
|
logger.warn 'Git repository does not contain an applicable tag, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
|
|
|
|
} else {
|
|
|
|
project.version = version_parseVersion(tag.name, tag.commit != git.head())
|
|
|
|
}
|
|
|
|
}
|
|
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
|
|
if (project.version == 'unspecified') project.version = 'dev'
|
|
project.ext.commit = commit ?: '-'
|
|
project.ext.branch = branch ?: '-'
|
|
|
|
logger.warn 'No Git repository found in project root, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
|
|
}
|
|
|
|
if (branch.contains '/') {
|
|
// Strip remote - no one wants that
|
|
project.ext.branch = branch.takeAfter '/'
|
|
}
|
|
|
|
if (!project.hasProperty('buildId')) {
|
|
project.ext.buildId = '-'
|
|
}
|
|
}
|
|
|
|
doLast {
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Apply LWJGL logic
|
|
*/
|
|
apply from: 'build_logic/lwjgl.gradle'
|
|
|
|
|
|
|
|
/*
|
|
* Copy libraries into build/libs/lib directory, next to Progressia.jar
|
|
*/
|
|
|
|
task exportLibs(type: Sync) {
|
|
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
|
|
|
jar.dependsOn exportLibs
|
|
dependsOn lwjgl_addNativesToRuntimeOnly
|
|
|
|
// from defined in configureManifest
|
|
into 'build/libs/lib'
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Configure JAR manifest
|
|
*/
|
|
|
|
task configureManifest {
|
|
description 'Populates JAR manifest with Main-Class, Class-Path and version metadata.'
|
|
|
|
jar.dependsOn configureManifest
|
|
dependsOn resolveVersion
|
|
dependsOn lwjgl_addNativesToRuntimeOnly
|
|
|
|
doFirst {
|
|
def classPath = project.lwjgl.replaceNativesIn(configurations.runtimeClasspath)
|
|
|
|
exportLibs.from classPath
|
|
|
|
jar.manifest.attributes(
|
|
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
|
|
'Class-Path': classPath.collect { "lib/${java.net.URLEncoder.encode it.name}" } .join(' '),
|
|
|
|
'Specification-Title': 'Progressia',
|
|
|
|
'Implementation-Title': 'Progressia',
|
|
'Implementation-Version': project.version,
|
|
'Implementation-Version-Git-Commit': project.commit,
|
|
'Implementation-Version-Git-Branch': project.branch,
|
|
'Implementation-Version-BuildId': project.buildId,
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Packaging working directory configuration
|
|
*/
|
|
|
|
import java.nio.file.*
|
|
import java.nio.file.attribute.*
|
|
|
|
task deletePackagingDirs(type: Delete) {
|
|
description 'Deletes build/tmp/packaging directory.'
|
|
followSymlinks = false
|
|
delete 'build/tmp/packaging'
|
|
}
|
|
|
|
task linkBuildOutputForPackaging {
|
|
description 'Symlinks the contents of build/libs into packaging working directory.'
|
|
|
|
dependsOn build
|
|
mustRunAfter deletePackagingDirs
|
|
|
|
onlyIf { preparePackaging.ext.mode == 'symlink' }
|
|
|
|
ext.from = 'build/libs'
|
|
ext.into = "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
|
|
|
|
inputs.dir from
|
|
outputs.dir into
|
|
|
|
doLast {
|
|
def fromPath = Paths.get from
|
|
def intoPath = Paths.get into
|
|
|
|
Files.createDirectories intoPath
|
|
|
|
Files.list(fromPath).each {
|
|
def fileName = it.fileName.toString()
|
|
|
|
// Exclude all JARs except the current one
|
|
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
|
|
return
|
|
|
|
Files.createSymbolicLink intoPath.resolve(it.fileName), intoPath.relativize(it)
|
|
}
|
|
}
|
|
}
|
|
|
|
task copyBuildOutputForPackaging(type: Copy) {
|
|
description 'Copies the contents of build/libs into packaging working directory.'
|
|
|
|
dependsOn build
|
|
mustRunAfter deletePackagingDirs
|
|
|
|
onlyIf { preparePackaging.ext.mode == 'copy' }
|
|
|
|
from 'build/libs'
|
|
filesMatching("${project.name}*.jar") {
|
|
include tasks.jar.archiveFileName.get()
|
|
}
|
|
into "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
|
|
}
|
|
|
|
task preparePackaging {
|
|
preparePackaging.ext.buildDest = ''
|
|
preparePackaging.ext.mode = 'symlink'
|
|
|
|
dependsOn deletePackagingDirs
|
|
dependsOn linkBuildOutputForPackaging
|
|
dependsOn copyBuildOutputForPackaging
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Apply all packaging scripts
|
|
*/
|
|
|
|
new File(projectDir, 'build_logic/packaging').list().each {
|
|
apply from: "build_logic/packaging/$it/script.gradle"
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Ensure no more than one packaging task is scheduled
|
|
*/
|
|
|
|
gradle.taskGraph.whenReady { graph ->
|
|
if (graph.allTasks.count { it.name ==~ /package[^_]*/ } > 1) {
|
|
def offenders = graph.allTasks.findAll { it.name ==~ /package[^_]*/ }
|
|
throw new GradleException("Cannot execute multiple package tasks within a single build\n" +
|
|
"\tOffending tasks: $offenders")
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Convenience build tasks
|
|
*/
|
|
|
|
task buildCrossPlatform {
|
|
description 'Builds the project including native libraries for all available platforms.'
|
|
group 'Progressia'
|
|
|
|
dependsOn requestCrossPlatformDependencies
|
|
dependsOn build
|
|
|
|
doLast {
|
|
logger.info 'Native libraries for all platforms have been added'
|
|
}
|
|
}
|
|
|
|
task buildLocal {
|
|
description "Builds the project including only native libraries for current platform (${lwjgl.localArch})."
|
|
group 'Progressia'
|
|
|
|
dependsOn build
|
|
|
|
doLast {
|
|
logger.info "Native libraries only for platform ${lwjgl.localArch} have been added"
|
|
}
|
|
}
|