Skip to content

Commit 87cc2ee

Browse files
authored
Merge pull request #10 from jakepurple13/trying-something-new
Toml Support and Better Generation
2 parents 621a935 + b3bda61 commit 87cc2ee

38 files changed

Lines changed: 865 additions & 899 deletions

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ plugins {
88
}
99

1010
group = "com.programmersbox"
11-
version = "1.0.23"
11+
version = "1.0.24"
1212

1313
repositories {
1414
mavenCentral()

src/main/kotlin/com/programmersbox/fullmultiplatformcompose/BuilderParams.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class BuilderParams {
2525

2626
class Android {
2727
var minimumSdk: Int by mutableStateOf(24)
28-
var appName: String by mutableStateOf("My Application")
2928
}
3029

3130
class IOS {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.programmersbox.fullmultiplatformcompose
2+
3+
import com.intellij.icons.AllIcons
4+
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptor
5+
import com.intellij.ide.fileTemplates.FileTemplateGroupDescriptorFactory
6+
7+
internal class BuilderTemplateGroup : FileTemplateGroupDescriptorFactory {
8+
override fun getFileTemplatesDescriptor(): FileTemplateGroupDescriptor {
9+
val root = FileTemplateGroupDescriptor("COMPOSE", AllIcons.Nodes.Module)
10+
11+
with(root) {
12+
addTemplate(COMPOSE_PROJECT_GRADLE)
13+
addTemplate(ANDROID_BUILD)
14+
addTemplate(ANDROID_MAINACTIVITY)
15+
addTemplate(ANDROID_MANIFEST)
16+
addTemplate(COMMON_APP)
17+
addTemplate(COMMON_BUILD)
18+
addTemplate(COMMON_PLATFORM)
19+
addTemplate(DEFAULT_PLATFORM)
20+
addTemplate(DESKTOP_BUILD)
21+
addTemplate(DESKTOP_MAIN)
22+
addTemplate(IDEA_GRADLE)
23+
addTemplate(IOS_IOSAPP)
24+
addTemplate(IOS_PLATFORM)
25+
addTemplate(IOS_PLATFORM3)
26+
addTemplate(IOS_PROJECT)
27+
addTemplate(JS_BUILD)
28+
addTemplate(JS_MAIN)
29+
addTemplate(PROJECT_GRADLE)
30+
addTemplate(PROJECT_SETTINGS)
31+
addTemplate(COMMON_ANDROID_MANIFEST)
32+
addTemplate(PROJECT_TOML)
33+
}
34+
35+
return root
36+
}
37+
38+
companion object {
39+
const val COMPOSE_PROJECT_GRADLE = "project_build.gradle.kts"
40+
const val ANDROID_BUILD = "android_build.gradle.kts"
41+
const val ANDROID_MAINACTIVITY = "android_mainactivity.kt"
42+
const val ANDROID_MANIFEST = "android_manifest.xml"
43+
const val COMMON_APP = "common_app.kt"
44+
const val COMMON_BUILD = "common_build.gradle.kts"
45+
const val COMMON_PLATFORM = "common_platform.kt"
46+
const val DEFAULT_PLATFORM = "default_platform.kt"
47+
const val DESKTOP_BUILD = "desktop_build.gradle.kts"
48+
const val DESKTOP_MAIN = "desktop_main.kt"
49+
const val IDEA_GRADLE = "idea_gradle.xml"
50+
const val IOS_IOSAPP = "ios_iosapp.swift"
51+
const val IOS_PLATFORM = "ios_platform.kt"
52+
const val IOS_PLATFORM3 = "ios_platform3.kt"
53+
const val IOS_PROJECT = "ios_project.pbxproj"
54+
const val JS_BUILD = "js_build.gradle.kts"
55+
const val JS_MAIN = "js_main.js.kt"
56+
const val PROJECT_GRADLE = "project_gradle.properties"
57+
const val PROJECT_SETTINGS = "project_settings.gradle.kts"
58+
const val COMMON_ANDROID_MANIFEST = "common_android_manifest.xml"
59+
const val PROJECT_TOML = "libs.versions.toml"
60+
}
61+
}
Lines changed: 96 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,61 @@
1+
@file:Suppress("UnstableApiUsage")
2+
13
package com.programmersbox.fullmultiplatformcompose
24

5+
import com.intellij.ide.fileTemplates.FileTemplateManager
36
import com.intellij.ide.projectWizard.ProjectSettingsStep
4-
import com.intellij.ide.util.projectWizard.ModuleBuilder
7+
import com.intellij.ide.starters.local.*
8+
import com.intellij.ide.starters.local.wizard.StarterInitialStep
9+
import com.intellij.ide.starters.shared.KOTLIN_STARTER_LANGUAGE
10+
import com.intellij.ide.starters.shared.StarterLanguage
11+
import com.intellij.ide.starters.shared.StarterProjectType
512
import com.intellij.ide.util.projectWizard.ModuleWizardStep
6-
import com.intellij.ide.util.projectWizard.SettingsStep
713
import com.intellij.ide.util.projectWizard.WizardContext
8-
import com.intellij.openapi.Disposable
9-
import com.intellij.openapi.application.ApplicationManager
1014
import com.intellij.openapi.module.ModuleType
1115
import com.intellij.openapi.project.Project
12-
import com.intellij.openapi.roots.ModifiableRootModel
16+
import com.intellij.openapi.project.ProjectManager
1317
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
1418
import com.intellij.openapi.util.io.FileUtil
1519
import com.intellij.openapi.vfs.LocalFileSystem
1620
import com.intellij.openapi.vfs.VirtualFile
17-
import com.intellij.psi.PsiManager
21+
import com.intellij.pom.java.LanguageLevel
1822
import com.intellij.psi.codeStyle.CodeStyleManager
19-
import com.intellij.psi.impl.file.PsiDirectoryFactory
20-
import com.intellij.ui.components.Link
23+
import com.intellij.util.lang.JavaVersion
2124
import com.programmersbox.fullmultiplatformcompose.generators.CommonGenerator
25+
import com.programmersbox.fullmultiplatformcompose.generators.PACKAGE_NAME
26+
import com.programmersbox.fullmultiplatformcompose.generators.SHARED_NAME
27+
import com.programmersbox.fullmultiplatformcompose.steps.ComposeStarterStep
2228
import com.programmersbox.fullmultiplatformcompose.steps.PlatformOptionsStep
2329
import com.programmersbox.fullmultiplatformcompose.utils.NetworkVersions
24-
import com.programmersbox.fullmultiplatformcompose.utils.backgroundTask
25-
import com.programmersbox.fullmultiplatformcompose.utils.runGradle
30+
import kotlinx.coroutines.runBlocking
31+
import org.jetbrains.kotlin.idea.KotlinIcons
2632
import org.jetbrains.kotlin.idea.core.util.toPsiFile
27-
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
28-
import org.jetbrains.skiko.OS
29-
import org.jetbrains.skiko.hostOs
30-
import java.awt.Desktop
31-
import java.awt.event.ItemEvent
3233
import java.io.File
33-
import java.net.URI
34-
import javax.swing.JCheckBox
35-
import javax.swing.JLabel
36-
import javax.swing.JSeparator
34+
import javax.swing.Icon
3735

38-
class BuilderWizardBuilder : ModuleBuilder() {
36+
/**
37+
* Following https://github.com/JetBrains/intellij-community/blob/master/plugins/kotlin/project-wizard/compose/src/org/jetbrains/kotlin/tools/composeProjectWizard/ComposeModuleBuilder.kt
38+
*/
39+
class BuilderWizardBuilder : StarterModuleBuilder() {
3940
val params = BuilderParams()
4041

4142
override fun getModuleType(): ModuleType<*> = BuilderModuleType()
43+
override fun getNodeIcon(): Icon = KotlinIcons.Wizard.MULTIPLATFORM
44+
45+
override fun getPresentableName(): String = "Full Multiplatform Compose"
46+
47+
override fun getProjectTypes(): List<StarterProjectType> = emptyList()
48+
49+
override fun getMinJavaVersion(): JavaVersion = LanguageLevel.JDK_11.toJavaVersion()
50+
51+
override fun getStarterPack(): StarterPack = StarterPack(
52+
"compose",
53+
listOf(
54+
Starter("compose", "Compose", getDependencyConfig("/starters/compose.pom"), emptyList())
55+
)
56+
)
4257

43-
override fun setupRootModel(modifiableRootModel: ModifiableRootModel) {
58+
/*override fun setupRootModel(modifiableRootModel: ModifiableRootModel) {
4459
val root = createAndGetRoot() ?: return
4560
modifiableRootModel.addContentEntry(root)
4661
modifiableRootModel.sdk = moduleJdk
@@ -69,14 +84,9 @@ class BuilderWizardBuilder : ModuleBuilder() {
6984
)
7085
7186
formatCode(modifiableRootModel.project, root)
72-
73-
/*BuilderConfigurationFactory.createConfigurations(
74-
modifiableRootModel.project,
75-
params
76-
)*/
7787
}
7888
}
79-
}
89+
}*/
8090

8191
private fun formatCode(project: Project, root: VirtualFile) {
8292
val csm = CodeStyleManager.getInstance(project)
@@ -91,73 +101,85 @@ class BuilderWizardBuilder : ModuleBuilder() {
91101
return LocalFileSystem.getInstance().refreshAndFindFileByPath(File(path).apply { mkdirs() }.absolutePath)
92102
}
93103

94-
private fun installGradleWrapper(project: Project) {
95-
project.runGradle("wrapper --gradle-version 7.5.1 --distribution-type all")
96-
}
97-
98-
override fun getCustomOptionsStep(context: WizardContext?, parentDisposable: Disposable?): ModuleWizardStep {
99-
return ProjectSettingsStep(context)
104+
override fun createOptionsStep(contextProvider: StarterContextProvider): StarterInitialStep {
105+
return ComposeStarterStep(this, params, contextProvider)
100106
}
101107

102108
override fun createWizardSteps(
103-
wizardContext: WizardContext,
104-
modulesProvider: ModulesProvider
109+
context: WizardContext,
110+
modulesProvider: ModulesProvider,
105111
): Array<ModuleWizardStep> {
106112
return arrayOf(
107113
PlatformOptionsStep(this),
108114
)
109115
}
110116

111-
override fun modifySettingsStep(settingsStep: SettingsStep): ModuleWizardStep? {
112-
settingsStep.addCheckboxItem("Include Android", params.hasAndroid) { params.hasAndroid = it }
113-
if (hostOs == OS.MacOS) {
114-
settingsStep.addCheckboxItem("Include iOS", params.hasiOS) { params.hasiOS = it }
115-
}
116-
settingsStep.addCheckboxItem("Include Desktop", params.hasDesktop) { params.hasDesktop = it }
117-
settingsStep.addCheckboxItem("Include Web", params.hasWeb) { params.hasWeb = it }
118-
settingsStep.addDivider()
119-
settingsStep.addCheckboxItem("Use Material 3", params.compose.useMaterial3) { params.compose.useMaterial3 = it }
117+
override fun getAssets(starter: Starter): List<GeneratorAsset> {
118+
val ftManager = FileTemplateManager.getInstance(ProjectManager.getInstance().defaultProject)
119+
val standardAssetsProvider = StandardAssetsProvider()
120120

121-
settingsStep.addDivider()
121+
return mutableListOf<GeneratorAsset>().apply {
122+
val packageName = starterContext.group.split(".").joinToString("/")
122123

123-
settingsStep.addCheckboxItem("Use Koin for Dependency Injection", params.library.useKoin) { params.library.useKoin = it }
124-
settingsStep.addCheckboxItem("Use Ktor for HTTP client apps", params.library.useKtor) { params.library.useKtor = it }
124+
operator fun GeneratorAsset.unaryPlus() = add(this)
125125

126-
settingsStep.addDivider()
126+
addAll(standardAssetsProvider.getGradlewAssets())
127127

128-
settingsStep.addCheckboxItem(
129-
"Get latest library versions from remote source?",
130-
params.remoteVersions
131-
) { params.remoteVersions = it }
132-
settingsStep.addSettingsField("", JLabel().apply { text = "The source is from this plugin's GitHub Repo." })
133-
134-
settingsStep.addExpertField(
135-
"GitHub:",
136-
Link(NetworkVersions.githubRepoUrl) { Desktop.getDesktop().browse(URI(NetworkVersions.githubRepoUrl)) }
137-
)
128+
if (starterContext.isCreatingNewProject) {
129+
addAll(standardAssetsProvider.getGradleIgnoreAssets())
130+
}
138131

139-
return super.modifySettingsStep(settingsStep)
132+
CommonGenerator(params, starterContext).generate(this, ftManager, packageName)
133+
}
140134
}
141135

142-
private fun SettingsStep.addDivider() = addSettingsField("", JSeparator())
143-
144-
private fun SettingsStep.addCheckboxItem(
145-
label: String,
146-
isChecked: Boolean,
147-
selectedChangeListener: (Boolean) -> Unit
148-
) {
149-
addSettingsField(
150-
"",
151-
JCheckBox().apply {
152-
text = label
153-
isSelected = isChecked
154-
addItemListener { selectedChangeListener(it.stateChange == ItemEvent.SELECTED) }
155-
}
136+
override fun getTemplateProperties(): Map<String, Any> {
137+
val versions = runBlocking { NetworkVersions().getVersions(params.remoteVersions) }
138+
val sanitizedPackageName = sanitizePackage(starterContext.artifact)
139+
return mapOf(
140+
PACKAGE_NAME to starterContext.group,
141+
SHARED_NAME to params.sharedName,
142+
"APP_NAME" to starterContext.artifact,
143+
params.hasAndroid(),
144+
params.hasDesktop(),
145+
params.hasIOS(),
146+
params.hasWeb(),
147+
"USE_MATERIAL3" to params.compose.useMaterial3,
148+
"COMPOSE" to versions.composeVersion,
149+
"KOTLIN" to versions.kotlinVersion,
150+
"AGP" to versions.agpVersion,
151+
"KTOR" to versions.ktor,
152+
"KOIN" to versions.koin,
153+
"androidxAppCompat" to versions.androidxAppCompat,
154+
"androidxCore" to versions.androidxCore,
155+
"LAST_PACKAGE_NAME" to sanitizedPackageName,
156+
"MINSDK" to params.android.minimumSdk,
157+
"USE_KTOR" to params.library.useKtor,
158+
"USE_KOIN" to params.library.useKoin,
156159
)
157160
}
158161

162+
override fun getBuilderId(): String = BuilderModuleType.ID
163+
164+
override fun getDescription(): String = """
165+
A project wizard to create a compose multiplatform application in your choice of android, ios, web,
166+
and/or desktop!
167+
""".trimIndent()
168+
159169
override fun getIgnoredSteps(): MutableList<Class<out ModuleWizardStep>> {
160170
return mutableListOf(ProjectSettingsStep::class.java)
161171
}
162172

163-
}
173+
override fun getLanguages(): List<StarterLanguage> = listOf(KOTLIN_STARTER_LANGUAGE)
174+
175+
override fun setupModule(module: com.intellij.openapi.module.Module) {
176+
starterContext.starter = starterContext.starterPack.starters.first()
177+
starterContext.starterDependencyConfig = loadDependencyConfig()[starterContext.starter?.id]
178+
super.setupModule(module)
179+
}
180+
}
181+
182+
private fun BuilderParams.hasAndroid() = "HAS_ANDROID" to hasAndroid
183+
private fun BuilderParams.hasIOS() = "HAS_IOS" to hasiOS
184+
private fun BuilderParams.hasWeb() = "HAS_WEB" to hasWeb
185+
private fun BuilderParams.hasDesktop() = "HAS_DESKTOP" to hasDesktop

0 commit comments

Comments
 (0)