Wizard: add basic ktor server template

This commit is contained in:
Ilya Kirillov
2019-12-13 15:42:24 +03:00
parent f927fb3471
commit 56fccce305
14 changed files with 284 additions and 97 deletions
@@ -0,0 +1,29 @@
import io.ktor.application.call
import io.ktor.html.respondHtml
import io.ktor.http.HttpStatusCode
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import ${serverEngine.getImport()}
import kotlinx.html.*
fun HTML.index() {
head {
title("Hello from Ktor!")
}
body {
div {
+"Hello from Ktor"
}
}
}
fun main() {
embeddedServer(${serverEngine.getEngineName()}, port = 8080, host = "127.0.0.1") {
routing {
get("/") {
call.respondHtml(HttpStatusCode.OK, HTML::index)
}
}
}.start(wait = true)
}
@@ -1,8 +1,5 @@
package org.jetbrains.kotlin.tools.projectWizard.core
import org.jetbrains.kotlin.tools.projectWizard.core.entity.Setting
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BodyIR
import java.io.IOException
import java.nio.file.Path
import java.nio.file.Paths
@@ -10,6 +7,12 @@ import kotlin.properties.ReadOnlyProperty
import kotlin.random.Random
import kotlin.reflect.KProperty
inline infix fun <A, B, C> ((A) -> B).andThen(crossinline then: (B) -> C): (A) -> C =
{ then(this(it)) }
@Suppress("NOTHING_TO_INLINE")
inline fun <T> idFunction(): (T) -> T = { it }
operator fun Path.div(other: String): Path =
resolve(other)
@@ -42,24 +45,11 @@ internal inline fun <T> cached(crossinline createValue: (name: String) -> T) = o
@PublishedApi
internal inline fun <reified T> Any?.safeAs(): T? = this as? T
@Suppress("NOTHING_TO_INLINE")
@Suppress("NOTHING_TO_INLINE", "unused")
inline fun Any?.ignore() = Unit
internal fun <T> T.asSingletonList() = listOf(this)
inline fun <reified R> Iterable<*>.filterIsInstanceWith(predicate: (R) -> Boolean): List<R> {
val result = mutableListOf<R>()
for (element in this) {
if (element is R && predicate(element)) {
result += element
}
}
return result
}
fun Path.asAbsolute(prefix: Path) =
if (isAbsolute) this else prefix / this
@DslMarker
annotation class Builder
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScrip
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScriptRepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.DefaultTargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
@@ -115,6 +117,18 @@ data class MultiplatformModulesStructureIR(
}
}
fun MultiplatformModulesStructureIR.updateTargets(
updater: (TargetConfigurationIR) -> TargetConfigurationIR
): MultiplatformModulesStructureIR {
val newTargets = targets.map { target ->
when (target) {
is TargetConfigurationIR -> updater(target)
else -> target
}
}
return copy(targets = newTargets)
}
data class SingleplatformModulesStructureWithSingleModuleIR(
val module: SingleplatformModuleIR,
override val irs: List<BuildSystemIR>
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.BuildFilePrinter
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.CustomMavenRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repository
@@ -12,6 +13,17 @@ data class RepositoryIR(val repository: Repository) : BuildSystemIR {
+repository.type.asGradleName()
+"()"
}
is CustomMavenRepository -> {
sectionCall("maven", needIndent = true) {
assignmentOrCall("url") {
val url = repository.url.quotified
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN -> call("uri") { +url }
GradlePrinter.GradleDsl.GROOVY -> +url
}
}
}
}
else -> Unit
}
else -> Unit
@@ -43,7 +43,7 @@ data class GradleCallIr(
val name: String
) : GradleIR {
override fun GradlePrinter.renderGradle() {
sectionCall(name) {}
call(name, forceBrackets = true) {}
}
}
@@ -90,6 +90,21 @@ data class CompilationAccessIr(
}
}
data class GradleDynamicPropertyAccessIR(val qualifier: BuildSystemIR, val propertyName: String) : GradleIR {
override fun GradlePrinter.renderGradle() {
qualifier.render(this)
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN -> +"[${propertyName.quotified}]"
GradlePrinter.GradleDsl.GROOVY -> +".$propertyName"
}
}
}
data class GradlePropertyAccessIR(val propertyName: String) : GradleIR {
override fun GradlePrinter.renderGradle() {
+propertyName
}
}
interface BuildScriptIR : BuildSystemIR
@@ -3,13 +3,15 @@ package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplat
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.IrsOwner
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.KotlinIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleCallIr
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.withIrs
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
interface MultiplatformIR : GradleIR, KotlinIR
interface TargetIR: MultiplatformIR
interface TargetIR : MultiplatformIR
data class TargetAccessIR(
val type: ModuleSubType,
@@ -23,12 +25,23 @@ data class TargetAccessIR(
}
}
interface TargetConfigurationIR : MultiplatformIR, IrsOwner
interface TargetConfigurationIR : MultiplatformIR, IrsOwner {
val name: String
}
fun TargetConfigurationIR.addWithJavaIntoJvmTarget() = when {
this is DefaultTargetConfigurationIR && targetAccess.type == ModuleSubType.jvm ->
withIrs(GradleCallIr("withJava"))
else -> this
}
data class DefaultTargetConfigurationIR(
val targetAccess: TargetAccessIR,
override val irs: List<BuildSystemIR>
) : TargetConfigurationIR {
override val name: String
get() = targetAccess.nonDefaultName ?: targetAccess.type.name
override fun withReplacedIrs(irs: List<BuildSystemIR>): DefaultTargetConfigurationIR =
copy(irs = irs)
@@ -44,7 +57,7 @@ data class DefaultTargetConfigurationIR(
}
data class NonDefaultTargetConfigurationIR(
val name: String,
override val name: String,
override val irs: List<BuildSystemIR>
) : TargetConfigurationIR {
override fun withReplacedIrs(irs: List<BuildSystemIR>): NonDefaultTargetConfigurationIR =
@@ -54,7 +67,7 @@ data class NonDefaultTargetConfigurationIR(
+name
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN -> +".apply"
GradlePrinter.GradleDsl.GROOVY-> +".with"
GradlePrinter.GradleDsl.GROOVY -> +".with"
}
+" "; inBrackets { irs.listNl() }
}
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
fun runTaskIrs(mainClass: String, classPath: BuildSystemIR? = null) = buildList<BuildSystemIR> {
+ApplicationPluginIR(mainClass)
+GradleSectionIR("application", buildBody {
+GradleAssignmentIR("mainClassName", GradleStringConstIR(mainClass))
})
if (classPath != null) {
+GetGradleTaskIR(
name = "run",
taskClass = "JavaExec",
body = buildBody {
classPath.let { +GradleAssignmentIR("classpath", it) }
}
)
}
}
@@ -7,9 +7,7 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.Groov
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.KotlinDslPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.ConsoleJvmApplicationTemplatePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.KotlinTestTemplatePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.*
object Plugins {
val allPlugins = { context: Context ->
@@ -27,7 +25,9 @@ object Plugins {
// templates
KotlinTestTemplatePlugin(context),
ConsoleJvmApplicationTemplatePlugin(context)
ConsoleJvmApplicationTemplatePlugin(context),
KtorTemplatesPlugin(context),
JsTemplatesPlugin(context)
)
}
}
@@ -0,0 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.templates.*
class KtorTemplatesPlugin(context: Context) : TemplatePlugin(context) {
val addTemplate by addTemplateTask(KtorServerTemplate())
}
@@ -65,20 +65,28 @@ class TemplatesPlugin(context: Context) : Plugin(context) {
}
)
}
}.map { it.fold() }
}.map(List<TemplateApplicationResult>::fold)
}
is SourcesetModuleIR -> {
applyTemplateToSourceset(
module.template,
module,
templateEngine
)
}
is SourcesetModuleIR -> applyTemplateToSourceset(
module.template,
module,
templateEngine
)
}.map { result -> module.withIrs(result.librariesToAdd) to result }
}.map {
val (moduleIrs, results) = it.unzip()
val foldedResults = results.fold()
buildFile.copy(
modules = buildFile.modules.withModules(moduleIrs)
).withIrs(foldedResults.irsToAddToBuildFile)
).withIrs(foldedResults.irsToAddToBuildFile).let { buildFile ->
when (val structure = buildFile.modules) {
is MultiplatformModulesStructureIR ->
buildFile.copy(modules = structure.updateTargets(foldedResults.updateTarget))
else -> buildFile
}
}
}
}
}
@@ -7,10 +7,23 @@ data class DefaultRepository(val type: Type) : Repository {
JCENTER, MAVEN_CENTRAL, GOOGLE, GRADLE_PLUGIN_PORTAL
}
companion object {
companion object {
val JCENTER = DefaultRepository(Type.JCENTER)
val MAVEN_CENTRAL = DefaultRepository(Type.MAVEN_CENTRAL)
val GOOGLE = DefaultRepository(Type.GOOGLE)
val GRADLE_PLUGIN_PORTAL = DefaultRepository(Type.GRADLE_PLUGIN_PORTAL)
}
}
interface CustomMavenRepository : Repository {
val url: String
}
data class BintrayRepository(val repository: String) : CustomMavenRepository {
override val url: String = "https://dl.bintray.com/$repository"
}
object Repositories {
val KTOR_BINTRAY = BintrayRepository("ktor/ktor")
}
@@ -3,11 +3,9 @@ package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.TaskRunningContext
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.*
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.buildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.addWithJavaIntoJvmTarget
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
class ConsoleJvmApplicationTemplate : Template() {
@@ -22,51 +20,12 @@ class ConsoleJvmApplicationTemplate : Template() {
override fun TaskRunningContext.getIrsToAddToBuildFile(
sourceset: SourcesetIR
) = buildList<BuildSystemIR> {
+ApplicationPluginIR("MainKt")
if (buildSystemType.isGradle) {
+GradleSectionIR("application", buildBody {
+GradleAssignmentIR("mainClassName", GradleStringConstIR("MainKt"))
})
}
if (sourceset is SourcesetModuleIR) {
+GetGradleTaskIR(
"run",
"JavaExec",
buildBody {
val compilationAccess =
CompilationAccessIr(sourceset.type.name, sourceset.sourcesetType.name, null)
val classPath = RawGradleIR {
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN -> {
+"with("
compilationAccess.render(this)
+") "
inBrackets {
indent()
+"output.allOutputs + compileDependencyFiles + runtimeDependencyFiles"
}
}
GradlePrinter.GradleDsl.GROOVY -> {
compilationAccess.render(this); +".output.allOutputs + "; nl()
indented {
indent(); compilationAccess.render(this); +".compileDependencyFiles + "; nl()
indent(); compilationAccess.render(this); +".runtimeDependencyFiles"
}
}
}
}
+GradleAssignmentIR(
"classpath",
classPath
)
}
)
}
+runTaskIrs("MainKt")
}
override fun updateTargetIr(sourceset: SourcesetIR, targetConfigurationIR: TargetConfigurationIR): TargetConfigurationIR =
targetConfigurationIR.addWithJavaIntoJvmTarget()
override fun TaskRunningContext.getFileTemplates(sourceset: SourcesetIR) =
buildList<FileTemplateDescriptor> {
+FileTemplateDescriptor("$id/main.kt.vm", sourcesPath("main.kt"))
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.tools.projectWizard.templates
import org.jetbrains.kotlin.tools.projectWizard.core.TaskRunningContext
import org.jetbrains.kotlin.tools.projectWizard.core.buildList
import org.jetbrains.kotlin.tools.projectWizard.core.entity.TemplateSetting
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.addWithJavaIntoJvmTarget
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repositories
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.SourcesetType
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
class KtorServerTemplate : Template() {
override val title: String = "Ktor-based Server"
override val htmlDescription: String = title
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.jvm)
override val sourcesetTypes: Set<SourcesetType> = setOf(SourcesetType.main)
override val id: String = "ktorServer"
override fun TaskRunningContext.getRequiredLibraries(sourceset: SourcesetIR): List<DependencyIR> =
withSettingsOf(sourceset.original) {
buildList {
+ktorArtifactDependency(serverEngine.reference.settingValue.dependencyName)
+ktorArtifactDependency("ktor-html-builder")
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.JCENTER, "org.jetbrains.kotlinx", "kotlinx-html-jvm"),
Version.fromString("0.6.12"),
DependencyType.MAIN
)
}
}
override fun TaskRunningContext.getIrsToAddToBuildFile(sourceset: SourcesetIR): List<BuildSystemIR> = buildList {
+RepositoryIR(Repositories.KTOR_BINTRAY)
+RepositoryIR(DefaultRepository.JCENTER)
+runTaskIrs(mainClass = "ServerKt")
}
override fun updateTargetIr(sourceset: SourcesetIR, targetConfigurationIR: TargetConfigurationIR): TargetConfigurationIR =
targetConfigurationIR.addWithJavaIntoJvmTarget()
override fun TaskRunningContext.getFileTemplates(sourceset: SourcesetIR): List<FileTemplateDescriptor> = listOf(
FileTemplateDescriptor("$id/server.kt.vm", sourcesPath("server.kt"))
)
val serverEngine by enumSetting<KtorServerEngine>("Ktor Server", GenerationPhase.PROJECT_GENERATION)
override val settings: List<TemplateSetting<*, *>> = listOf(serverEngine)
}
private fun ktorArtifactDependency(name: String) = ArtifactBasedLibraryDependencyIR(
MavenArtifact(Repositories.KTOR_BINTRAY, "io.ktor", name),
Version.fromString("1.2.6"),
DependencyType.MAIN
)
@Suppress("MemberVisibilityCanBePrivate")
enum class KtorServerEngine(val engineName: String, val dependencyName: String) : DisplayableSettingItem {
Netty("Netty", dependencyName = "ktor-server-netty"),
Tomcat("Tomcat", dependencyName = "ktor-server-tomcat"),
Jetty("Jetty", dependencyName = "ktor-server-jetty");
override val text: String
get() = engineName.capitalize()
val import: String
get() = "io.ktor.server.${engineName.decapitalize()}.${engineName.capitalize()}"
}
@@ -5,9 +5,8 @@ import org.jetbrains.kotlin.tools.projectWizard.SettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.BuildSystemIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.DependencyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.SourcesetIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.multiplatform.TargetConfigurationIR
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
@@ -52,7 +51,7 @@ fun <T> withSettingsOf(
abstract class Template : SettingsOwner {
override fun <V : Any, T : SettingType<V>> settingDelegate(
final override fun <V : Any, T : SettingType<V>> settingDelegate(
create: (path: String) -> SettingBuilder<V, T>
): ReadOnlyProperty<Any, TemplateSetting<V, T>> = cached { name ->
TemplateSetting(create(name).buildInternal())
@@ -72,6 +71,11 @@ abstract class Template : SettingsOwner {
sourceset: SourcesetIR
): List<BuildSystemIR> = emptyList()
open fun updateTargetIr(
sourceset: SourcesetIR,
targetConfigurationIR: TargetConfigurationIR
): TargetConfigurationIR = targetConfigurationIR
open fun TaskRunningContext.getFileTemplates(sourceset: SourcesetIR): List<FileTemplateDescriptor> = emptyList()
fun TaskRunningContext.applyToSourceset(
@@ -85,7 +89,16 @@ abstract class Template : SettingsOwner {
val librariesToAdd = getRequiredLibraries(sourceset)
val irsToAddToBuildFile = getIrsToAddToBuildFile(sourceset)
val result = TemplateApplicationResult(librariesToAdd, irsToAddToBuildFile)
val targetsUpdater = when (sourceset) {
is SourcesetModuleIR -> { target: TargetConfigurationIR ->
val targetName = sourceset.name.removeSuffix(sourceset.sourcesetType.name.capitalize())
if (target.name == targetName) updateTargetIr(sourceset, target)
else target
}
else -> idFunction()
}
val result = TemplateApplicationResult(librariesToAdd, irsToAddToBuildFile, targetsUpdater)
return getFileTemplates(sourceset).map { fileTemplate ->
val fileText = templateEngine.renderTemplate(fileTemplate, allSettings)
@@ -107,7 +120,7 @@ abstract class Template : SettingsOwner {
)
@Suppress("UNCHECKED_CAST")
override fun <V : DisplayableSettingItem> dropDownSetting(
final override fun <V : DisplayableSettingItem> dropDownSetting(
title: String,
neededAtPhase: GenerationPhase,
parser: Parser<V>,
@@ -121,7 +134,7 @@ abstract class Template : SettingsOwner {
) as ReadOnlyProperty<Any, TemplateSetting<V, DropDownSettingType<V>>>
@Suppress("UNCHECKED_CAST")
override fun stringSetting(
final override fun stringSetting(
title: String,
neededAtPhase: GenerationPhase,
init: StringSettingType.Builder.() -> Unit
@@ -133,7 +146,7 @@ abstract class Template : SettingsOwner {
) as ReadOnlyProperty<Any, TemplateSetting<String, StringSettingType>>
@Suppress("UNCHECKED_CAST")
override fun booleanSetting(
final override fun booleanSetting(
title: String,
neededAtPhase: GenerationPhase,
init: BooleanSettingType.Builder.() -> Unit
@@ -145,7 +158,7 @@ abstract class Template : SettingsOwner {
) as ReadOnlyProperty<Any, TemplateSetting<Boolean, BooleanSettingType>>
@Suppress("UNCHECKED_CAST")
override fun <V : Any> valueSetting(
final override fun <V : Any> valueSetting(
title: String,
neededAtPhase: GenerationPhase,
parser: Parser<V>,
@@ -159,7 +172,7 @@ abstract class Template : SettingsOwner {
) as ReadOnlyProperty<Any, TemplateSetting<V, ValueSettingType<V>>>
@Suppress("UNCHECKED_CAST")
override fun versionSetting(
final override fun versionSetting(
title: String,
neededAtPhase: GenerationPhase,
init: VersionSettingType.Builder.() -> Unit
@@ -171,7 +184,7 @@ abstract class Template : SettingsOwner {
) as ReadOnlyProperty<Any, TemplateSetting<Version, VersionSettingType>>
@Suppress("UNCHECKED_CAST")
override fun <V : Any> listSetting(
final override fun <V : Any> listSetting(
title: String,
neededAtPhase: GenerationPhase,
parser: Parser<V>,
@@ -186,7 +199,7 @@ abstract class Template : SettingsOwner {
@Suppress("UNCHECKED_CAST")
override fun pathSetting(
final override fun pathSetting(
title: String,
neededAtPhase: GenerationPhase,
init: PathSettingType.Builder.() -> Unit
@@ -233,7 +246,7 @@ fun TaskRunningContext.applyTemplateToSourceset(
sourceset: SourcesetIR,
templateEngine: TemplateEngine
): TaskResult<TemplateApplicationResult> = when (template) {
null -> TemplateApplicationResult(emptyList(), emptyList()).asSuccess()
null -> TemplateApplicationResult.EMPTY.asSuccess()
else -> with(template) {
applyToSourceset(templateEngine, sourceset)
}
@@ -242,10 +255,15 @@ fun TaskRunningContext.applyTemplateToSourceset(
data class TemplateApplicationResult(
val librariesToAdd: List<DependencyIR>,
val irsToAddToBuildFile: List<BuildSystemIR>
val irsToAddToBuildFile: List<BuildSystemIR>,
val updateTarget: (TargetConfigurationIR) -> TargetConfigurationIR
) {
companion object {
val EMPTY = TemplateApplicationResult(emptyList(), emptyList())
val EMPTY = TemplateApplicationResult(
librariesToAdd = emptyList(),
irsToAddToBuildFile = emptyList(),
updateTarget = { it }
)
}
}
@@ -255,5 +273,6 @@ fun List<TemplateApplicationResult>.fold() =
operator fun TemplateApplicationResult.plus(other: TemplateApplicationResult) =
TemplateApplicationResult(
librariesToAdd + other.librariesToAdd,
irsToAddToBuildFile + other.irsToAddToBuildFile
irsToAddToBuildFile + other.irsToAddToBuildFile,
updateTarget andThen other.updateTarget
)