Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ platformPlugins =
platformBundledPlugins = org.jetbrains.android, org.jetbrains.kotlin, com.intellij.java

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion=8.13.2
gradleVersion=9.4.1

# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
kotlin.stdlib.default.dependency = false
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,50 +57,86 @@ fun StringBuilder.addLibsPlugin(plugin: Plugin) {
append("${plugin.name} = { id = \"${plugin.id}\", version.ref = \"${plugin.verRef}\" }\n")
}

fun StringBuilder.addGradlePlugin(plugin: Plugin, isProject: Boolean = false) {
fun StringBuilder.addGradlePlugin(plugin: Plugin, isProject: Boolean = false, isKts: Boolean = true) {
val name = plugin.name.replace("-", ".")
val lastPath = if (isProject) " apply false" else ""
append(" alias(libs.plugins.$name)$lastPath\n")
val lastPath = if (isProject) (if (isKts) " apply false" else " apply false") else ""
if (isKts) {
append(" alias(libs.plugins.$name)$lastPath\n")
} else {
append(" alias libs.plugins.$name$lastPath\n")
}
}

fun StringBuilder.addGradleImplementation(library: Library) {
fun StringBuilder.addGradleImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" implementation(libs.$name)\n")
if (isKts) {
append(" implementation(libs.$name)\n")
} else {
append(" implementation libs.$name\n")
}
}

fun StringBuilder.addGradleDetektImplementation(library: Library) {
fun StringBuilder.addGradleDetektImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" detektPlugins(libs.$name)\n")
if (isKts) {
append(" detektPlugins(libs.$name)\n")
} else {
append(" detektPlugins libs.$name\n")
}
}

fun StringBuilder.addGradlePlatformImplementation(library: Library) {
fun StringBuilder.addGradlePlatformImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" implementation(platform(libs.$name))\n")
if (isKts) {
append(" implementation(platform(libs.$name))\n")
} else {
append(" implementation platform(libs.$name)\n")
}
}

fun StringBuilder.addGradleTestImplementation(library: Library) {
fun StringBuilder.addGradleTestImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" testImplementation(libs.$name)\n")
if (isKts) {
append(" testImplementation(libs.$name)\n")
} else {
append(" testImplementation libs.$name\n")
}
}

fun StringBuilder.addGradleAndroidTestImplementation(library: Library) {
fun StringBuilder.addGradleAndroidTestImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" androidTestImplementation(libs.$name)\n")
if (isKts) {
append(" androidTestImplementation(libs.$name)\n")
} else {
append(" androidTestImplementation libs.$name\n")
}
}

fun StringBuilder.addGradleAndroidTestPlatformImplementation(library: Library) {
fun StringBuilder.addGradleAndroidTestPlatformImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" androidTestImplementation(platform(libs.$name))\n")
if (isKts) {
append(" androidTestImplementation(platform(libs.$name))\n")
} else {
append(" androidTestImplementation platform(libs.$name)\n")
}
}

fun StringBuilder.addGradleDebugImplementation(library: Library) {
fun StringBuilder.addGradleDebugImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" debugImplementation(libs.$name)\n")
if (isKts) {
append(" debugImplementation(libs.$name)\n")
} else {
append(" debugImplementation libs.$name\n")
}
}

