Files
CustomNPC-Gecko-Addon/gradle.submodules.gradle

128 lines
5.1 KiB
Groovy

// ============================================================================
// Submodule Dependency Management
// ============================================================================
// Manages CustomNPC+ and GeckoLib as git submodule dependencies.
//
// How it works:
// - Both mods are git submodules built automatically alongside this mod
// - Their dev JARs are referenced as devOnlyNonPublishable dependencies
// - This means: available at COMPILE + RUNTIME, but NOT in the output JAR
// - Submodule builds are skipped when their source hasn't changed
// - When they do rebuild, old JARs are cleaned first to prevent duplicates
//
// Tasks:
// ./gradlew initSubmodules — first-time: clone/update submodules
// ./gradlew buildSubmodules — force rebuild both (always runs)
// ./gradlew buildCNPC — force rebuild CustomNPC+ only
// ./gradlew buildGeckoLib — force rebuild GeckoLib only
// ============================================================================
def isWindows = System.getProperty('os.name').toLowerCase().contains('windows')
// Resolve the gradlew executable for a submodule directory
def gradlewFor = { File submoduleDir ->
if (isWindows) {
return new File(submoduleDir, 'gradlew.bat').absolutePath
} else {
return new File(submoduleDir, 'gradlew').absolutePath
}
}
// Helper: find the dev JAR in a submodule's build output (resolved at execution time)
def findDevJar = { String submoduleDir ->
def libsDir = file("${submoduleDir}/build/libs")
if (!libsDir.exists()) return []
return libsDir.listFiles()?.findAll { it.name.endsWith('-dev.jar') && !it.name.contains('-preshadow') } ?: []
}
// ---- Submodule Init Task ----
tasks.register('initSubmodules', Exec) {
group = 'submodules'
description = 'Initialize and update all git submodules recursively'
commandLine 'git', 'submodule', 'update', '--init', '--recursive'
}
// Helper: clean old dev JARs from a submodule's build/libs before rebuilding
// Prevents stale JARs from different versions accumulating on the classpath
def cleanDevJars = { String submoduleDir ->
def libsDir = file("${submoduleDir}/build/libs")
if (libsDir.exists()) {
libsDir.listFiles()?.each { if (it.name.endsWith('.jar')) it.delete() }
}
}
// Helper: touch a marker file after a successful build
// We track this marker as the task output instead of build/libs (whose filenames
// change with every commit due to version stamps, confusing Gradle's up-to-date check)
def touchMarker = { String submoduleDir ->
def marker = file("${submoduleDir}/build/libs/.build-marker")
marker.parentFile.mkdirs()
marker.text = "${System.currentTimeMillis()}"
}
// ---- Build CustomNPC+ ----
// Uses -Pnomixin to avoid embedding Mixin into the JAR (UniMixins provides it at runtime)
// Skipped automatically when source hasn't changed. doFirst cleans stale JARs when it runs.
tasks.register('buildCNPC', Exec) {
group = 'submodules'
description = 'Builds CustomNPC+ dev JAR from submodule source (no embedded Mixin)'
workingDir file('CustomNPC-Plus')
doFirst { cleanDevJars('CustomNPC-Plus') }
doLast { touchMarker('CustomNPC-Plus') }
def gradlew = gradlewFor(file('CustomNPC-Plus'))
if (isWindows) {
commandLine 'cmd', '/c', gradlew, 'build', '-Pnomixin', '-x', 'test'
} else {
commandLine gradlew, 'build', '-Pnomixin', '-x', 'test'
}
inputs.dir file('CustomNPC-Plus/src')
inputs.files file('CustomNPC-Plus/build.gradle'), file('CustomNPC-Plus/dependencies.gradle')
outputs.file file('CustomNPC-Plus/build/libs/.build-marker')
}
// ---- Build GeckoLib ----
// Skipped automatically when source hasn't changed. doFirst cleans stale JARs when it runs.
tasks.register('buildGeckoLib', Exec) {
group = 'submodules'
description = 'Builds GeckoLib dev JAR from submodule source'
workingDir file('GeckoLib')
doFirst { cleanDevJars('GeckoLib') }
doLast { touchMarker('GeckoLib') }
def gradlew = gradlewFor(file('GeckoLib'))
if (isWindows) {
commandLine 'cmd', '/c', gradlew, 'build', '-x', 'test'
} else {
commandLine gradlew, 'build', '-x', 'test'
}
inputs.dir file('GeckoLib/src')
inputs.files file('GeckoLib/build.gradle'), file('GeckoLib/dependencies.gradle')
outputs.file file('GeckoLib/build/libs/.build-marker')
}
// ---- Convenience: build all submodules ----
tasks.register('buildSubmodules') {
group = 'submodules'
description = 'Builds all submodule dev JARs'
dependsOn 'buildCNPC', 'buildGeckoLib'
}
// ---- Auto-build & dependency mode ----
// Both submodule dev JARs are always built and on the classpath.
// In source injection mode, the dev JARs serve as FML mod containers (so FML
// discovers each @Mod in its own JAR). Hotswap works via build/classes/java/main/.
// In JAR mode (-PnoSourceInjection=true), the dev JARs are the sole source of submodule code.
tasks.named('compileJava').configure {
dependsOn 'buildCNPC', 'buildGeckoLib'
}
dependencies {
devOnlyNonPublishable files({ findDevJar('CustomNPC-Plus') })
devOnlyNonPublishable files({ findDevJar('GeckoLib') })
}