Skip to content

Commit f5e4774

Browse files
committed
feat: enhance project analysis and build cleanup error handling
- Add NDK version, CMake version, and platform list to project overview - Implement platform detection logic for Android, JVM, JS, WASM, iOS, and Server - Update UI to display additional project metadata using a FlowRow layout - Enhance build folder deletion to return and display error messages - Refactor JDK path discovery logic for better readability and OS handling - Update multi-module detection threshold in project analysis
1 parent 598aec5 commit f5e4774

9 files changed

Lines changed: 85 additions & 33 deletions

File tree

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/core/utility/DefaultPath.kt

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ fun getDefaultJetbrainsFolderPaths(): List<String> {
4747
"$userHome\\AppData\\Local\\JetBrains",
4848
"$userHome\\AppData\\Roaming\\JetBrains"
4949
)
50+
5051
os.contains("mac") -> listOf(
5152
"$userHome/Library/Caches/JetBrains",
5253
"$userHome/Library/Logs/JetBrains",
@@ -89,33 +90,27 @@ fun getDefaultJdkFolderPaths(): List<String> {
8990
val userHome = System.getProperty("user.home")
9091
val os = System.getProperty("os.name").lowercase()
9192

92-
val defaultPaths = mutableListOf<String>()
93-
when {
94-
os.contains("mac") -> defaultPaths.addAll(
93+
return when {
94+
os.contains("mac") ->
9595
listOf(
9696
"$userHome/Library/Java/JavaVirtualMachines",
9797
"/Library/Java/JavaVirtualMachines",
9898
"$userHome/.gradle/jdks",
9999
)
100-
)
101100

102-
os.contains("windows") -> defaultPaths.addAll(
101+
os.contains("windows") ->
103102
listOf(
104103
"C:\\Program Files\\Java",
105104
"C:\\Program Files\\Eclipse Adoptium",
106105
"$userHome\\.gradle\\jdks"
107106
)
108-
)
109107

110-
else -> defaultPaths.addAll(
108+
else ->
111109
listOf(
112110
"/usr/lib/jvm",
113111
"$userHome/.gradle/jdks",
114112
"$userHome/.sdkman/candidates/java"
115113
)
116-
)
117114
}
118-
119-
return defaultPaths
120115
}
121116

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/data/models/project/ProjectOverviewInfo.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@ data class ProjectOverviewInfo(
1111
val compileSdkVersion: String?,
1212
val targetSdkVersion: String?,
1313
val minSdkVersion: String?,
14-
val isMultiModule: Boolean
14+
val isMultiModule: Boolean,
15+
val ndkVersion: String?,
16+
val cmakeVersion: String?,
17+
val platformList: List<String>,
1518
)

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/data/repository/cleanbuild/CleanBuildRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ interface CleanBuildRepository {
99
updateProgress: (progress: Float, status: String) -> Unit
1010
): List<ProjectBuildInfo>
1111

12-
suspend fun deleteBuildFolder(path: String): Boolean
12+
suspend fun deleteBuildFolder(path: String): Pair<Boolean, String?>
1313

1414
}
1515

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/data/repository/cleanbuild/CleanBuildRepositoryImpl.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,13 @@ class CleanBuildRepositoryImpl : CleanBuildRepository {
106106
}
107107

108108

109-
override suspend fun deleteBuildFolder(path: String): Boolean {
109+
override suspend fun deleteBuildFolder(path: String): Pair<Boolean, String?> {
110110
return try {
111111
val file = File(path)
112-
if (file.exists() && file.isDirectory) {
113-
file.deleteRecursively()
114-
} else {
115-
false
116-
}
112+
Pair(file.deleteRecursively(), null)
117113
} catch (e: Exception) {
118114
AppLogger.e(TAG, e) { "Error deleting folder: $path" }
119-
false
115+
Pair(false, e.message)
120116
}
121117
}
122118
}

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/data/repository/project/ProjectAnalyzerRepositoryImpl.kt

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ class ProjectAnalyzerRepositoryImpl : ProjectAnalyzerRepository {
7373
settingsGradleFileInfo = settingsGradleFileInfo,
7474
gradleWrapperPropertiesFileInfo = gradleWrapperPropertiesFileInfo,
7575
versionCatalog = versionCatalog,
76-
moduleBuildFileInfos = moduleBuildFileInfos,
77-
isMultiModule = moduleBuildFileInfos.size > 1
76+
moduleBuildFileInfos = moduleBuildFileInfos
7877
)
7978

8079
updateProgress(0.5f, "Analyzing plugins...")
@@ -525,8 +524,7 @@ class ProjectAnalyzerRepositoryImpl : ProjectAnalyzerRepository {
525524
settingsGradleFileInfo: SettingsGradleFileInfo?,
526525
gradleWrapperPropertiesFileInfo: GradleWrapperPropertiesFileInfo?,
527526
versionCatalog: VersionCatalog?,
528-
moduleBuildFileInfos: List<ModuleBuildFileInfo>,
529-
isMultiModule: Boolean
527+
moduleBuildFileInfos: List<ModuleBuildFileInfo>
530528
): ProjectOverviewInfo {
531529
AppLogger.d(TAG) { "Finding project info" }
532530

@@ -637,20 +635,61 @@ class ProjectAnalyzerRepositoryImpl : ProjectAnalyzerRepository {
637635
return subModuleBuildFileInfo?.let { regex.find(it.content)?.groupValues?.get(1) }
638636
}
639637

638+
fun extractNdkVersion(): String? {
639+
val regex = Regex("""ndkVersion\s*=?\s*["']?(\d+\.\d+\.\d+)["']?""")
640+
val subModuleBuildFileInfo =
641+
moduleBuildFileInfos.find { regex.containsMatchIn(it.content) }
642+
return subModuleBuildFileInfo?.let { regex.find(it.content)?.groupValues?.get(1) }
643+
}
644+
645+
fun extractCmakeVersion(): String? {
646+
val regex = Regex("""version\s*=?\s*["']?(\d+\.\d+\.\d+)["']?""")
647+
val subModuleBuildFileInfo =
648+
moduleBuildFileInfos.find { regex.containsMatchIn(it.content) }
649+
return subModuleBuildFileInfo?.let { regex.find(it.content)?.groupValues?.get(1) }
650+
}
651+
652+
fun getPlatforms(): List<String> {
653+
val platforms = mutableSetOf<String>()
654+
655+
val androidRegex = Regex("""\bandroid(Target)?\s*([({])""")
656+
val jvmRegex = Regex("""\bjvm\s*([({])""")
657+
val jsRegex = Regex("""\bjs\s*([({])""")
658+
val wasmRegex = Regex("""\bwasm(Js)?\s*([({])""")
659+
val iosRegex = Regex("""\bios(Arm64|X64|SimulatorArm64)?\s*([({])""")
660+
val serverRegex = Regex("""\bapplication\s*([({])""")
661+
662+
moduleBuildFileInfos.forEach { file ->
663+
val content = file.content
664+
665+
if (androidRegex.containsMatchIn(content)) platforms.add("ANDROID")
666+
if (jvmRegex.containsMatchIn(content)) platforms.add("JVM")
667+
if (jsRegex.containsMatchIn(content)) platforms.add("JS")
668+
if (wasmRegex.containsMatchIn(content)) platforms.add("WASM")
669+
if (iosRegex.containsMatchIn(content)) platforms.add("IOS")
670+
if (serverRegex.containsMatchIn(content)) platforms.add("SERVER")
671+
}
672+
673+
return platforms.toList()
674+
}
675+
640676
val sizeBytes = Utils.calculateFolderSize(projectDir)
641677

642678
val projectOverviewInfo = ProjectOverviewInfo(
643679
projectPath = projectDir.absolutePath,
644680
projectName = findProjectName(),
645681
sizeReadable = Utils.formatSize(sizeBytes),
646682
totalSizeBytes = sizeBytes,
647-
isMultiModule = isMultiModule,
683+
isMultiModule = moduleBuildFileInfos.size > 2,
648684
gradleVersion = findGradleVersion(),
649685
kotlinVersion = extractKotlinVersion(),
650686
androidGradlePluginVersion = extractAgpVersion(),
651687
targetSdkVersion = extractTargetSdk(),
652688
minSdkVersion = extractMinSdk(),
653-
compileSdkVersion = extractCompileSdk()
689+
compileSdkVersion = extractCompileSdk(),
690+
ndkVersion = extractNdkVersion(),
691+
cmakeVersion = extractCmakeVersion(),
692+
platformList = getPlatforms()
654693
)
655694
AppLogger.d(TAG) { "Found project info." }
656695
AppLogger.i(TAG) {
@@ -661,6 +700,8 @@ class ProjectAnalyzerRepositoryImpl : ProjectAnalyzerRepository {
661700
Gradle Version: ${projectOverviewInfo.gradleVersion} Kotlin Version: ${projectOverviewInfo.kotlinVersion}
662701
isMultiModule: ${projectOverviewInfo.isMultiModule} Android Gradle Plugin Version: ${projectOverviewInfo.androidGradlePluginVersion}
663702
Compile SDK Version: ${projectOverviewInfo.compileSdkVersion} Target SDK Version: ${projectOverviewInfo.targetSdkVersion} Min SDK Version: ${projectOverviewInfo.minSdkVersion}
703+
Ndk Version: ${projectOverviewInfo.ndkVersion} CMake Version: ${projectOverviewInfo.cmakeVersion}
704+
Platforms: ${projectOverviewInfo.platformList}
664705
""".trimIndent()
665706
}
666707
return projectOverviewInfo

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/presentation/screen/cleanbuild/CleanBuildUiState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ data class CleanBuildUiState(
7373
data class DeletionProgress(
7474
val moduleBuild: ModuleBuild,
7575
val status: DeletionStatus,
76+
val error: String? = null,
7677
)
7778

7879

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/presentation/screen/cleanbuild/CleanBuildViewModel.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,16 @@ class CleanBuildViewModel(
181181
}
182182

183183
// Perform deletion
184-
val success = repository.deleteBuildFolder(module.path)
185-
184+
val (success, errorMessage) = repository.deleteBuildFolder(module.path)
186185
// Update status to SUCCESS or FAILED
187186
_uiState.update { state ->
188187
state.copy(
189188
deletionProgressList = state.deletionProgressList.map {
190189
if (it.moduleBuild.uniqueId == module.uniqueId) {
191-
it.copy(status = if (success) DeletionStatus.SUCCESS else DeletionStatus.FAILED)
190+
it.copy(
191+
status = if (success) DeletionStatus.SUCCESS else DeletionStatus.FAILED,
192+
error = errorMessage
193+
)
192194
} else it
193195
}
194196
)

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/presentation/screen/cleanbuild/components/DeletionProgressDialog.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ private fun DeletionProgressItem(progress: DeletionProgress) {
301301
else
302302
Modifier
303303
)
304+
if (progress.error != null) {
305+
Text(
306+
text = "Error msg: " + progress.error,
307+
style = MaterialTheme.typography.bodySmall,
308+
color = MaterialTheme.colorScheme.error,
309+
maxLines = 1,
310+
)
311+
}
304312
}
305313

306314
// Status and size

composeApp/src/jvmMain/kotlin/com/meet/dev/analyzer/presentation/screen/project/components/ProjectOverviewTabContent.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.meet.dev.analyzer.presentation.screen.project.components
33
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.BoxWithConstraints
55
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.FlowRow
67
import androidx.compose.foundation.layout.PaddingValues
78
import androidx.compose.foundation.layout.Row
89
import androidx.compose.foundation.layout.Spacer
@@ -13,10 +14,8 @@ import androidx.compose.foundation.layout.padding
1314
import androidx.compose.foundation.layout.size
1415
import androidx.compose.foundation.layout.width
1516
import androidx.compose.foundation.lazy.LazyColumn
16-
import androidx.compose.foundation.lazy.LazyRow
1717
import androidx.compose.foundation.lazy.grid.GridCells
1818
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
19-
import androidx.compose.foundation.lazy.items
2019
import androidx.compose.foundation.lazy.rememberLazyListState
2120
import androidx.compose.foundation.rememberScrollbarAdapter
2221
import androidx.compose.material.icons.Icons
@@ -168,15 +167,22 @@ fun ProjectOverviewCard(
168167
if (projectOverviewInfo.isMultiModule) {
169168
add("Multi-Module")
170169
}
170+
projectOverviewInfo.ndkVersion?.let { add("NDK $it") }
171+
projectOverviewInfo.cmakeVersion?.let { add("CMake $it") }
172+
projectOverviewInfo.platformList.forEach {
173+
add(it)
174+
}
171175
}
172176
}
173177

174178
if (versions.isNotEmpty()) {
175179
HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.2f))
176-
LazyRow(
177-
horizontalArrangement = Arrangement.spacedBy(8.dp)
180+
FlowRow(
181+
horizontalArrangement = Arrangement.spacedBy(8.dp),
182+
verticalArrangement = Arrangement.spacedBy(8.dp),
183+
modifier = Modifier.fillMaxWidth()
178184
) {
179-
items(versions) { version ->
185+
versions.forEach { version ->
180186
Surface(
181187
color = MaterialTheme.colorScheme.primaryContainer,
182188
shape = MaterialTheme.shapes.small

0 commit comments

Comments
 (0)