Wizard: add configuration for Android MPP target

This commit is contained in:
Ilya Kirillov
2020-02-20 21:30:59 +03:00
parent 3eca687611
commit 7e22572324
21 changed files with 347 additions and 165 deletions
@@ -1,6 +1,6 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'org.jetbrains.kotlin.android' version '1.3.61'
id 'kotlin-android-extensions' id 'kotlin-android-extensions'
} }
group = 'testGroupId' group = 'testGroupId'
@@ -13,8 +13,8 @@ repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0' implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7'
} }
@@ -1,6 +1,6 @@
plugins { plugins {
id("com.android.application") id("com.android.application")
id("kotlin-android") kotlin("android") version "1.3.61"
id("kotlin-android-extensions") id("kotlin-android-extensions")
} }
group = "testGroupId" group = "testGroupId"
@@ -13,8 +13,8 @@ repositories {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
implementation("androidx.appcompat:appcompat:1.1.0")
implementation("androidx.core:core-ktx:1.1.0") implementation("androidx.core:core-ktx:1.1.0")
implementation("androidx.appcompat:appcompat:1.1.0")
implementation("androidx.constraintlayout:constraintlayout:1.1.3") implementation("androidx.constraintlayout:constraintlayout:1.1.3")
implementation(kotlin("stdlib-jdk7")) implementation(kotlin("stdlib-jdk7"))
} }
@@ -1,14 +1,3 @@
buildscript {
repositories {
gradlePluginPortal()
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61'
}
}
group = 'testGroupId' group = 'testGroupId'
version = '1.0-SNAPSHOT' version = '1.0-SNAPSHOT'
@@ -1,14 +1,3 @@
buildscript {
repositories {
gradlePluginPortal()
google()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:3.2.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61")
}
}
group = "testGroupId" group = "testGroupId"
version = "1.0-SNAPSHOT" version = "1.0-SNAPSHOT"
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="${package.asCodePackage()}"/>
@@ -0,0 +1,16 @@
/*
* 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
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
object Versions {
object GradlePlugins {
val ANDROID = version("3.5.2")
}
}
private fun version(version: String) = Version.fromString(version)
@@ -43,10 +43,9 @@ data class KotlinBuildSystemPluginIR(
override fun BuildFilePrinter.render() = when (this) { override fun BuildFilePrinter.render() = when (this) {
is GradlePrinter -> { is GradlePrinter -> {
when { when (dsl) {
type == Type.android -> call("id") { +"kotlin-android".quotified } GradlePrinter.GradleDsl.KOTLIN -> call("kotlin") { +type.toString().quotified }
dsl == GradlePrinter.GradleDsl.KOTLIN -> call("kotlin") { +type.toString().quotified } GradlePrinter.GradleDsl.GROOVY -> call("id") { +"org.jetbrains.kotlin.$type".quotified }
else -> call("id") { +"org.jetbrains.kotlin.$type".quotified }
} }
version?.let { version?.let {
+" version " +" version "
@@ -20,6 +20,9 @@ inline fun <reified I : BuildSystemIR> IrsOwner.irsOfType(): List<I> =
inline fun <reified I : BuildSystemIR> IrsOwner.irsOfTypeOrNull() = inline fun <reified I : BuildSystemIR> IrsOwner.irsOfTypeOrNull() =
irsOfType<I>().takeIf { it.isNotEmpty() } irsOfType<I>().takeIf { it.isNotEmpty() }
inline fun <reified I : BuildSystemIR> List<BuildSystemIR>.irsOfTypeOrNull() =
filterIsInstance<I>().takeIf { it.isNotEmpty() }
inline fun <reified T : BuildSystemIR> IrsOwner.firstIrOfType() = inline fun <reified T : BuildSystemIR> IrsOwner.firstIrOfType() =
irs.firstOrNull { ir -> ir is T } as T? irs.firstOrNull { ir -> ir is T } as T?
@@ -0,0 +1,42 @@
/*
* 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.ir.buildsystem
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.GradleIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.printer.GradlePrinter
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
interface PluginManagementIR : GradleIR
data class AndroidResolutionStrategyIR(
val androidGradlePluginVersion: Version
) : PluginManagementIR, FreeIR {
override fun GradlePrinter.renderGradle() {
sectionCall("resolutionStrategy", needIndent = true) {
sectionCall("eachPlugin", needIndent = true) {
sectionCall(
"if (requested.id.namespace == ${"com.android".quotified} || requested.id.name == ${"kotlin-android-extensions".quotified})",
needIndent = true
) {
call("useModule", forceBrackets = true) {
when (dsl) {
GradlePrinter.GradleDsl.KOTLIN ->
+"com.android.tools.build:gradle:${androidGradlePluginVersion}".quotified
GradlePrinter.GradleDsl.GROOVY ->
+"com.android.tools.build:gradle:$androidGradlePluginVersion".quotified
}
}
}
}
}
}
}
data class PluginManagementRepositoryIR(val repositoryIR: RepositoryIR) : PluginManagementIR {
override fun GradlePrinter.renderGradle() {
repositoryIR.render(this)
}
}
@@ -7,12 +7,14 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
interface AndroidIR : GradleIR interface AndroidIR : GradleIR
//TODO parematrize //TODO parematrize
data class AndroidConfigIR(val javaPackage: JavaPackage) : AndroidIR, FreeIR { data class AndroidConfigIR(val javaPackage: JavaPackage?) : AndroidIR, FreeIR {
override fun GradlePrinter.renderGradle() { override fun GradlePrinter.renderGradle() {
sectionCall("android", needIndent = true) { sectionCall("android", needIndent = true) {
call("compileSdkVersion") { +"29" }; nlIndented() // TODO dehardcode call("compileSdkVersion") { +"29" }; nlIndented() // TODO dehardcode
sectionCall("defaultConfig", needIndent = true) { sectionCall("defaultConfig", needIndent = true) {
assignmentOrCall("applicationId") { +javaPackage.asCodePackage().quotified }; nlIndented() if (javaPackage != null) {
assignmentOrCall("applicationId") { +javaPackage.asCodePackage().quotified }; nlIndented()
}
call("minSdkVersion") { +"24" }; nlIndented() // TODO dehardcode call("minSdkVersion") { +"24" }; nlIndented() // TODO dehardcode
call("targetSdkVersion") { +"29" }; nlIndented() // TODO dehardcode call("targetSdkVersion") { +"29" }; nlIndented() // TODO dehardcode
assignmentOrCall("versionCode") { +"1" }; nlIndented() assignmentOrCall("versionCode") { +"1" }; nlIndented()
@@ -16,15 +16,19 @@ data class SettingsGradleFileIR(
override fun withReplacedIrs(irs: List<BuildSystemIR>): SettingsGradleFileIR = copy(irs = irs) override fun withReplacedIrs(irs: List<BuildSystemIR>): SettingsGradleFileIR = copy(irs = irs)
override fun GradlePrinter.renderGradle() { override fun GradlePrinter.renderGradle() {
val repositories = irsOfType<RepositoryIR>() irsOfTypeOrNull<PluginManagementIR>()?.let { pluginManagementIrs ->
if (repositories.isNotEmpty()) {
sectionCall("pluginManagement", needIndent = true) { sectionCall("pluginManagement", needIndent = true) {
sectionCall("repositories") { pluginManagementIrs.irsOfTypeOrNull<PluginManagementRepositoryIR>()?.let { repositories ->
repositories.listNl() sectionCall("repositories") {
repositories.listNl()
}
} }
nl()
freeIrs().listNl()
} }
nl(lineBreaks = 2)
} }
nl()
+"rootProject.name = "; +projectName.quotified +"rootProject.name = "; +projectName.quotified
nl(lineBreaks = 2) nl(lineBreaks = 2)
if (subProjects.isNotEmpty()) { if (subProjects.isNotEmpty()) {
@@ -0,0 +1,158 @@
/*
* 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.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.Versions
import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PluginSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
import org.jetbrains.kotlin.tools.projectWizard.plugins.AndroidPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ModuleConfiguratorSetting
import org.jetbrains.kotlin.tools.projectWizard.core.service.kotlinVersionKind
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
import org.jetbrains.kotlin.tools.projectWizard.phases.GenerationPhase
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repository
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
import java.nio.file.Path
interface AndroidModuleConfigurator : ModuleConfigurator,
ModuleConfiguratorWithSettings,
ModuleConfiguratorWithModuleType,
GradleModuleConfigurator {
override val moduleType: ModuleType
get() = ModuleType.jvm
override val greyText: String
get() = "Requires Android SDK"
override fun getPluginSettings(): List<PluginSettingReference<Any, SettingType<Any>>> =
listOf(AndroidPlugin::androidSdkPath.reference)
override fun createBuildFileIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData,
module: Module
) = buildList<BuildSystemIR> {
+GradleOnlyPluginByNameIR(readingContext.createAndroidPlugin(module).pluginName)
+GradleOnlyPluginByNameIR("kotlin-android-extensions")
+AndroidConfigIR(
when (readingContext.createAndroidPlugin(module)) {
AndroidGradlePlugin.APPLICATION -> module.javaPackage(configurationData.pomIr)
AndroidGradlePlugin.LIBRARY -> null
}
)
+createRepositories(configurationData.kotlinVersion).map(::RepositoryIR)
}
fun ReadingContext.createAndroidPlugin(module: Module): AndroidGradlePlugin
override fun ReadingContext.createSettingsGradleIRs(module: Module) = buildList<BuildSystemIR> {
+createRepositories(KotlinPlugin::version.propertyValue).map { PluginManagementRepositoryIR(RepositoryIR(it)) }
+AndroidResolutionStrategyIR(Versions.GradlePlugins.ANDROID)
}
override fun createModuleIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData,
module: Module
): List<BuildSystemIR> =
buildList {
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.GOOGLE, "androidx.core", "core-ktx"),
version = Version.fromString("1.1.0"),
dependencyType = DependencyType.MAIN
)
}
override fun createStdlibType(configurationData: ModuleConfigurationData, module: Module): StdlibType? =
StdlibType.StdlibJdk7
object FileTemplateDescriptors {
val activityMainXml = FileTemplateDescriptor(
"android/activity_main.xml.vm",
"src" / "main" / "res" / "layout" / "activity_main.xml"
)
val androidManifestXml = FileTemplateDescriptor(
"android/AndroidManifest.xml.vm",
"src" / "main" / "AndroidManifest.xml"
)
val androidanifestForLibraryXml = FileTemplateDescriptor(
"android/AndroidManifestLibrary.xml.vm",
"src" / "main" / "AndroidManifest.xml"
)
fun mainActivityKt(javaPackage: JavaPackage) = FileTemplateDescriptor(
"android/MainActivity.kt.vm",
"src" / "main" / "java" / javaPackage.asPath() / "MainActivity.kt"
)
}
companion object {
fun createRepositories(kotlinVersion: Version) = buildList<Repository> {
+DefaultRepository.GRADLE_PLUGIN_PORTAL
+DefaultRepository.GOOGLE
+DefaultRepository.JCENTER
addIfNotNull(kotlinVersion.kotlinVersionKind.repository)
}
}
}
object AndroidTargetConfigurator : TargetConfigurator,
SimpleTargetConfigurator,
AndroidModuleConfigurator,
SingleCoexistenceTargetConfigurator,
ModuleConfiguratorSettings() {
override val moduleSubType = ModuleSubType.android
override val moduleType = ModuleType.jvm
override fun ReadingContext.createAndroidPlugin(module: Module): AndroidGradlePlugin =
withSettingsOf(module) { androidPlugin.reference.settingValue }
override fun getConfiguratorSettings() = buildList<ModuleConfiguratorSetting<*, *>> {
+super.getConfiguratorSettings()
+androidPlugin
}
override fun WritingContext.runArbitraryTask(
configurationData: ModuleConfigurationData,
module: Module,
modulePath: Path
): TaskResult<Unit> = computeM {
val javaPackage = module.javaPackage(configurationData.pomIr)
val settings = mapOf("package" to javaPackage)
TemplatesPlugin::addFileTemplates.execute(
listOf(
FileTemplate(AndroidModuleConfigurator.FileTemplateDescriptors.androidanifestForLibraryXml, modulePath, settings)
)
)
}
val androidPlugin by enumSetting<AndroidGradlePlugin>("Android Library", neededAtPhase = GenerationPhase.PROJECT_GENERATION)
}
enum class AndroidGradlePlugin(override val text: String, val pluginName: String) : DisplayableSettingItem {
APPLICATION("Android Application", "com.android.application"),
LIBRARY("Android Library", "com.android.library")
}
@@ -1,75 +1,62 @@
package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators package org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators
import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.PluginSettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.kotlinVersionKind
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.* import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.AndroidConfigIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScriptDependencyIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.BuildScriptRepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.RawGradleIR
import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact import org.jetbrains.kotlin.tools.projectWizard.library.MavenArtifact
import org.jetbrains.kotlin.tools.projectWizard.plugins.AndroidPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleConfigurationData
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin import org.jetbrains.kotlin.tools.projectWizard.plugins.templates.TemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.settings.JavaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.DefaultRepository
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Repository
import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage import org.jetbrains.kotlin.tools.projectWizard.settings.javaPackage
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplate
import org.jetbrains.kotlin.tools.projectWizard.templates.FileTemplateDescriptor
import java.nio.file.Path import java.nio.file.Path
object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings, object AndroidSinglePlatformModuleConfigurator :
SinglePlatformModuleConfigurator, SinglePlatformModuleConfigurator,
AndroidModuleConfigurator, AndroidModuleConfigurator {
ModuleConfiguratorWithModuleType {
override val moduleType = ModuleType.jvm
override val id = "android" override val id = "android"
override val suggestedModuleName = "android" override val suggestedModuleName = "android"
override val text = "Android" override val text = "Android"
override val greyText = "Requires Android SDK"
private fun createRepositories(configurationData: ModuleConfigurationData) = buildList<Repository> { override fun createBuildFileIRs(
+DefaultRepository.GRADLE_PLUGIN_PORTAL readingContext: ReadingContext,
+DefaultRepository.GOOGLE
+DefaultRepository.JCENTER
addIfNotNull(configurationData.kotlinVersion.kotlinVersionKind.repository)
}
override fun ReadingContext.createBuildFileIRs(
configurationData: ModuleConfigurationData, configurationData: ModuleConfigurationData,
module: Module module: Module
) = ) = buildList<BuildSystemIR> {
buildList<BuildSystemIR> { +super<AndroidModuleConfigurator>.createBuildFileIRs(readingContext, configurationData, module)
+GradleOnlyPluginByNameIR("com.android.application")
// it is explicitly here instead of by `createKotlinPluginIR` as it should be after `com.android.application` // it is explicitly here instead of by `createKotlinPluginIR` as it should be after `com.android.application`
+KotlinBuildSystemPluginIR( +KotlinBuildSystemPluginIR(
KotlinBuildSystemPluginIR.Type.android, KotlinBuildSystemPluginIR.Type.android,
version = null // Version is already present in the parent buildfile version = configurationData.kotlinVersion
) )
+GradleOnlyPluginByNameIR("kotlin-android-extensions") }.sortedBy { ir: BuildSystemIR ->
+AndroidConfigIR(module.javaPackage(configurationData.pomIr)) if (ir is GradleOnlyPluginByNameIR) {
+createRepositories(configurationData).map(::RepositoryIR) // TODO implement proper sort on irs
} // But for now kotlin-android-extensions should be after Android kotlin plugin
if (ir.pluginId == "kotlin-android-extensions") 1 else 0
} else 0
}
override fun createRootBuildFileIrs(configurationData: ModuleConfigurationData) = buildList<BuildSystemIR> { override fun createModuleIRs(
+createRepositories(configurationData).map { BuildScriptRepositoryIR(RepositoryIR(it)) } readingContext: ReadingContext,
+listOf( configurationData: ModuleConfigurationData,
RawGradleIR { call("classpath") { +"com.android.tools.build:gradle:3.2.1".quotified } }, module: Module
RawGradleIR { ) = buildList<BuildSystemIR> {
call("classpath") { +super<AndroidModuleConfigurator>.createModuleIRs(readingContext, configurationData, module)
+"org.jetbrains.kotlin:kotlin-gradle-plugin:${configurationData.kotlinVersion}".quotified
} +ArtifactBasedLibraryDependencyIR(
} MavenArtifact(DefaultRepository.GOOGLE, "androidx.appcompat", "appcompat"),
).map(::BuildScriptDependencyIR) version = Version.fromString("1.1.0"),
dependencyType = DependencyType.MAIN
)
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.GOOGLE, "androidx.constraintlayout", "constraintlayout"),
version = Version.fromString("1.1.3"),
dependencyType = DependencyType.MAIN
)
} }
override fun WritingContext.runArbitraryTask( override fun WritingContext.runArbitraryTask(
@@ -78,56 +65,16 @@ object AndroidSinglePlatformModuleConfigurator : ModuleConfiguratorWithSettings,
modulePath: Path modulePath: Path
): TaskResult<Unit> = computeM { ): TaskResult<Unit> = computeM {
val javaPackage = module.javaPackage(configurationData.pomIr) val javaPackage = module.javaPackage(configurationData.pomIr)
val settings = mapOf("package" to javaPackage)
TemplatesPlugin::addFileTemplates.execute( TemplatesPlugin::addFileTemplates.execute(
listOf( listOf(
FileTemplate(FileTemplateDescriptors.activityMainXml, modulePath, "package" to javaPackage), FileTemplate(AndroidModuleConfigurator.FileTemplateDescriptors.activityMainXml, modulePath, settings),
FileTemplate(FileTemplateDescriptors.androidManifestXml, modulePath, "package" to javaPackage), FileTemplate(AndroidModuleConfigurator.FileTemplateDescriptors.androidManifestXml, modulePath, settings),
FileTemplate(FileTemplateDescriptors.mainActivityKt(javaPackage), modulePath, "package" to javaPackage) FileTemplate(AndroidModuleConfigurator.FileTemplateDescriptors.mainActivityKt(javaPackage), modulePath, settings)
) )
) )
} }
override fun ReadingContext.createModuleIRs(configurationData: ModuleConfigurationData, module: Module): List<BuildSystemIR> = override fun ReadingContext.createAndroidPlugin(module: Module): AndroidGradlePlugin =
buildList { AndroidGradlePlugin.APPLICATION
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.GOOGLE, "androidx.appcompat", "appcompat"),
version = Version.fromString("1.1.0"),
dependencyType = DependencyType.MAIN
)
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.GOOGLE, "androidx.core", "core-ktx"),
version = Version.fromString("1.1.0"),
dependencyType = DependencyType.MAIN
)
+ArtifactBasedLibraryDependencyIR(
MavenArtifact(DefaultRepository.GOOGLE, "androidx.constraintlayout", "constraintlayout"),
version = Version.fromString("1.1.3"),
dependencyType = DependencyType.MAIN
)
}
override fun createStdlibType(configurationData: ModuleConfigurationData, module: Module): StdlibType? =
StdlibType.StdlibJdk7
override fun getPluginSettings(): List<PluginSettingReference<Any, SettingType<Any>>> =
listOf(AndroidPlugin::androidSdkPath.reference)
private object FileTemplateDescriptors {
val activityMainXml = FileTemplateDescriptor(
"android/activity_main.xml.vm",
"src" / "main" / "res" / "layout" / "activity_main.xml"
)
val androidManifestXml = FileTemplateDescriptor(
"android/AndroidManifest.xml.vm",
"src" / "main" / "AndroidManifest.xml"
)
fun mainActivityKt(javaPackage: JavaPackage) = FileTemplateDescriptor(
"android/MainActivity.kt.vm",
"src" / "main" / "java" / javaPackage.asPath() / "MainActivity.kt"
)
}
} }
@@ -35,7 +35,8 @@ object JsSingleplatformModuleConfigurator : JSConfigurator, ModuleConfiguratorWi
version = configurationData.kotlinVersion version = configurationData.kotlinVersion
) )
override fun ReadingContext.createBuildFileIRs( override fun createBuildFileIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData, configurationData: ModuleConfigurationData,
module: Module module: Module
): List<BuildSystemIR> = buildList { ): List<BuildSystemIR> = buildList {
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Path import java.nio.file.Path
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
sealed class ModuleCondifuratorSettingsEnvironment { sealed class ModuleCondifuratorSettingsEnvironment {
@@ -205,13 +204,18 @@ interface ModuleConfigurator : DisplayableSettingItem, EntitiesOwnerDescriptor {
val suggestedModuleName: String? get() = null val suggestedModuleName: String? get() = null
val canContainSubModules: Boolean get() = false val canContainSubModules: Boolean get() = false
fun ReadingContext.createBuildFileIRs( fun createBuildFileIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData, configurationData: ModuleConfigurationData,
module: Module module: Module
): List<BuildSystemIR> = ): List<BuildSystemIR> =
emptyList() emptyList()
fun ReadingContext.createModuleIRs(configurationData: ModuleConfigurationData, module: Module): List<BuildSystemIR> = fun createModuleIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData,
module: Module
): List<BuildSystemIR> =
emptyList() emptyList()
fun createStdlibType(configurationData: ModuleConfigurationData, module: Module): StdlibType? = fun createStdlibType(configurationData: ModuleConfigurationData, module: Module): StdlibType? =
@@ -266,4 +270,8 @@ interface ModuleConfigurator : DisplayableSettingItem, EntitiesOwnerDescriptor {
configurator configurator
} }
} }
}
interface GradleModuleConfigurator : ModuleConfigurator {
fun ReadingContext.createSettingsGradleIRs(module: Module): List<BuildSystemIR> = emptyList()
} }
@@ -39,19 +39,26 @@ interface ModuleConfiguratorWithTests : ModuleConfiguratorWithSettings {
fun defaultTestFramework(): KotlinTestFramework fun defaultTestFramework(): KotlinTestFramework
override fun ReadingContext.createModuleIRs(configurationData: ModuleConfigurationData, module: Module): List<BuildSystemIR> = override fun createModuleIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData,
module: Module
): List<BuildSystemIR> =
withSettingsOf(module) { withSettingsOf(module) {
testFramework.reference.settingValue.dependencyNames.map { dependencyName -> with(readingContext) {
KotlinArbitraryDependencyIR( testFramework.reference.settingValue.dependencyNames.map { dependencyName ->
dependencyName, KotlinArbitraryDependencyIR(
isInMppModule = module.kind dependencyName,
.let { it == ModuleKind.multiplatform || it == ModuleKind.target }, isInMppModule = module.kind
version = KotlinPlugin::version.propertyValue, .let { it == ModuleKind.multiplatform || it == ModuleKind.target },
dependencyType = DependencyType.TEST version = KotlinPlugin::version.propertyValue,
) dependencyType = DependencyType.TEST
)
}
} }
} }
override fun getConfiguratorSettings(): List<ModuleConfiguratorSetting<*, *>> = listOf(testFramework) override fun getConfiguratorSettings(): List<ModuleConfiguratorSetting<*, *>> = listOf(testFramework)
} }
@@ -74,7 +74,8 @@ object NativeForCurrentSystemTarget : NativeTargetConfigurator, SingleCoexistenc
} }
} }
override fun ReadingContext.createBuildFileIRs( override fun createBuildFileIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData, configurationData: ModuleConfigurationData,
module: Module module: Module
): List<BuildSystemIR> = buildList { ): List<BuildSystemIR> = buildList {
@@ -123,10 +123,3 @@ object JvmTargetConfigurator : JvmModuleConfigurator,
} }
} }
} }
object AndroidTargetConfigurator : TargetConfigurator,
SimpleTargetConfigurator,
AndroidModuleConfigurator,
SingleCoexistenceTargetConfigurator {
override val moduleSubType = ModuleSubType.android
}
@@ -43,7 +43,6 @@ enum class TargetJvmVersion(val value: String) : DisplayableSettingItem {
get() = value get() = value
} }
interface AndroidModuleConfigurator : ModuleConfigurator
interface ModuleConfiguratorWithModuleType : ModuleConfigurator { interface ModuleConfiguratorWithModuleType : ModuleConfigurator {
val moduleType: ModuleType val moduleType: ModuleType
@@ -89,11 +88,19 @@ object JvmSinglePlatformModuleConfigurator : JvmModuleConfigurator,
) )
override fun ReadingContext.createBuildFileIRs(configurationData: ModuleConfigurationData, module: Module): List<BuildSystemIR> = override fun createBuildFileIRs(
readingContext: ReadingContext,
configurationData: ModuleConfigurationData,
module: Module
): List<BuildSystemIR> =
buildList { buildList {
+GradleImportIR("org.jetbrains.kotlin.gradle.tasks.KotlinCompile") +GradleImportIR("org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
val targetVersionValue = withSettingsOf(module) { JvmModuleConfigurator.targetJvmVersion.reference.settingValue.value } val targetVersionValue = withSettingsOf(module) {
with(readingContext) {
JvmModuleConfigurator.targetJvmVersion.reference.settingValue.value
}
}
when { when {
configurationData.buildSystemType.isGradle -> { configurationData.buildSystemType.isGradle -> {
+GradleConfigureTaskIR( +GradleConfigureTaskIR(
@@ -3,6 +3,8 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle
import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference import org.jetbrains.kotlin.tools.projectWizard.core.entity.reference
import org.jetbrains.kotlin.tools.projectWizard.core.service.FileSystemWizardService 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.PluginManagementRepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.RepositoryIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.SettingsGradleFileIR import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.gradle.SettingsGradleFileIR
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.render import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.render
@@ -36,6 +38,8 @@ abstract class GradlePlugin(context: Context) : BuildSystemPlugin(context) {
val gradleProperties by listProperty<Pair<String, String>>() val gradleProperties by listProperty<Pair<String, String>>()
val settingsGradleFileIRs by listProperty<BuildSystemIR>()
val createGradlePropertiesFile by pipelineTask(GenerationPhase.PROJECT_GENERATION) { val createGradlePropertiesFile by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
runAfter(KotlinPlugin::createModules) runAfter(KotlinPlugin::createModules)
runBefore(TemplatesPlugin::renderFileTemplates) runBefore(TemplatesPlugin::renderFileTemplates)
@@ -105,6 +109,7 @@ abstract class GradlePlugin(context: Context) : BuildSystemPlugin(context) {
val createSettingsFileTask by pipelineTask(GenerationPhase.PROJECT_GENERATION) { val createSettingsFileTask by pipelineTask(GenerationPhase.PROJECT_GENERATION) {
runAfter(KotlinPlugin::createModules)
runAfter(KotlinPlugin::createPluginRepositories) runAfter(KotlinPlugin::createPluginRepositories)
isAvailable = isGradle isAvailable = isGradle
withAction { withAction {
@@ -115,11 +120,12 @@ abstract class GradlePlugin(context: Context) : BuildSystemPlugin(context) {
if (isNotEmpty()) { if (isNotEmpty()) {
+RepositoryIR(DefaultRepository.MAVEN_CENTRAL) +RepositoryIR(DefaultRepository.MAVEN_CENTRAL)
} }
} }.map(::PluginManagementRepositoryIR)
val settingsGradleIR = SettingsGradleFileIR( val settingsGradleIR = SettingsGradleFileIR(
StructurePlugin::name.settingValue, StructurePlugin::name.settingValue,
allModulesPaths.map { path -> path.joinToString(separator = "") { ":$it" } }, allModulesPaths.map { path -> path.joinToString(separator = "") { ":$it" } },
repositories repositories + GradlePlugin::settingsGradleFileIRs.propertyValue
) )
val buildFileText = createBuildFile().printBuildFile { settingsGradleIR.render(this) } val buildFileText = createBuildFile().printBuildFile { settingsGradleIR.render(this) }
service<FileSystemWizardService>().createFile( service<FileSystemWizardService>().createFile(
@@ -3,8 +3,10 @@ package org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin
import org.jetbrains.kotlin.tools.projectWizard.core.* import org.jetbrains.kotlin.tools.projectWizard.core.*
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.* import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.AndroidSinglePlatformModuleConfigurator import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.AndroidSinglePlatformModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.GradleModuleConfigurator
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.TargetConfigurator import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.TargetConfigurator
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.gradle.GradlePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.* import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.*
import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
@@ -102,7 +104,7 @@ class ModulesToIRsConverter(
+module.sourcesets.flatMap { sourceset -> +module.sourcesets.flatMap { sourceset ->
sourceset.dependencies.map { it.toIR(sourceset.sourcesetType.toDependencyType()) } sourceset.dependencies.map { it.toIR(sourceset.sourcesetType.toDependencyType()) }
} }
with(configurator) { +createModuleIRs(data, module) } with(configurator) { +createModuleIRs(this@createSinglePlatformModule, data, module) }
addIfNotNull( addIfNotNull(
configurator.createStdlibType(data, module)?.let { stdlibType -> configurator.createStdlibType(data, module)?.let { stdlibType ->
KotlinStdlibDependencyIR( KotlinStdlibDependencyIR(
@@ -160,7 +162,7 @@ class ModulesToIRsConverter(
} }
val targetModuleIrs = module.subModules.map { target -> val targetModuleIrs = module.subModules.map { target ->
createTargetSourceset(target, modulePath) createTargetModule(target, modulePath)
} }
return BuildFileIR( return BuildFileIR(
@@ -179,7 +181,8 @@ class ModulesToIRsConverter(
).asSingletonList().asSuccess() ).asSingletonList().asSuccess()
} }
private fun ReadingContext.createTargetSourceset(target: Module, modulePath: Path): MultiplatformModuleIR { private fun ReadingContext.createTargetModule(target: Module, modulePath: Path): MultiplatformModuleIR {
data.writingContext.mutateProjectStructureByModuleConfigurator(target, modulePath)
val sourcesetss = target.sourcesets.map { sourceset -> val sourcesetss = target.sourcesets.map { sourceset ->
val sourcesetName = target.name + sourceset.sourcesetType.name.capitalize() val sourcesetName = target.name + sourceset.sourcesetType.name.capitalize()
val sourcesetIrs = buildList<BuildSystemIR> { val sourcesetIrs = buildList<BuildSystemIR> {
@@ -208,7 +211,7 @@ class ModulesToIRsConverter(
return MultiplatformModuleIR( return MultiplatformModuleIR(
target.name, target.name,
modulePath, modulePath,
with(target.configurator) { createModuleIRs(data, target) }, with(target.configurator) { createModuleIRs(this@createTargetModule, data, target) },
target.template, target.template,
target, target,
sourcesetss sourcesetss
@@ -219,8 +222,13 @@ class ModulesToIRsConverter(
module: Module, module: Module,
modulePath: Path modulePath: Path
): TaskResult<Unit> = with(module.configurator) { ): TaskResult<Unit> = with(module.configurator) {
rootBuildFileIrs += createRootBuildFileIrs(data) compute {
runArbitraryTask(data, module, modulePath) rootBuildFileIrs += createRootBuildFileIrs(data)
runArbitraryTask(data, module, modulePath).ensure()
if (this@with is GradleModuleConfigurator) {
GradlePlugin::settingsGradleFileIRs.addValues(createSettingsGradleIRs(module)).ensure()
}
}
} }
private fun ReadingContext.createBuildFileIRs( private fun ReadingContext.createBuildFileIRs(
@@ -239,7 +247,7 @@ class ModulesToIRsConverter(
} }
} }
addIfNotNull(kotlinPlugin) addIfNotNull(kotlinPlugin)
+with(module.configurator) { createBuildFileIRs(data, module) } +with(module.configurator) { createBuildFileIRs(this@createBuildFileIRs, data, module) }
} }
private fun SourcesetDependency.toIR(type: DependencyType): DependencyIR = with(data) { private fun SourcesetDependency.toIR(type: DependencyType): DependencyIR = with(data) {