From 8728ba4637e70c57c9170f55cd22c49fb91ccd14 Mon Sep 17 00:00:00 2001 From: Cedric Beust Date: Thu, 19 Nov 2015 03:27:15 -0800 Subject: [PATCH] Variant support for the compile target. --- .../com/beust/kobalt/api/KobaltContext.kt | 2 + .../kotlin/com/beust/kobalt/api/Project.kt | 4 +- .../kobalt/internal/JvmCompilerPlugin.kt | 50 +++++++++++++++++-- .../com/beust/kobalt/internal/ProjectInfo.kt | 2 + .../kotlin/com/beust/kobalt/misc/KFiles.kt | 25 +++++++--- .../kobalt/plugin/java/JavaProjectInfo.kt | 1 + .../kobalt/plugin/kotlin/KotlinProjectInfo.kt | 1 + 7 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/com/beust/kobalt/api/KobaltContext.kt b/src/main/kotlin/com/beust/kobalt/api/KobaltContext.kt index 453acc63..a01900cd 100644 --- a/src/main/kotlin/com/beust/kobalt/api/KobaltContext.kt +++ b/src/main/kotlin/com/beust/kobalt/api/KobaltContext.kt @@ -3,6 +3,7 @@ package com.beust.kobalt.api import com.beust.kobalt.Args import com.beust.kobalt.Plugins import com.beust.kobalt.internal.PluginInfo +import com.beust.kobalt.internal.Variant import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.misc.KobaltExecutors @@ -12,5 +13,6 @@ public class KobaltContext(val args: Args) { lateinit var pluginProperties: PluginProperties lateinit var dependencyManager: DependencyManager lateinit var executors: KobaltExecutors + var variant: Variant = Variant() } diff --git a/src/main/kotlin/com/beust/kobalt/api/Project.kt b/src/main/kotlin/com/beust/kobalt/api/Project.kt index a8998422..0e712512 100644 --- a/src/main/kotlin/com/beust/kobalt/api/Project.kt +++ b/src/main/kotlin/com/beust/kobalt/api/Project.kt @@ -95,14 +95,14 @@ open public class Project( @Directive val projectName: String get() = name - private val productFlavors = hashMapOf() + val productFlavors = hashMapOf() fun addProductFlavor(name: String, pf: ProductFlavorConfig) { println("Adding ProductFlavor $name") productFlavors.put(name, pf) } - private val buildTypes = hashMapOf() + val buildTypes = hashMapOf() fun addBuildType(name: String, bt: BuildTypeConfig) { println("Adding BuildType $name") diff --git a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt index cba00309..057162d9 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/JvmCompilerPlugin.kt @@ -53,6 +53,20 @@ abstract class JvmCompilerPlugin @Inject constructor( super.apply(project, context) project.projectProperties.put(BUILD_DIR, project.buildDirectory + File.separator + "classes") project.projectProperties.put(DEPENDENT_PROJECTS, projects()) + + project.productFlavors.keys.forEach { pf -> + project.buildTypes.keys.forEach { bt -> + val taskName = Variant(pf, bt).toTask("compile") + addTask(project, taskName, "Compile $taskName", + task = { p: Project -> + context.variant = Variant(pf, bt) + taskCompile(project) + TaskResult() + }) + println("New task: " + Variant(pf, bt).toTask("compile")) + } + } + println("Done") } /** @@ -148,12 +162,12 @@ abstract class JvmCompilerPlugin @Inject constructor( override fun projects() = projects @Task(name = JavaPlugin.TASK_COMPILE, description = "Compile the project") - fun taskCompile(project: Project) = doCompile(project, createCompilerActionInfo(project)) + fun taskCompile(project: Project) = doCompile(project, createCompilerActionInfo(project, context)) @Task(name = JavaPlugin.TASK_JAVADOC, description = "Run Javadoc") - fun taskJavadoc(project: Project) = doJavadoc(project, createCompilerActionInfo(project)) + fun taskJavadoc(project: Project) = doJavadoc(project, createCompilerActionInfo(project, context)) - private fun createCompilerActionInfo(project: Project) : CompilerActionInfo { + private fun createCompilerActionInfo(project: Project, context: KobaltContext) : CompilerActionInfo { copyResources(project, JvmCompilerPlugin.SOURCE_SET_MAIN) val classpath = dependencyManager.calculateDependencies(project, context, projects, @@ -163,7 +177,8 @@ abstract class JvmCompilerPlugin @Inject constructor( val buildDirectory = File(projectDirectory, project.buildDirectory + File.separator + "classes") buildDirectory.mkdirs() - val sourceFiles = files.findRecursively(projectDirectory, project.sourceDirectories.map { File(it) }, + val sourceDirectories = context.variant.sourceDirectories(project) + val sourceFiles = files.findRecursively(projectDirectory, sourceDirectories, { it .endsWith(project.sourceSuffix) }) .map { File(projectDirectory, it).absolutePath } @@ -175,3 +190,30 @@ abstract class JvmCompilerPlugin @Inject constructor( abstract fun doCompile(project: Project, cai: CompilerActionInfo) : TaskResult abstract fun doJavadoc(project: Project, cai: CompilerActionInfo) : TaskResult } + +class Variant(val productFlavorName: String = "", val buildTypeName: String = "") { + val isDefault : Boolean + get() = productFlavorName.isBlank() && buildTypeName.isBlank() + + fun toTask(taskName: String) = taskName + productFlavorName.capitalize() + buildTypeName.capitalize() + + fun sourceDirectories(project: Project) : List { + val sourceDirectories = project.sourceDirectories.map { File(it) } + if (isDefault) return sourceDirectories + else { + val result = arrayListOf() + if (! productFlavorName.isBlank()) { + val dir = File(KFiles.joinDir("src", productFlavorName, project.projectInfo.sourceDirectory)) + log(2, "Adding source for product flavor $productFlavorName: ${dir.path}") + result.add(dir) + } + if (! buildTypeName.isBlank()) { + val dir = File(KFiles.joinDir("src", buildTypeName, project.projectInfo.sourceDirectory)) + log(2, "Adding source for build type $buildTypeName: ${dir.path}") + result.add(dir) + } + result.addAll(sourceDirectories) + return result + } + } +} diff --git a/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt index 81653a92..1ffe91be 100644 --- a/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt +++ b/src/main/kotlin/com/beust/kobalt/internal/ProjectInfo.kt @@ -6,6 +6,8 @@ import java.util.* * Data that is useful for projects to have but should not be specified in the DSL. */ interface IProjectInfo { + /** Used to determine the last directory segment of the flavored sources, e.g. src/main/JAVA */ + val sourceDirectory : String val defaultSourceDirectories: HashSet val defaultTestDirectories: HashSet } diff --git a/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index a162a617..4489df8a 100644 --- a/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -8,6 +8,7 @@ import java.io.File import java.io.IOException import java.nio.file.Files import java.nio.file.Path +import java.nio.file.Paths import java.nio.file.StandardCopyOption class KFiles { @@ -100,23 +101,33 @@ class KFiles { allDirs.addAll(directories.map { File(rootDir, it.path) }) } - allDirs.forEach { - if (! it.exists()) { - log(2, "Couldn't find directory $it") + val seen = hashSetOf() + allDirs.forEach { dir -> + if (! dir.exists()) { + log(2, "Couldn't find directory $dir") } else { - result.addAll(findRecursively(it, function)) + val files = findRecursively(dir, function) + files.map { Paths.get(it) }.forEach { + val rel = Paths.get(dir.path).relativize(it) + if (! seen.contains(rel)) { + result.add(File(dir, rel.toFile().path).path) + seen.add(rel) + } else { + log(2, "Skipped file already seen in previous flavor: $rel") + } + } } } // Return files relative to rootDir - val r = result.map { it.substring(rootDir.absolutePath.length + 1)} + val r = result.map { it.substring(rootDir.path.length + 1)} return r } fun findRecursively(directory: File, function: Function1): List { var result = arrayListOf() directory.listFiles().forEach { - if (it.isFile && function(it.absolutePath)) { - result.add(it.absolutePath) + if (it.isFile && function(it.path)) { + result.add(it.path) } else if (it.isDirectory) { result.addAll(findRecursively(it, function)) } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt index f0ae3ff3..f3ddc6be 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/java/JavaProjectInfo.kt @@ -5,6 +5,7 @@ import com.google.inject.Singleton @Singleton class JavaProjectInfo : IProjectInfo { + override val sourceDirectory = "java" override val defaultSourceDirectories = hashSetOf("src/main/java", "src/main/resources") override val defaultTestDirectories = hashSetOf("src/test/java", "src/test/resources") } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt index 30f9c153..20b573de 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinProjectInfo.kt @@ -5,6 +5,7 @@ import com.google.inject.Singleton @Singleton class KotlinProjectInfo : IProjectInfo { + override val sourceDirectory = "kotlin" override val defaultSourceDirectories = hashSetOf("src/main/kotlin", "src/main/resources") override val defaultTestDirectories = hashSetOf("src/test/kotlin", "src/test/resources") }