Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import androidx.datastore.preferences.preferencesDataStore
import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.ApkInstaller
import com.ahmadkharfan.androidstudiolite.data.buildsystem.signing.AndroidKeystoreManager
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildStore
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.data.remote.RemoteBuildSystem
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildSystem
import com.ahmadkharfan.androidstudiolite.domain.repository.GitRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ package com.ahmadkharfan.androidstudiolite.di
import com.ahmadkharfan.androidstudiolite.data.gradle.GradleProjectReader
import com.ahmadkharfan.androidstudiolite.data.gradle.deps.DependencyManager
import com.ahmadkharfan.androidstudiolite.data.gradle.deps.MavenDependencySearch
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.GradleProjectInspector
import org.koin.dsl.module

val gradleModule = module {
single { GradleProjectReader() }

// Features depend on the narrow domain contract; the data layer keeps the richer reader for its
// own use, so both resolve to the same instance rather than two parsers.
single<GradleProjectInspector> { get<GradleProjectReader>() }
single { DependencyManager() }
single { MavenDependencySearch() }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ahmadkharfan.androidstudiolite.data.ai

import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.data.ai.agent.AiAgentLog
import com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmChatRequest
import com.ahmadkharfan.androidstudiolite.data.ai.llm.LlmProviderRegistry
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ahmadkharfan.androidstudiolite.data.ai

import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.domain.model.AiAgentSettings
import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderConfig
import com.ahmadkharfan.androidstudiolite.domain.model.ApiKeyStatus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ahmadkharfan.androidstudiolite.data.ai

import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.data.ai.agent.AgentProtocol
import com.ahmadkharfan.androidstudiolite.data.ai.agent.AgentToolExecutor
import com.ahmadkharfan.androidstudiolite.data.ai.agent.AiAgentLog
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.ahmadkharfan.androidstudiolite.data.ai.llm

import com.ahmadkharfan.androidstudiolite.data.ai.AiLlmException
import com.ahmadkharfan.androidstudiolite.data.ai.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog

internal class LlmProviderRegistry(http: LlmHttpClient) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.ahmadkharfan.androidstudiolite.data.ai.llm

import com.ahmadkharfan.androidstudiolite.data.ai.AiLlmException
import com.ahmadkharfan.androidstudiolite.data.ai.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.data.ai.LlmChatTurn
import com.ahmadkharfan.androidstudiolite.domain.model.ChatRole
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.ahmadkharfan.androidstudiolite.data.ai.llm

import com.ahmadkharfan.androidstudiolite.data.ai.AiLlmException
import com.ahmadkharfan.androidstudiolite.data.ai.AiLlmGateway
import com.ahmadkharfan.androidstudiolite.data.ai.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.domain.model.AiProviderCatalog
import com.ahmadkharfan.androidstudiolite.data.ai.LlmChatTurn
import com.ahmadkharfan.androidstudiolite.domain.model.ChatRole
import okhttp3.Request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import com.ahmadkharfan.androidstudiolite.data.gradle.parse.GradlePropertiesPars
import com.ahmadkharfan.androidstudiolite.data.gradle.parse.SettingsGradleParser
import com.ahmadkharfan.androidstudiolite.data.gradle.parse.VersionCatalogParser
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.DependencyModel
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.GradleProjectInspector
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.GradleProjectSummary
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.DependencyScope
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ModuleModel
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ModuleType
Expand All @@ -32,11 +34,14 @@ data class GradleProjectReadResult(
val agpVersion: String? = null,
)

class GradleProjectReader {
class GradleProjectReader : GradleProjectInspector {

fun isGradleProject(dir: File): Boolean =
override fun isGradleProject(dir: File): Boolean =
File(dir, "settings.gradle.kts").isFile || File(dir, "settings.gradle").isFile

override fun inspect(projectRoot: File): GradleProjectSummary =
read(projectRoot).let { GradleProjectSummary(it.model, it.gradleVersion, it.agpVersion) }

fun read(projectRoot: File): GradleProjectReadResult {
val diagnostics = ArrayList<GradleDiagnostic>()
val catalog = readCatalog(projectRoot, diagnostics)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ahmadkharfan.androidstudiolite.data.remote

import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuild
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
Expand All @@ -11,29 +13,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map

data class ActiveBuild(
val buildId: String,
val operationId: String = buildId,
val projectId: String,
val projectRootPath: String,
val projectName: String,
val installAfterSuccess: Boolean,
val autoLaunchAfterInstall: Boolean = true,
val startedAtEpochMs: Long,
val modulePath: String = "",
val variantName: String = "",
val kind: String = "ASSEMBLE",
val taskPath: String? = null,
val buildType: String? = null,
)

interface ActiveBuildRepository {
fun observe(): Flow<ActiveBuild?>
suspend fun get(): ActiveBuild?
suspend fun save(build: ActiveBuild)
suspend fun clear(buildId: String? = null)
}

class ActiveBuildStore(
private val dataStore: DataStore<Preferences>,
) : ActiveBuildRepository {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ahmadkharfan.androidstudiolite.domain.buildsystem

import kotlinx.coroutines.flow.Flow

/**
* A build that has been admitted and is expected to still be running, persisted so the app can
* re-attach to it after process death.
*/
data class ActiveBuild(
val buildId: String,
val operationId: String = buildId,
val projectId: String,
val projectRootPath: String,
val projectName: String,
val installAfterSuccess: Boolean,
val autoLaunchAfterInstall: Boolean = true,
val startedAtEpochMs: Long,
val modulePath: String = "",
val variantName: String = "",
val kind: String = "ASSEMBLE",
val taskPath: String? = null,
val buildType: String? = null,
)

interface ActiveBuildRepository {
fun observe(): Flow<ActiveBuild?>
suspend fun get(): ActiveBuild?
suspend fun save(build: ActiveBuild)

/** Clears the stored build, or only [buildId] when given, so a stale writer cannot clobber a newer build. */
suspend fun clear(buildId: String? = null)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.ahmadkharfan.androidstudiolite.domain.buildsystem

import java.io.File

/**
* What a feature needs to know about a Gradle project on disk.
*
* Deliberately narrower than the data layer's full parse result: features only ever need the module
* model and the toolchain versions, so parser-specific types (diagnostics, the version catalog, raw
* `gradle.properties`) stay inside the data layer instead of leaking across the boundary.
*/
data class GradleProjectSummary(
val model: ProjectModel,
val gradleVersion: String? = null,
val agpVersion: String? = null,
)

interface GradleProjectInspector {

/** Whether [dir] looks like the root of a Gradle project. */
fun isGradleProject(dir: File): Boolean

fun inspect(projectRoot: File): GradleProjectSummary
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.ahmadkharfan.androidstudiolite.data.ai
package com.ahmadkharfan.androidstudiolite.domain.model

data class AiProviderDefinition(
val id: String,
Expand Down
2 changes: 1 addition & 1 deletion feature/buildrun/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ dependencies {
implementation(platform(libs.koin.bom))
implementation(platform(libs.androidx.compose.bom))
implementation(projects.domain)
implementation(projects.data.build)
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)
implementation(libs.androidx.compose.material3)
Expand All @@ -15,5 +14,6 @@ dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.datastore.preferences)
implementation(libs.kotlinx.coroutines.android)
testImplementation(projects.data.build)
testImplementation(libs.junit)
}
4 changes: 2 additions & 2 deletions feature/buildrun/detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
<ID>CyclomaticComplexMethod:ApkInstaller.kt$ApkInstaller$fun install( apk: File, applicationId: String?, autoLaunch: Boolean, requestToken: String = UUID.randomUUID().toString(), ): Flow&lt;InstallEvent&gt;</ID>
<ID>LongMethod:ApkInstaller.kt$ApkInstaller$fun install( apk: File, applicationId: String?, autoLaunch: Boolean, requestToken: String = UUID.randomUUID().toString(), ): Flow&lt;InstallEvent&gt;</ID>
<ID>LongMethod:RemoteBuildKeepAliveService.kt$RemoteBuildKeepAliveService$override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int</ID>
<ID>LongParameterList:BuildRunCoordinator.kt$BuildRunCoordinator$( context: Context, buildSystem: BuildSystem, keystoreManager: KeystoreManager, apkInstaller: ApkInstaller, gradleReader: GradleProjectReader, notifier: BuildNotifier, activeBuildStore: ActiveBuildRepository, clock: AslClock = SystemAslClock, ids: IdGenerator = UuidIdGenerator, )</ID>
<ID>LongParameterList:BuildRunCoordinator.kt$BuildRunCoordinator$( private val context: Context, private val buildSystem: BuildSystem, private val keystoreManager: KeystoreManager, private val installOperations: BuildInstallOperations, private val gradleReader: GradleProjectReader, private val notifier: BuildNotifier, private val activeBuildStore: ActiveBuildRepository, private val clock: AslClock, private val ids: IdGenerator, )</ID>
<ID>LongParameterList:BuildRunCoordinator.kt$BuildRunCoordinator$( context: Context, buildSystem: BuildSystem, keystoreManager: KeystoreManager, apkInstaller: ApkInstaller, gradleReader: GradleProjectInspector, notifier: BuildNotifier, activeBuildStore: ActiveBuildRepository, clock: AslClock = SystemAslClock, ids: IdGenerator = UuidIdGenerator, )</ID>
<ID>LongParameterList:BuildRunCoordinator.kt$BuildRunCoordinator$( private val context: Context, private val buildSystem: BuildSystem, private val keystoreManager: KeystoreManager, private val installOperations: BuildInstallOperations, private val gradleReader: GradleProjectInspector, private val notifier: BuildNotifier, private val activeBuildStore: ActiveBuildRepository, private val clock: AslClock, private val ids: IdGenerator, )</ID>
<ID>TooGenericExceptionCaught:ApkInstaller.kt$ApkInstaller$e: Exception</ID>
<ID>TooGenericExceptionCaught:ApkInstaller.kt$ApkInstaller$error: Exception</ID>
<ID>TooGenericExceptionCaught:BuildRunCoordinator.kt$BuildRunCoordinator$error: Exception</ID>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageInstaller
import android.os.Build
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.feature.buildrun.BuildRunCoordinator
import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.CoroutineScope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.ahmadkharfan.androidstudiolite.feature.buildrun

import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.InstallEvent
import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.UninstallEvent
import com.ahmadkharfan.androidstudiolite.data.gradle.GradleProjectReader
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.GradleProjectInspector
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildEvent
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildRequest
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ModuleType
Expand All @@ -27,7 +27,7 @@ internal class BuildInstallOperations(

internal class BuildInstallRunner(
private val operations: BuildInstallOperations,
private val gradleReader: GradleProjectReader,
private val gradleReader: GradleProjectInspector,
private val ids: IdGenerator,
) {
suspend fun install(
Expand Down Expand Up @@ -55,7 +55,7 @@ internal class BuildInstallRunner(
private suspend fun resolveApplicationId(projectRoot: File, modulePath: String): String? =
withContext(Dispatchers.IO) {
runCatching {
val modules = gradleReader.read(projectRoot).model.modules
val modules = gradleReader.inspect(projectRoot).model.modules
val module = modules.firstOrNull { it.path == modulePath }
?: modules.firstOrNull { it.type == ModuleType.ANDROID_APP }
module?.applicationId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package com.ahmadkharfan.androidstudiolite.feature.buildrun
import android.content.Context
import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.ApkInstaller
import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.UninstallEvent
import com.ahmadkharfan.androidstudiolite.data.gradle.GradleProjectReader
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuild
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.GradleProjectInspector
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuild
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildEvent
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildKind
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildRequest
Expand Down Expand Up @@ -51,7 +51,7 @@ class BuildRunCoordinator internal constructor(
private val buildSystem: BuildSystem,
private val keystoreManager: KeystoreManager,
private val installOperations: BuildInstallOperations,
private val gradleReader: GradleProjectReader,
private val gradleReader: GradleProjectInspector,
private val notifier: BuildNotifier,
private val activeBuildStore: ActiveBuildRepository,
private val clock: AslClock,
Expand All @@ -65,7 +65,7 @@ class BuildRunCoordinator internal constructor(
buildSystem: BuildSystem,
keystoreManager: KeystoreManager,
apkInstaller: ApkInstaller,
gradleReader: GradleProjectReader,
gradleReader: GradleProjectInspector,
notifier: BuildNotifier,
activeBuildStore: ActiveBuildRepository,
clock: AslClock = SystemAslClock,
Expand Down Expand Up @@ -447,7 +447,7 @@ class BuildRunCoordinator internal constructor(

override suspend fun preflight(projectRoot: File): BuildPreflightResult = withContext(Dispatchers.IO) {
val versions = runCatching {
val read = gradleReader.read(projectRoot)
val read = gradleReader.inspect(projectRoot)
ToolchainVersions(
gradle = read.gradleVersion,
agp = read.agpVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.ahmadkharfan.androidstudiolite.feature.buildrun
import android.content.ContextWrapper
import com.ahmadkharfan.androidstudiolite.data.buildsystem.install.InstallEvent
import com.ahmadkharfan.androidstudiolite.data.gradle.GradleProjectReader
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuild
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuild
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildEvent
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildKind
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import android.content.ComponentName
import android.content.ContextWrapper
import android.content.Intent
import com.ahmadkharfan.androidstudiolite.data.gradle.GradleProjectReader
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuild
import com.ahmadkharfan.androidstudiolite.data.remote.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuild
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.ActiveBuildRepository
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildEvent
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildKind
import com.ahmadkharfan.androidstudiolite.domain.buildsystem.BuildRequest
Expand Down
2 changes: 1 addition & 1 deletion feature/editor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ dependencies {
implementation(platform(libs.androidx.compose.bom))
implementation(projects.domain)
implementation(projects.core.common)
implementation(projects.data.build)
implementation(projects.designsystem)
implementation(projects.feature.buildrun)
implementation(projects.feature.git)
Expand All @@ -22,6 +21,7 @@ dependencies {
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.androidx.datastore.preferences)
testImplementation(projects.data.build)
testImplementation(projects.data.local)
testImplementation(libs.junit)
testImplementation(libs.kotlinx.coroutines.test)
Expand Down
Loading
Loading