mirror of
https://github.com/ethauvin/kobalt.git
synced 2025-04-26 16:28:12 -07:00
183 lines
7.4 KiB
Kotlin
183 lines
7.4 KiB
Kotlin
package com.beust.kobalt.internal
|
|
|
|
import com.beust.kobalt.KobaltException
|
|
import com.beust.kobalt.TaskResult
|
|
import com.beust.kobalt.api.*
|
|
import com.beust.kobalt.api.annotation.ExportedProjectProperty
|
|
import com.beust.kobalt.api.annotation.Task
|
|
import com.beust.kobalt.maven.DepFactory
|
|
import com.beust.kobalt.maven.DependencyManager
|
|
import com.beust.kobalt.maven.LocalRepo
|
|
import com.beust.kobalt.misc.KFiles
|
|
import com.beust.kobalt.misc.KobaltExecutors
|
|
import com.beust.kobalt.misc.log
|
|
import com.beust.kobalt.misc.warn
|
|
import com.beust.kobalt.plugin.java.JavaPlugin
|
|
import java.io.File
|
|
import java.util.*
|
|
import javax.inject.Inject
|
|
import javax.inject.Singleton
|
|
|
|
@Singleton
|
|
abstract class JvmCompilerPlugin @Inject constructor(
|
|
open val localRepo: LocalRepo,
|
|
open val files: KFiles,
|
|
open val depFactory: DepFactory,
|
|
open val dependencyManager: DependencyManager,
|
|
open val executors: KobaltExecutors,
|
|
open val jvmCompiler: JvmCompiler) : BasePlugin(), IProjectContributor {
|
|
|
|
companion object {
|
|
@ExportedProjectProperty(doc = "Projects this project depends on", type = "List<ProjectDescription>")
|
|
const val DEPENDENT_PROJECTS = "dependentProjects"
|
|
|
|
@ExportedProjectProperty(doc = "Compiler args", type = "List<String>")
|
|
const val COMPILER_ARGS = "compilerArgs"
|
|
|
|
const val TASK_CLEAN = "clean"
|
|
const val TASK_TEST = "test"
|
|
|
|
const val SOURCE_SET_MAIN = "main"
|
|
const val SOURCE_SET_TEST = "test"
|
|
const val DOCS_DIRECTORY = "docs/javadoc"
|
|
}
|
|
|
|
/**
|
|
* Log with a project.
|
|
*/
|
|
protected fun lp(project: Project, s: String) {
|
|
log(2, "${project.name}: $s")
|
|
}
|
|
|
|
override fun apply(project: Project, context: KobaltContext) {
|
|
super.apply(project, context)
|
|
project.projectProperties.put(DEPENDENT_PROJECTS, projects())
|
|
addVariantTasks(project, "compile", runTask = { taskCompile(project) })
|
|
}
|
|
|
|
@Task(name = TASK_TEST, description = "Run the tests", runAfter = arrayOf("compile", "compileTest"))
|
|
fun taskTest(project: Project) : TaskResult {
|
|
lp(project, "Running tests")
|
|
|
|
val runContributor = context.pluginInfo.testRunnerContributors.maxBy { it.affinity(project, context)}
|
|
if (runContributor != null && runContributor.affinity(project, context) > 0) {
|
|
return runContributor.run(project, context, dependencyManager.testDependencies(project, context,
|
|
projects()))
|
|
} else {
|
|
log(2, "Couldn't find a test runner for project ${project.name}, not running any tests")
|
|
return TaskResult()
|
|
}
|
|
}
|
|
|
|
@Task(name = TASK_CLEAN, description = "Clean the project", runBefore = arrayOf("compile"))
|
|
fun taskClean(project : Project ) : TaskResult {
|
|
java.io.File(project.directory, project.buildDirectory).let { dir ->
|
|
if (! dir.deleteRecursively()) {
|
|
warn("Couldn't delete $dir")
|
|
}
|
|
}
|
|
return TaskResult()
|
|
}
|
|
|
|
/**
|
|
* Copy the resources from a source directory to the build one
|
|
*/
|
|
protected fun copyResources(project: Project, sourceSet: String) {
|
|
val sourceDirs: ArrayList<String> = arrayListOf()
|
|
var outputDir: String?
|
|
if (sourceSet == JvmCompilerPlugin.SOURCE_SET_MAIN) {
|
|
sourceDirs.addAll(project.sourceDirectories.filter { it.contains("resources") })
|
|
outputDir = KFiles.CLASSES_DIR
|
|
} else if (sourceSet == JvmCompilerPlugin.SOURCE_SET_TEST) {
|
|
sourceDirs.addAll(project.sourceDirectoriesTest.filter { it.contains("resources") })
|
|
outputDir = KFiles.TEST_CLASSES_DIR
|
|
} else {
|
|
throw IllegalArgumentException("Custom source sets not supported yet: $sourceSet")
|
|
}
|
|
|
|
if (sourceDirs.size > 0) {
|
|
lp(project, "Copying $sourceSet resources")
|
|
val absOutputDir = File(KFiles.joinDir(project.directory, project.buildDirectory, outputDir))
|
|
sourceDirs.map { File(project.directory, it) }.filter {
|
|
it.exists()
|
|
} .forEach {
|
|
log(2, "Copying from $sourceDirs to $absOutputDir")
|
|
KFiles.copyRecursively(it, absOutputDir)
|
|
}
|
|
} else {
|
|
lp(project, "No resources to copy for $sourceSet")
|
|
}
|
|
}
|
|
|
|
private val compilerArgs = hashMapOf<String, List<String>>()
|
|
|
|
protected fun compilerArgsFor(project: Project) : List<String> {
|
|
val result = project.projectProperties.get(COMPILER_ARGS)
|
|
if (result != null) {
|
|
return result as List<String>
|
|
} else {
|
|
return emptyList()
|
|
}
|
|
}
|
|
|
|
fun addCompilerArgs(project: Project, vararg args: String) {
|
|
project.projectProperties.put(COMPILER_ARGS, arrayListOf(*args))
|
|
}
|
|
|
|
fun findSourceFiles(dir: String, sourceDirectories: Collection<String>): List<String> {
|
|
val projectDir = File(dir)
|
|
return files.findRecursively(projectDir,
|
|
sourceDirectories.map { File(it) }) { it: String -> it.endsWith(".java") }
|
|
.map { File(projectDir, it).absolutePath }
|
|
}
|
|
|
|
override fun projects() = projects
|
|
|
|
@Task(name = JavaPlugin.TASK_COMPILE, description = "Compile the project")
|
|
fun taskCompile(project: Project) : TaskResult {
|
|
context.variant.maybeGenerateBuildConfig(project, context)
|
|
val info = createCompilerActionInfo(project, context)
|
|
val compiler = selectAffinityActor(project, context.pluginInfo.compilerContributors)
|
|
if (compiler != null) {
|
|
return compiler.compile(project, context, info)
|
|
} else {
|
|
throw KobaltException("Couldn't find any compiler for project ${project.name}")
|
|
}
|
|
}
|
|
|
|
private fun <T : IAffinity> selectAffinityActor(project: Project, actors: List<T>) : T? =
|
|
actors.maxBy { it.affinity(project, context) }
|
|
|
|
@Task(name = JavaPlugin.TASK_JAVADOC, description = "Run Javadoc")
|
|
fun taskJavadoc(project: Project) = doJavadoc(project, createCompilerActionInfo(project, context))
|
|
|
|
private fun createCompilerActionInfo(project: Project, context: KobaltContext) : CompilerActionInfo {
|
|
copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN)
|
|
|
|
val classpath = dependencyManager.calculateDependencies(project, context, projects,
|
|
project.compileDependencies)
|
|
|
|
val projectDirectory = File(project.directory)
|
|
val buildDirectory = File(project.classesDir(context))
|
|
buildDirectory.mkdirs()
|
|
|
|
val initialSourceDirectories = context.variant.sourceDirectories(project)
|
|
val sourceDirectories = context.pluginInfo.sourceDirectoriesInterceptors.fold(initialSourceDirectories,
|
|
{ sd, interceptor -> interceptor.intercept(project, context, sd) })
|
|
|
|
val sourceFiles = files.findRecursively(projectDirectory, sourceDirectories,
|
|
{ it .endsWith(project.sourceSuffix) })
|
|
.map { File(projectDirectory, it).path }
|
|
|
|
val initialActionInfo = CompilerActionInfo(projectDirectory.path, classpath, sourceFiles, buildDirectory,
|
|
emptyList())
|
|
val result = context.pluginInfo.compilerInterceptors.fold(initialActionInfo, { ai, interceptor ->
|
|
interceptor.intercept(project, context, ai)
|
|
})
|
|
return result
|
|
}
|
|
|
|
abstract fun doCompile(project: Project, cai: CompilerActionInfo) : TaskResult
|
|
abstract fun doJavadoc(project: Project, cai: CompilerActionInfo) : TaskResult
|
|
}
|
|
|