Wizard: add compose desktop template

This commit is contained in:
Ilya Kirillov
2020-10-01 16:03:32 +03:00
parent d547cb9ee6
commit db069c3264
19 changed files with 444 additions and 4 deletions
@@ -0,0 +1,33 @@
import org.jetbrains.compose.compose
plugins {
id 'org.jetbrains.kotlin.jvm' version 'KOTLIN_VERSION'
id 'org.jetbrains.compose' version '0.1.0-build63'
id 'application'
}
group = 'me.user'
version = '1.0-SNAPSHOT'
repositories {
jcenter()
mavenCentral()
maven { url 'KOTLIN_REPO' }
maven { url 'https://maven.pkg.jetbrains.space/public/p/compose/dev' }
}
dependencies {
implementation compose.desktop.all
}
compileKotlin {
kotlinOptions.jvmTarget = '1.8'
}
compileTestKotlin {
kotlinOptions.jvmTarget = '1.8'
}
application {
mainClassName = 'MainKt'
}
@@ -0,0 +1,30 @@
import org.jetbrains.compose.compose
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "KOTLIN_VERSION"
id("org.jetbrains.compose") version "0.1.0-build63"
application
}
group = "me.user"
version = "1.0-SNAPSHOT"
repositories {
jcenter()
mavenCentral()
maven { url = uri("KOTLIN_REPO") }
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
}
dependencies {
implementation(compose.desktop.all)
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "1.8"
}
application {
mainClassName = "MainKt"
}
@@ -0,0 +1,10 @@
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven { url 'KOTLIN_REPO' }
maven { url 'https://maven.pkg.jetbrains.space/public/p/compose/dev' }
}
}
rootProject.name = 'composeDesktopApplication'
@@ -0,0 +1,10 @@
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
maven { url = uri("KOTLIN_REPO") }
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") }
}
}
rootProject.name = "composeDesktopApplication"
@@ -72,4 +72,14 @@ public class ProjectTemplateBuildFileGenerationTestGenerated extends AbstractPro
public void testNativeApplication() throws Exception {
runTest("libraries/tools/new-project-wizard/new-project-wizard-cli/testData/projectTemplatesBuildFileGeneration/nativeApplication/");
}
@TestMetadata("сomposeMultiplatformApplication")
public void testComposeMultiplatformApplication() throws Exception {
runTest("libraries/tools/new-project-wizard/new-project-wizard-cli/testData/projectTemplatesBuildFileGeneration/composeMultiplatformApplication/");
}
@TestMetadata("composeDesktopApplication")
public void testComposeDesktopApplication() throws Exception {
runTest("libraries/tools/new-project-wizard/new-project-wizard-cli/testData/projectTemplatesBuildFileGeneration/composeDesktopApplication/");
}
}
@@ -39,6 +39,7 @@ project.kind.android=Android
project.kind.kotlin.js=Kotlin/JS
project.kind.multiplatform=Multiplatform
project.kind.singleplatform=JVM
project.kind.compose=JetBrains Compose
project=Project
@@ -147,9 +148,16 @@ project.template.mpp.mobile.lib.title=Mobile Library
project.template.mpp.mobile.lib.description=Library that supports sharing code between iOS and Android.
project.template.compose.desktop.title=Desktop
project.template.compose.desktop.description=A Compose application targeting the desktop JVM platform (Windows, Linux, macOS)
module.template.console.jvm.title=Console Application
module.template.console.jvm.description=Simple "Hello World!" Kotlin/JVM application that works in the console
module.template.compose.desktop.title=Compose Desktop Application
module.template.compose.desktop.description=A Compose application targeting the desktop JVM platform
module.template.mpp.mobile.title=Mobile Application
module.template.mpp.mobile.description=Mobile applications for iOS and Android with Kotlin Multiplatform Mobile, which supports sharing common code between platforms.
@@ -0,0 +1,20 @@
import androidx.compose.desktop.Window
import androidx.compose.foundation.Text
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
fun main() = Window {
var text by remember { mutableStateOf("Hello, World!") }
MaterialTheme {
Button(onClick = {
text = "Hello, Desktop!"
}) {
Text(text)
}
}
}
@@ -14,6 +14,7 @@ object Versions {
val KTOR = version("1.4.0")
val JUNIT = version("4.13")
val JUNIT5 = version("5.6.0")
val JETBRAINS_COMPOSE = version("0.1.0-build63")
object ANDROID {
val ANDROID_MATERIAL = version("1.2.1")
@@ -17,7 +17,7 @@ import java.nio.file.Path
interface FileIR : BuildSystemIR, IrsOwner
data class BuildFileIR(
data class BuildFileIR constructor(
val name: String,
val directoryPath: Path,
val modules: ModulesStructureIR,
@@ -32,9 +32,17 @@ data class ApplicationPluginIR(val mainClass: String) : DefaultBuildSystemPlugin
}
}
data class GradleOnlyPluginByNameIR(@NonNls val pluginId: String, override val priority: Int? = null) : BuildSystemPluginIR, GradleIR {
data class GradleOnlyPluginByNameIR(
@NonNls val pluginId: String,
val version: Version? = null,
override val priority: Int? = null,
) : BuildSystemPluginIR, GradleIR {
override fun GradlePrinter.renderGradle() {
call("id") { +pluginId.quotified }
version?.let { version ->
+" version "
+version.text.quotified
}
}
}
@@ -168,6 +168,19 @@ data class KotlinArbitraryDependencyIR(
override fun withDependencyType(type: DependencyType): KotlinArbitraryDependencyIR = copy(dependencyType = type)
}
data class CustomGradleDependencyDependencyIR(
val dependency: String,
override val dependencyType: DependencyType
) : DependencyIR, GradleIR {
override fun withDependencyType(type: DependencyType): CustomGradleDependencyDependencyIR = copy(dependencyType = type)
override fun GradlePrinter.renderGradle() {
call(dependencyType.getGradleName()) {
+dependency
}
}
}
enum class StdlibType(val artifact: String) {
StdlibJdk7("stdlib-jdk7"),
StdlibJdk8("stdlib-jdk8"),
@@ -33,6 +33,7 @@ object Plugins {
ReactJsTemplatesPlugin(context),
SimpleNodeJsTemplatesPlugin(context),
NativeConsoleApplicationTemplatePlugin(context),
ComposeTemplatesPlugin(context),
MobileMppTemplatePlugin(context),
)
}
@@ -198,7 +198,8 @@ enum class ProjectKind(override val text: String) : DisplayableSettingItem {
Singleplatform(KotlinNewProjectWizardBundle.message("project.kind.singleplatform")),
Multiplatform(KotlinNewProjectWizardBundle.message("project.kind.multiplatform")),
Android(KotlinNewProjectWizardBundle.message("project.kind.android")),
Js(KotlinNewProjectWizardBundle.message("project.kind.kotlin.js"))
Js(KotlinNewProjectWizardBundle.message("project.kind.kotlin.js")),
COMPOSE(KotlinNewProjectWizardBundle.message("project.kind.compose"))
}
fun List<Module>.withAllSubModules(includeSourcesets: Boolean = false): List<Module> = buildList {
@@ -0,0 +1,26 @@
package org.jetbrains.kotlin.tools.projectWizard.plugins.templates
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.PluginSettingsOwner
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PipelineTask
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.templates.compose.ComposeJvmDesktopTemplate
class ComposeTemplatesPlugin(context: Context) : TemplatePlugin(context) {
override val path = pluginPath
override val pipelineTasks: List<PipelineTask> = super.pipelineTasks +
listOf(
addTemplate,
)
companion object : PluginSettingsOwner() {
override val pluginPath = "template.compose"
val addTemplate by pipelineTask(GenerationPhase.PREPARE) {
withAction {
TemplatesPlugin.addTemplate.execute(ComposeJvmDesktopTemplate())
}
}
}
}
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.templates.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.JvmSinglePlatformModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.templates.compose.ComposeJvmDesktopTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.mpp.MobileMppTemplate
sealed class ProjectTemplate : DisplayableSettingItem {
@@ -80,7 +82,8 @@ sealed class ProjectTemplate : DisplayableSettingItem {
FrontendApplicationProjectTemplate,
ReactApplicationProjectTemplate,
FullStackWebApplicationProjectTemplate,
NodeJsApplicationProjectTemplate
NodeJsApplicationProjectTemplate,
ComposeDesktopApplicationProjectTemplate,
)
fun byId(id: String): ProjectTemplate? = ALL.firstOrNull {
@@ -443,4 +446,31 @@ object NodeJsApplicationProjectTemplate : ProjectTemplate() {
)
)
)
}
object ComposeDesktopApplicationProjectTemplate : ProjectTemplate() {
override val title = KotlinNewProjectWizardBundle.message("project.template.compose.desktop.title")
override val description = KotlinNewProjectWizardBundle.message("project.template.compose.desktop.description")
override val id = "composeDesktopApplication"
@NonNls
override val suggestedProjectName = "myComposeDesktopApplication"
override val projectKind = ProjectKind.COMPOSE
override val setsPluginSettings: List<SettingWithValue<*, *>>
get() = listOf(
KotlinPlugin.modules.reference withValue listOf(
Module(
"compose",
JvmSinglePlatformModuleConfigurator,
template = ComposeJvmDesktopTemplate(),
sourcesets = SourcesetType.ALL.map { type ->
Sourceset(type, dependencies = emptyList())
},
subModules = emptyList()
).withConfiguratorSettings(JvmSinglePlatformModuleConfigurator) {
ModuleConfiguratorWithTests.testFramework withValue KotlinTestFramework.NONE
}
)
)
}
@@ -37,10 +37,18 @@ data class BintrayRepository(val repository: String, val base: String = "https:/
get() = "bintray." + repository.replace('/', '.')
}
data class JetBrainsSpace(val repository: String) : CustomMavenRepository {
override val url: String = "https://maven.pkg.jetbrains.space/public/p/$repository"
override val idForMaven: String
get() = "jetbrains." + repository.replace('/', '.')
}
object Repositories {
val KTOR_BINTRAY = BintrayRepository("kotlin/ktor")
val KOTLINX = BintrayRepository("kotlin/kotlinx")
val KOTLIN_JS_WRAPPERS_BINTRAY = BintrayRepository("kotlin/kotlin-js-wrappers")
val KOTLIN_EAP_BINTRAY = BintrayRepository("kotlin/kotlin-eap")
val KOTLIN_DEV_BINTRAY = BintrayRepository("kotlin/kotlin-dev")
val JETBRAINS_COMPOSE_DEV = JetBrainsSpace("compose/dev")
}
@@ -0,0 +1,61 @@
/*
* Copyright 2010-2020 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.compose
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.tools.projectWizard.KotlinNewProjectWizardBundle
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleImportIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.irsList
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.buildSystem.BuildSystemPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
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.templates.FileTemplateDescriptor
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptorWithPath
import org.jetbrains.kotlin.tools.projectWizard.templates.Template
import org.jetbrains.kotlin.tools.projectWizard.templates.asSrcOf
class ComposeJvmDesktopTemplate : Template() {
@NonNls
override val id: String = "composeDesktopTemplate"
override val title: String = KotlinNewProjectWizardBundle.message("module.template.compose.desktop.title")
override val description: String = KotlinNewProjectWizardBundle.message("module.template.compose.desktop.description")
override val moduleTypes: Set<ModuleType> = setOf(ModuleType.jvm)
override fun Writer.getIrsToAddToBuildFile(
module: ModuleIR
) = irsList {
+RepositoryIR(Repositories.JETBRAINS_COMPOSE_DEV)
+RepositoryIR(DefaultRepository.JCENTER)
+GradleOnlyPluginByNameIR("org.jetbrains.compose", version = Versions.JETBRAINS_COMPOSE)
+runTaskIrs("MainKt")
+GradleImportIR("org.jetbrains.compose.compose")
}
override fun Writer.getRequiredLibraries(module: ModuleIR): List<DependencyIR> = listOf(
CustomGradleDependencyDependencyIR("compose.desktop.all", dependencyType = DependencyType.MAIN)
)
override fun Writer.runArbitratyTask(module: ModuleIR): TaskResult<Unit> =
BuildSystemPlugin.pluginRepositoreis.addValues(Repositories.JETBRAINS_COMPOSE_DEV)
override fun updateTargetIr(module: ModuleIR, targetConfigurationIR: TargetConfigurationIR): TargetConfigurationIR =
targetConfigurationIR.addWithJavaIntoJvmTarget()
override fun Reader.getFileTemplates(module: ModuleIR) =
buildList<FileTemplateDescriptorWithPath> {
+(FileTemplateDescriptor("$id/main.kt", "main.kt".asPath()) asSrcOf SourcesetType.main)
}
}