Files
apollo/game/plugins.gradle
T
Gary Tierney b536b2ed9d Add start of test framework for plugins
Adds a basic testing framework suitable for plugins that start simple
Actions for players, which can be expanded on in the future.  The
banking and training dummy tests have been updated to use this framework
and serve as samples.
2017-06-19 02:59:57 +01:00

209 lines
6.6 KiB
Groovy

import com.moandjiezana.toml.Toml
import org.apollo.build.tasks.KotlinScriptCompileTask
import java.nio.file.Paths
def PLUGIN_VERIFICATION_GROUP = "plugin-verification"
def PLUGIN_BUILD_GROUP = "plugin-build"
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'com.moandjiezana.toml', name: 'toml4j', version: '0.7.1'
}
}
task testPlugins {
group = "plugin-verification"
doLast {
println("Finished executing plugin tests")
}
}
sourceSets {
pluginTesting {
kotlin {
srcDir 'src/pluginTesting/kotlin'
}
}
}
dependencies {
pluginTestingCompile sourceSets.test.output
pluginTestingCompile sourceSets.test.compileClasspath
}
check.dependsOn testPlugins
class PluginBuildData {
PluginBuildData(String normalizedName, SourceSet mainSources, SourceSet testSources,
FileCollection scriptFiles, List<String> dependencyNames) {
this.normalizedName = normalizedName
this.mainSources = mainSources
this.testSources = testSources
this.scriptFiles = scriptFiles
this.dependencyNames = dependencyNames
}
String normalizedName
SourceSet mainSources
SourceSet testSources
FileCollection scriptFiles
List<String> dependencyNames
}
Map<String, PluginBuildData> pluginMap = new HashMap<>()
def configurePluginDependencies(SourceSet mainSources, SourceSet testSources,
List<PluginBuildData> pluginDependencies) {
def testConfiguration = testSources.compileConfigurationName
def mainConfiguration = mainSources.compileConfigurationName
// Add this plugin as a runtime dependency to the main game project
dependencies.add(configurations.runtime.name, mainSources.output)
pluginDependencies.each {
dependencies.add(mainConfiguration, it.mainSources.output)
dependencies.add(testConfiguration, it.testSources.output)
}
dependencies.add(mainConfiguration, configurations.compile)
dependencies.add(mainConfiguration, sourceSets.main.output)
dependencies.add(testConfiguration, mainSources.output)
dependencies.add(testConfiguration, configurations.testCompile)
dependencies.add(testConfiguration, sourceSets.test.output)
dependencies.add(testConfiguration, sourceSets.test.compileClasspath)
dependencies.add(testConfiguration, sourceSets.pluginTesting.output)
}
def configurePluginTasks(String name, SourceSet mainSources, SourceSet testSources,
FileCollection scriptFiles, List<PluginBuildData> pluginDependencies) {
def taskName = name.split("_").collect { it.capitalize() }.join("")
def testsTask = task("test${taskName}", type: Test) {
group = "plugin-verification"
testClassesDir = testSources.output.classesDir
classpath = testSources.runtimeClasspath + mainSources.runtimeClasspath
binResultsDir = file("$buildDir/plugin-test-results/binary/$name")
reports {
html.destination = "$buildDir/reports/plugin-tests/$name"
junitXml.destination = "$buildDir/plugin-tests/$name"
}
testLogging {
events "passed", "skipped", "failed"
}
}
testPlugins.dependsOn testsTask
if (!scriptFiles.empty) {
def compileScriptsTask = task("compile${taskName}Scripts", type: KotlinScriptCompileTask) {
group = "plugin-compile"
def outputDir = mainSources.output.classesDir
inputs.files scriptFiles
outputsDir = outputDir
compileClasspath = sourceSets.main.compileClasspath +
sourceSets.main.runtimeClasspath +
mainSources.compileClasspath +
mainSources.runtimeClasspath
scriptDefinitionClass = "org.apollo.game.plugin.kotlin.KotlinPluginScript"
mustRunAfter tasks[mainSources.classesTaskName]
}
testPlugins.dependsOn compileScriptsTask
tasks[mainSources.classesTaskName].finalizedBy compileScriptsTask
}
}
def pluginTree = fileTree(dir: "$pluginsDir")
def pluginDefinitions = pluginTree.matching {
include '**/meta.toml'
}
class PluginScriptFile {
def scriptFileName
def pluginDir
PluginScriptFile(scriptFileName, pluginDir) {
this.scriptFileName = scriptFileName
this.pluginDir = pluginDir
}
}
def pluginFiles = new ArrayList<PluginScriptFile>()
pluginDefinitions.each { file ->
def meta = new Toml()
meta.read(file.absoluteFile)
def pluginFolder = Paths.get(file.parentFile.absolutePath)
def name = meta.getString("name", pluginFolder.getFileName().toString())
def normalizedName = name.replaceAll("[^a-zA-Z0-9_]", '_').toLowerCase()
def displayNameArray = normalizedName.split("_").collect { it.capitalize() }.join("").toCharArray()
displayNameArray[0] = displayNameArray[0].toLowerCase()
def sourceSetName = new String(displayNameArray)
def packageName = meta.getString("package", "org.apollo.game.plugin")
def authors = meta.getList("authors", new ArrayList())
def dependencies = meta.getList("dependencies", new ArrayList())
def scripts = fileTree(file.parentFile) {
include '**/*.plugin.kts'
exclude '*.kt'
}
def srcsDir = meta.getString("config.src", "src/")
def testDir = meta.getString("config.test", "test/")
def mainSources = sourceSets.create("${sourceSetName}Main") {
kotlin {
srcDir pluginFolder.resolve(srcsDir).toString()
exclude '*.kts'
}
}
def testSources = sourceSets.create("${sourceSetName}Test") {
kotlin {
srcDir pluginFolder.resolve(testDir).toString()
}
}
scripts.files.forEach {
def scriptFileName = it.getName()
//@todo - also compare package
def existingFile = pluginFiles.find { it.scriptFileName == scriptFileName }
if (existingFile != null) {
throw new GradleException("Duplicate script file found named ${scriptFileName} in ${pluginFolder}, " +
"also exists in ${existingFile.pluginDir}")
}
pluginFiles.add(new PluginScriptFile(scriptFileName, pluginFolder))
}
def pluginData = new PluginBuildData(normalizedName, mainSources, testSources, scripts, dependencies)
pluginMap.put(normalizedName, pluginData)
}
pluginMap.values().each {
def dependencies = it.dependencyNames.collect { name -> pluginMap.get(name) }
configurePluginDependencies(it.mainSources, it.testSources, dependencies)
configurePluginTasks(it.normalizedName, it.mainSources, it.testSources, it.scriptFiles, dependencies)
}