diff --git a/src/main/kotlin/com/beust/kobalt/api/ITestSourceDirectoryContributor.kt b/src/main/kotlin/com/beust/kobalt/api/ITestSourceDirectoryContributor.kt new file mode 100644 index 00000000..d88ca197 --- /dev/null +++ b/src/main/kotlin/com/beust/kobalt/api/ITestSourceDirectoryContributor.kt @@ -0,0 +1,11 @@ +package com.beust.kobalt.api + +import java.io.File + +/** + * Plug-ins that add tets source directories to be compiled need to implement this interface. + */ +interface ITestSourceDirectoryContributor { + fun testSourceDirectoriesFor(project: Project, context: KobaltContext): List +} + diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index dfe6b2f7..8a460f73 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -12,7 +12,6 @@ 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 @@ -36,6 +35,8 @@ abstract class JvmCompilerPlugin @Inject constructor( @ExportedProjectProperty(doc = "Compiler args", type = "List") const val COMPILER_ARGS = "compilerArgs" + const val TASK_COMPILE = "compile" + const val TASK_COMPILE_TEST = "compileTest" const val TASK_CLEAN = "clean" const val TASK_TEST = "test" @@ -57,7 +58,8 @@ abstract class JvmCompilerPlugin @Inject constructor( taskContributor.addVariantTasks(project, context, "compile", runTask = { taskCompile(project) }) } - @Task(name = TASK_TEST, description = "Run the tests", runAfter = arrayOf("compile", "compileTest")) + @Task(name = TASK_TEST, description = "Run the tests", + runAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE, JvmCompilerPlugin.TASK_COMPILE_TEST)) fun taskTest(project: Project) : TaskResult { lp(project, "Running tests") @@ -126,25 +128,10 @@ abstract class JvmCompilerPlugin @Inject constructor( project.projectProperties.put(COMPILER_ARGS, arrayListOf(*args)) } - fun findSourceFiles(project: Project, context: KobaltContext, dir: String, - sourceDirectories: Collection): List { - val projectDir = File(dir) - val allSourceDirectories = arrayListOf() - allSourceDirectories.addAll(sourceDirectories.map { File(it) }) - context.pluginInfo.sourceDirContributors.forEach { - allSourceDirectories.addAll(it.sourceDirectoriesFor(project, context)) - } - return files.findRecursively(projectDir, allSourceDirectories) { - it: String -> it.endsWith(".java") - }.map { File(projectDir, it).absolutePath } - } - - override fun projects() = projects - - @Task(name = JavaPlugin.TASK_COMPILE, description = "Compile the project") + @Task(name = JvmCompilerPlugin.TASK_COMPILE, description = "Compile the project") fun taskCompile(project: Project) : TaskResult { val generatedDir = context.variant.maybeGenerateBuildConfig(project, context) - val info = createCompilerActionInfo(project, context, generatedDir) + val info = createCompilerActionInfo(project, context, generatedDir, isTest = false) val compiler = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.compilerContributors) if (compiler != null) { return compiler.compile(project, context, info) @@ -153,23 +140,28 @@ abstract class JvmCompilerPlugin @Inject constructor( } } + override fun projects() = projects + @Task(name = "doc", description = "Generate the documentation for the project") fun taskJavadoc(project: Project) : TaskResult { val docGenerator = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.docContributors) if (docGenerator != null) { - return docGenerator.generateDoc(project, context, createCompilerActionInfo(project, context, null)) + return docGenerator.generateDoc(project, context, createCompilerActionInfo(project, context, null, + isTest = false)) } else { warn("Couldn't find any doc contributor for project ${project.name}") return TaskResult() } } - private fun createCompilerActionInfo(project: Project, context: KobaltContext, generatedSourceDir: File?) - : CompilerActionInfo { + protected fun createCompilerActionInfo(project: Project, context: KobaltContext, generatedSourceDir: File?, + isTest: Boolean) : CompilerActionInfo { copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN) - val classpath = dependencyManager.calculateDependencies(project, context, projects, - project.compileDependencies) + val classpath = if (isTest) + dependencyManager.testDependencies(project, context, projects) + else + dependencyManager.dependencies(project, context, projects) val projectDirectory = File(project.directory) val buildDirectory = File(project.classesDir(context)) @@ -183,22 +175,32 @@ abstract class JvmCompilerPlugin @Inject constructor( } // Source directories from the project and variants - initialSourceDirectories.addAll(context.variant.sourceDirectories(project)) - - // Source directories from the contributors - context.pluginInfo.sourceDirContributors.forEach { - initialSourceDirectories.addAll(it.sourceDirectoriesFor(project, context)) + if (! isTest) { + initialSourceDirectories.addAll(context.variant.sourceDirectories(project)) } + // Source directories from the contributors + initialSourceDirectories.addAll( + if (isTest) { + context.pluginInfo.testSourceDirContributors.flatMap { it.testSourceDirectoriesFor(project, context) } + } else { + context.pluginInfo.sourceDirContributors.flatMap { it.sourceDirectoriesFor(project, context) } + }) + // Transform them with the interceptors, if any - val sourceDirectories = context.pluginInfo.sourceDirectoriesInterceptors.fold(initialSourceDirectories.toList(), - { sd, interceptor -> interceptor.intercept(project, context, sd) }) + val sourceDirectories = if (isTest) { + initialSourceDirectories + } else { + context.pluginInfo.sourceDirectoriesInterceptors.fold(initialSourceDirectories.toList(), + { sd, interceptor -> interceptor.intercept(project, context, sd) }) + } // Now that we have the final list of source dirs, find source files in them val sourceFiles = files.findRecursively(projectDirectory, sourceDirectories, { it .endsWith(project.sourceSuffix) }) .map { File(projectDirectory, it).path } + // Finally, alter the info with the compiler interceptors before returning it val initialActionInfo = CompilerActionInfo(projectDirectory.path, classpath, sourceFiles, buildDirectory, emptyList()) val result = context.pluginInfo.compilerInterceptors.fold(initialActionInfo, { ai, interceptor -> diff --git a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt index 5827cc72..6665efa2 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/KobaltPluginXml.kt @@ -71,6 +71,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { val compilerContributors = arrayListOf() val docContributors = arrayListOf() val sourceDirContributors = arrayListOf() + val testSourceDirContributors = arrayListOf() val buildConfigFieldContributors = arrayListOf() val taskContributors = arrayListOf() @@ -138,6 +139,8 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { if (this is ISourceDirectoryIncerceptor) sourceDirectoriesInterceptors.add(this) if (this is ITestRunnerContributor) testRunnerContributors.add(this) + // Not documented yet + if (this is ITestSourceDirectoryContributor) testSourceDirContributors.add(this) } } } @@ -165,6 +168,7 @@ class PluginInfo(val xml: KobaltPluginXml, val classLoader: ClassLoader?) { sourceDirContributors.addAll(pluginInfo.sourceDirContributors) buildConfigFieldContributors.addAll(pluginInfo.buildConfigFieldContributors) taskContributors.addAll(pluginInfo.taskContributors) + testSourceDirContributors.addAll(pluginInfo.testSourceDirContributors) } } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt index d2c6fdad..2d9a9902 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaCompiler.kt @@ -10,6 +10,7 @@ import com.beust.kobalt.internal.ICompilerAction import com.beust.kobalt.internal.JvmCompiler import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.log +import com.beust.kobalt.misc.warn import com.beust.kobalt.plugin.android.forward import com.google.inject.Inject import com.google.inject.Singleton @@ -19,6 +20,11 @@ import java.io.File class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler) { fun compilerAction(executable: File) = object : ICompilerAction { override fun compile(info: CompilerActionInfo): TaskResult { + if (info.sourceFiles.isEmpty()) { + warn("No source files to compile") + return TaskResult() + } + info.outputDir.mkdirs() val allArgs = arrayListOf( diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt index 0f14173e..83b45ee1 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaPlugin.kt @@ -28,11 +28,9 @@ class JavaPlugin @Inject constructor( val javaCompiler: JavaCompiler, override val jvmCompiler: JvmCompiler) : JvmCompilerPlugin(localRepo, files, depFactory, dependencyManager, executors, jvmCompiler), - ICompilerContributor, IDocContributor { + ICompilerContributor, IDocContributor, ITestSourceDirectoryContributor { companion object { const val PLUGIN_NAME = "Java" - const val TASK_COMPILE = "compile" - const val TASK_COMPILE_TEST = "compileTest" } override val name = PLUGIN_NAME @@ -66,25 +64,16 @@ class JavaPlugin @Inject constructor( return result } - @Task(name = TASK_COMPILE_TEST, description = "Compile the tests", runAfter = arrayOf("compile")) + @Task(name = TASK_COMPILE_TEST, description = "Compile the tests", + runAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE)) fun taskCompileTest(project: Project): TaskResult { - val sourceFiles = findSourceFiles(project, context, project.directory, project.sourceDirectoriesTest) - val result = - if (sourceFiles.size > 0) { - copyResources(project, JvmCompilerPlugin.SOURCE_SET_TEST) - val buildDir = KFiles.makeOutputTestDir(project) - javaCompiler.compile(project, context, CompilerActionInfo(project.directory, - dependencyManager.testDependencies(project, context, projects()), - sourceFiles, buildDir, compilerArgsFor(project))) - } else { - warn("Couldn't find any tests to compile") - TaskResult() - } + copyResources(project, JvmCompilerPlugin.SOURCE_SET_TEST) + val compilerActionInfo = createCompilerActionInfo(project, context, null, isTest = true) + val result = javaCompiler.compile(project, context, compilerActionInfo) return result } // ICompilerContributor - override fun compile(project: Project, context: KobaltContext, info: CompilerActionInfo) : TaskResult { val result = if (info.sourceFiles.size > 0) { @@ -95,6 +84,10 @@ class JavaPlugin @Inject constructor( } return result } + + // ITestSourceDirectoryContributor + override fun testSourceDirectoriesFor(project: Project, context: KobaltContext) + = project.sourceDirectoriesTest.map { File(it) }.toList() } @Directive diff --git a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt index 2ec4c824..c07d72ae 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/packaging/PackagingPlugin.kt @@ -16,7 +16,6 @@ import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KobaltExecutors import com.beust.kobalt.misc.log import com.beust.kobalt.misc.toString -import com.beust.kobalt.plugin.java.JavaPlugin import java.io.File import java.io.FileOutputStream import java.io.OutputStream @@ -63,7 +62,8 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana private fun libsDir(project: Project) = KFiles.makeDir(buildDir(project).path, "libs").path - @Task(name = TASK_ASSEMBLE, description = "Package the artifacts", runAfter = arrayOf(JavaPlugin.TASK_COMPILE)) + @Task(name = TASK_ASSEMBLE, description = "Package the artifacts", + runAfter = arrayOf(JvmCompilerPlugin.TASK_COMPILE)) fun taskAssemble(project: Project) : TaskResult { project.projectProperties.put(PACKAGES, packages) packages.filter { it.project.name == project.name }.forEach { pkg ->