fun StringBuilder.addKspImplementation(library: Library) {
fun StringBuilder.addKspImplementation(library: Library, isKts: Boolean = true) {
val name = library.libName.replace("-", ".")
append(" ksp(libs.$name)\n")
if (isKts) {
append(" ksp(libs.$name)\n")
} else {
append(" ksp libs.$name\n")
}
}

fun StringBuilder.addDetektBlock() {
Expand All @@ -113,38 +149,61 @@ fun StringBuilder.addDetektBlock() {
append("}\n")
}

fun StringBuilder.addAndroidBlock(packageName: String, minApi: Int, javaJvmVersion: String, isCompose: Boolean) {
fun StringBuilder.addAndroidBlock(
packageName: String,
minApi: Int,
javaJvmVersion: String,
isCompose: Boolean,
isKts: Boolean = true
) {
val assignment = if (isKts) " = " else " "
append("android {\n")
append(" namespace = \"${packageName}\"\n")
append(" compileSdk = 36\n\n")
append(" android.buildFeatures.buildConfig = true\n\n")
append(" namespace${assignment}\"${packageName}\"\n")
append(" compileSdk${assignment}36\n\n")
if (isKts) {
append(" android.buildFeatures.buildConfig = true\n\n")
} else {
append(" buildFeatures {\n")
append(" buildConfig true\n")
append(" }\n\n")
}
append(" defaultConfig {\n")
append(" applicationId = \"${packageName}\"\n")
append(" minSdk = $minApi\n")
append(" targetSdk = 36\n")
append(" versionCode = 1\n")
append(" versionName = \"1.0\"\n\n")
append(" testInstrumentationRunner = \"androidx.test.runner.AndroidJUnitRunner\"\n")
append(" vectorDrawables.useSupportLibrary = true\n")
append(" applicationId${assignment}\"${packageName}\"\n")
append(" minSdk${assignment}$minApi\n")
append(" targetSdk${assignment}36\n")
append(" versionCode${assignment}1\n")
append(" versionName${assignment}\"1.0\"\n\n")
append(" testInstrumentationRunner${assignment}\"androidx.test.runner.AndroidJUnitRunner\"\n")
if (isKts) {
append(" vectorDrawables.useSupportLibrary = true\n")
} else {
append(" vectorDrawables.useSupportLibrary true\n")
}
append(" }\n\n")
append(" buildTypes {\n")
append(" release {\n")
append(" isMinifyEnabled = false\n")
append(" isMinifyEnabled${assignment}false\n")
append(" proguardFiles(\n")
append(" getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n")
append(" \"proguard-rules.pro\"\n")
append(" )\n")
append(" }\n")
append(" }\n")
append(" compileOptions {\n")
append(" sourceCompatibility = JavaVersion.VERSION_$javaJvmVersion\n")
append(" targetCompatibility = JavaVersion.VERSION_$javaJvmVersion\n")
append(" }\n")
append(" kotlin {\n")
append(" compilerOptions.jvmTarget.set(JvmTarget.JVM_$javaJvmVersion)\n")
append(" sourceCompatibility${assignment}JavaVersion.VERSION_$javaJvmVersion\n")
append(" targetCompatibility${assignment}JavaVersion.VERSION_$javaJvmVersion\n")
append(" }\n")
if (isKts) {
append(" kotlin {\n")
append(" compilerOptions.jvmTarget.set(JvmTarget.JVM_$javaJvmVersion)\n")
append(" }\n")
} else {
append(" kotlinOptions {\n")
append(" jvmTarget = '$javaJvmVersion'\n")
append(" }\n")
}
append(" buildFeatures {\n")
if (isCompose) append(" compose = true\n") else append(" viewBinding = true\n")
if (isCompose) append(" compose${assignment}true\n") else append(" viewBinding${assignment}true\n")
append(" }\n")
append(" packaging {\n")
append(" resources {\n")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,17 +653,25 @@ object Utils {
outputDir: VirtualFile,
asset: GeneratorTemplateFile,
) {
Configuration(Configuration.VERSION_2_3_33).apply {
val content = processTemplate(dataModel, asset)
val outputFilePathParts = asset.relativePath.split('/')
val dirPath = outputFilePathParts.dropLast(1).joinToString("/")
val targetDir = VfsUtil.createDirectoryIfMissing(outputDir, dirPath)
?: throw IOException("Failed to create directory: $dirPath")
val outputFile = targetDir.createChildData(this, outputFilePathParts.last())
VfsUtil.saveText(outputFile, content)
}

fun processTemplate(
dataModel: Map<String, Any>,
asset: GeneratorTemplateFile,
): String {
return Configuration(Configuration.VERSION_2_3_33).run {
setClassLoaderForTemplateLoading(this::class.java.classLoader, "fileTemplates/code")
val outputFilePathParts = asset.relativePath.split('/')
val dirPath = outputFilePathParts.dropLast(1).joinToString("/")
val targetDir = VfsUtil.createDirectoryIfMissing(outputDir, dirPath)
?: throw IOException("Failed to create directory: $dirPath")
val outputFile = targetDir.createChildData(this, outputFilePathParts.last())
StringWriter().use { writer ->
val template = "${asset.template.name}.${asset.template.extension}"
getTemplate("${template}.ft").process(dataModel, writer)
VfsUtil.saveText(outputFile, writer.toString())
writer.toString()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class FileWriter() {
modulePathAsString = modulePathAsString,
)

val isKts = settingsGradleFile.name.endsWith(".kts")

filesCreated += createDefaultModuleStructure(
packageName = packageName,
moduleFile = moduleFile,
Expand All @@ -62,6 +64,7 @@ class FileWriter() {
libraryDependencies = libraryDependencies,
pluginDependencies = pluginDependencies,
template = template,
isKts = isKts,
)

showSuccessDialog()
Expand All @@ -79,6 +82,7 @@ class FileWriter() {
libraryDependencies: String = Constants.EMPTY,
pluginDependencies: String = Constants.EMPTY,
template: ModuleTemplate? = null,
isKts: Boolean = true,
): List<File> {
val filesCreated = mutableListOf<File>()

Expand All @@ -89,6 +93,7 @@ class FileWriter() {
dependencies = dependencies,
libraryDependencies = libraryDependencies,
pluginDependencies = pluginDependencies,
isKts = isKts,
)

if (moduleType == Constants.ANDROID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class CMPConfigModel : WizardModel() {
var isDataDomainDiUiEnable: Boolean by mutableStateOf(false)
var screens: List<String> by mutableStateOf(emptyList())
var packageName by mutableStateOf("")
var isKts: Boolean by mutableStateOf(true)

override fun handleFinished() = Unit
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,21 @@ package com.github.cnrture.quickprojectwizard.projectwizard

import com.android.tools.idea.wizard.template.Template
import com.android.tools.idea.wizard.template.WizardTemplateProvider
import com.github.cnrture.quickprojectwizard.projectwizard.gradle.network.getVersions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch

class AndroidStudioTemplateProvider : WizardTemplateProvider() {
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

init {
// Start fetching versions asynchronously as soon as the provider is initialized
scope.launch {
getVersions()
}
}

override fun getTemplates(): List<Template> = listOf(composeMultiplatformTemplate, composeTemplate, xmlTemplate)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,11 @@ val composeMultiplatformTemplate = template {
name = "QuickProjectWizard - CMP"
description = "Quickly create a new project with libraries, tools and screens you want."
minApi = 23
constraints = listOf(TemplateConstraint.AndroidX, TemplateConstraint.Kotlin)
category = Category.Other
formFactor = FormFactor.Generic
screens = listOf(WizardUiContext.NewProject, WizardUiContext.NewProjectExtraDetail)

runBlocking {
try {
getVersions()
} catch (e: Exception) {
println("Failed to fetch versions: ${e.message}")
}
}

val isAndroidEnable = booleanParameter {
name = "Android"
default = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,6 @@ val composeTemplate = template {
formFactor = FormFactor.Mobile
screens = listOf(WizardUiContext.NewProject, WizardUiContext.NewProjectExtraDetail)

runBlocking {
try {
getVersions()
} catch (e: Exception) {
println("Failed to fetch versions: ${e.message}")
}
}

val projectName = defaultPackageNameParameter.value.split(".").last()
.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ val xmlTemplate = template {
formFactor = FormFactor.Mobile
screens = listOf(WizardUiContext.NewProject, WizardUiContext.NewProjectExtraDetail)

runBlocking {
try {
getVersions()
} catch (e: Exception) {
println("Failed to fetch versions: ${e.message}")
}
}

val selectedNetworkLibrary = enumParameter<NetworkLibrary> {
name = "Network Library"
default = NetworkLibrary.None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ class CommonFileGenerator(
ftManager.getCodeTemplate(Template.IDEA_WORKSPACE)
),
GeneratorTemplateFile(
"build.gradle.kts",
if (params.isKts) "build.gradle.kts" else "build.gradle",
ftManager.getCodeTemplate(Template.GRADLE_KTS)
),
GeneratorTemplateFile(
"settings.gradle.kts",
if (params.isKts) "settings.gradle.kts" else "settings.gradle",
ftManager.getCodeTemplate(Template.SETTINGS_GRADLE)
),
GeneratorTemplateFile(
Expand Down
Loading